Hello,

I am trying the free version of Xpress on a very small linear problem which I want to solve through the Python API. I find that the free solver of SciPy finds a much better optimal solution that XPress (obj function =-40000 vs 0). Could you please advise if I misuse the API? Or is there a parameter I need to set to help XPress find a solution better than 0?

I have reduced the problem to a dummy situation - pls see data attached.

The problem is of the form:

minimize: c^T * x

subject to: A_ub * x <= b_ub

A_eq * x == b_eq

lb<= x <= ub

Please see the Python code below that compares the two solvers (I might misuse the API though and add implicit constraints although I am unable to find any after checking). I have attached two text files that contain A_ub and A_eq matrices. Just need to place them in a folder and update the path below

Many Thanks for your help, it is hopefully me telling another problem than the one I think to XPress

Regards,

Nicolas

**PYTHON CODE:**

from scipy.optimize import linprog

import xpress as xp

import numpy as np

global generalFolder

generalFolder='C:\\[to be completed by user]\\'

nb_dogs=6

A_ub=np.loadtxt(generalFolder+'A_ub.txt')

A_eq=np.loadtxt(generalFolder+'A_eq.txt')

'''build objective function. we want to minimize the last variable'''

obj=np.zeros((12*nb_dogs+10*nb_dogs*(nb_dogs-1)+1,1))

obj[12*nb_dogs+10*nb_dogs*(nb_dogs-1)][0]=1

c=np.ndarray.flatten(obj)

b_ub=np.ndarray.flatten(np.zeros((A_ub.shape[0],1))) #b_ub is a vector of 0 except last two rows

b_ub[nb_dogs*(nb_dogs-1)]=-0.1

b_ub[nb_dogs*(nb_dogs-1)+1]=500

b_eq=np.ndarray.flatten(np.zeros((A_eq.shape[0],1)))

'''linprog takes a list of tuples for bounds, not a vector'''

bounds=tuple(((0,100) for i in range(0,nb_dogs)))

bounds=bounds+tuple((0,0) for i in range(nb_dogs,8*nb_dogs+4*nb_dogs*(nb_dogs-1)))

bounds=bounds+tuple(((0,None) for _ in range(0,4*nb_dogs+6*nb_dogs*(nb_dogs-1))))

bounds=bounds+tuple((None,None)for _ in range(0,1))

'''converts list of tuples to vectors for XPress'''

lb=[]

ub=[]

for b in bounds:

if b[0]==None:

lb.append(-xp.infinity)

else:

lb.append(b[0])

if b[1]==None:

ub.append(xp.infinity)

else:

ub.append(b[1])

'''solve problem with free sciPy linprog function. Solves problem min

minimize: c^T * x

subject to: A_ub * x <= b_ub

A_eq * x == b_eq

solution is in res['x'], the objective on the optimal point is= -39437.66

'''

res=linprog(c,A_ub,b_ub,A_eq,b_eq,bounds,'interior-point',options={'sparse':False,'presolve':False,'rr':False,'tol':1e-8})

'''

writes problem for xPress and solves

'''

p = xp.problem ()

x = np.array ([xp.var(lb=-xp.infinity,ub=xp.infinity, vartype=xp.continuous) for i in range(A_ub.shape[1])])

p.addVariable ( x )

p.addConstraint (xp.Dot(A_ub,x) <= b_ub)

p.addConstraint (xp.Dot(A_eq,x) == b_eq)

p.addConstraint(x<=ub)

p.addConstraint(lb<=x)

p.setObjective (xp.Dot(c,x),sense=xp.minimize)

p.solve()

sol=p.getSolution()

a=[]

obj_xp=p.getObjVal() # **objective is 0 whilst linprog manages to minimize to -39467**

print(sol)

Hi Nicolas,

it seems to me that you're using the Python interface correctly. I tried solving that problem using several settings in Xpress, but I get the same result all the time with objective value zero.

The objective function you found is for a solution that violates some of the constraints: the inequality constraints by at most 3.081e-06, the equality constraints by 2.018e-06, and the upper bounds by very little: 3.244e-09, only the last one being well within the 1e-08 tolerance. The 'simplex' option for linprog's solver fails after not finding any feasible basis to start from. I checked the violations with the following code after solving with linprog (note that this is an absolute feasibility measure, not a relative one that would perhaps be more accurate):

xs = np.array (res.x)

print ("ineq constraints:", b_ub - np.dot (A_ub, xs))

print ("eq constraints:", abs (np.dot (A_eq, xs) - b_eq))

print ("lower bounds:", xs - lb)

print ("upper bounds:", ub - xs)

print ("summary of violations\nineq constraints:", -min (b_ub - np.dot (A_ub, xs)),

"eq constraints:", max (abs (np.dot (A_eq, xs) - b_eq)),

"lower bounds:", max (lb - xs),

"upper bounds:", max (xs - ub))

In contrast, the Xpress solver has a maximum violation of 1e-15 for the equality constraints and 0 for all other constraints (inequality and bounds). This might be just a matter of tolerance. Is there a way to obtain a more accurate solution from linprog?