Free Python solver finds a solution - not XPress. Or do I misuse Python API?

Question asked by nicolas.winc on Jan 25, 2018
Latest reply on Jan 30, 2018 by pietrobelotti@fico.com

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

'''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.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)