AnsweredAssumed Answered

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

    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)

 

 

 

Attachments

Outcomes