jump-dev / Xpress.jl

A Julia interface to the FICO Xpress Optimization suite
https://www.fico.com/en/products/fico-xpress-optimization
65 stars 30 forks source link

semi-infinite variables #2

Closed mlubin closed 8 years ago

mlubin commented 8 years ago

If I set semi_solvers = [XpressSolver()] in test/jump.jl, I get the following failure:

[model] Test semi-integer variables
  > With solver Xpress.XpressSolver

Reading Problem 
Problem Statistics
           0 (      0 spare) rows
           0 (      0 spare) structural columns
           0 (      0 spare) non-zero elements
Global Statistics
           0 entities        0 sets        0 set members

Reading Problem 
Problem Statistics
           0 (      0 spare) rows
           0 (      0 spare) structural columns
           0 (      0 spare) non-zero elements
Global Statistics
           0 entities        0 sets        0 set members
?427 Error: Invalid column type passed to XPRSchgcoltype.
Element 0 of your array has invalid column type N
ERROR: LoadError: LoadError: Xpress.XpressError(0,"?427 Error: Invalid column type passed to XPRSchgcoltype.\nElement 0 of your array has invalid column type N")
 in chgcoltypes! at /home/mlubin/.julia/v0.4/Xpress/src/xprs_vars.jl:61
 in setvartype! at /home/mlubin/.julia/v0.4/Xpress/src/XpressSolverInterface.jl:323
 in build at /home/mlubin/.julia/v0.4/JuMP/src/solvers.jl:405
 in solve at /home/mlubin/.julia/v0.4/JuMP/src/solvers.jl:134
 in anonymous at /home/mlubin/.julia/v0.4/JuMP/test/model.jl:643
 in context at /home/mlubin/.julia/v0.4/FactCheck/src/FactCheck.jl:475
 in anonymous at /home/mlubin/.julia/v0.4/JuMP/test/model.jl:637
 in facts at /home/mlubin/.julia/v0.4/FactCheck/src/FactCheck.jl:449
 in include at ./boot.jl:261
 in include_from_node1 at ./loading.jl:320
 in include at ./boot.jl:261
 in include_from_node1 at ./loading.jl:320
 in process_options at ./client.jl:280
 in _start at ./client.jl:378
while loading /home/mlubin/.julia/v0.4/JuMP/test/model.jl, in expression starting on line 635
while loading /home/mlubin/.julia/v0.4/Xpress/test/jump.jl, in expression starting on line 11
joaquimg commented 8 years ago

Fixed by de88a7c Was just a wrong symbol, Xpress uses R instead of N for representing semi-integers.

[model] Test semi-continuous variables
  > With solver Xpress.XpressSolver
2 facts verified
mlubin commented 8 years ago

Now I see a failure with semi-continuous:

[model] Test semi-continuous variables
  > With solver Xpress.XpressSolver

Reading Problem 
Problem Statistics
           0 (      0 spare) rows
           0 (      0 spare) structural columns
           0 (      0 spare) non-zero elements
Global Statistics
           0 entities        0 sets        0 set members

Reading Problem 
Problem Statistics
           0 (      0 spare) rows
           0 (      0 spare) structural columns
           0 (      0 spare) non-zero elements
Global Statistics
           0 entities        0 sets        0 set members
Minimizing MILP 
Original problem has:
         1 rows            2 cols            2 elements         2 globals
Presolved problem has:
         0 rows            0 cols            0 elements         0 globals
Will try to keep branch and bound tree memory usage below 3.6Gb
Starting concurrent solve with dual

 Concurrent-Solve,   0s
            Dual        
    objective   dual inf
 D  1.0000000   .0000000
------- optimal --------
Concurrent statistics:
      Dual: 0 simplex iterations, 0.00s
Optimal solution found

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0          1.000000      D      0     0        .000000     0
Dual solved problem
  0 simplex iterations in 0s

Final objective                         : 1.000000000000000e+00
  Max primal violation      (abs / rel) :       0.0 /       0.0
  Max dual violation        (abs / rel) :       0.0 /       0.0
  Max complementarity viol. (abs / rel) :       0.0 /       0.0
All values within tolerances

Starting root cutting & heuristics

 Its Type    BestSoln    BestBound   Sols    Add    Del     Gap     GInf   Time
*            1.000000     1.000000      1                  0.00%       0      0
 *** Search completed ***     Time:     0 Nodes:          1
Number of integer feasible solutions found is 1
Best integer solution found is     1.000000
Best bound is     1.000000
Uncrunching matrix
    Failure :: (line:-1) :: With solver Xpress.XpressSolver :: fact was false
      Expression: getvalue(x) --> roughly(0.0,TOL)
        Expected: 1.0 ≅ 0.0
    Failure :: (line:-1) :: With solver Xpress.XpressSolver :: fact was false
      Expression: getvalue(y) --> roughly(2.0,TOL)
        Expected: 0.0 ≅ 2.0
joaquimg commented 8 years ago

It seems that Xpress will change the lower bound to 1, so bounds would have to be updated after the modification.

see page 132 of: https://www.msi-jp.com/xpress/learning/square/optimizer-2015.pdf

mlubin commented 8 years ago

That's strange, the other solvers don't do that.

joaquimg commented 8 years ago

That's indeed a weird behaviour, but I have just checked the most recent documentations and indeed it makes this weird change on LB, the UB remain unchanged. Apparently not too long ago (Xpress 7.8) modification to Semi continuous wasn't even possible.

m = Model(solver = XpressSolver())
@variable(m, 5 <= x <=10, SemiCont)
@constraint(m, x >= 0.5)
@objective(m, Min, x)
solve(m)
getvalue(x)

returns x = 1

while

m = Model(solver = XpressSolver())
@variable(m, 5 <= x <=10, SemiCont)
@constraint(m, x >= 0.5)
@objective(m, Max, x)
solve(m)
getvalue(x)

returns x = 10

Looks like a not very good way of making LB > 0

mlubin commented 8 years ago

So the solution is to re-set the bounds after setting the variable categories?

joaquimg commented 8 years ago

I talked to the guys a FICO and the behavior of semi-continuous variables is more strange actually, the gave me the following answer:

When you change a column into semi-continuous or semi-integer using XPRSchgcoltype (and it is not already one of these types), the lower bound of the variable will be set to zero and the semi-continuous lower bound will be set to 1.0. A semi-continuous variable x has the property that it is either 0 or above a semi-continuous lower bound, i.e., (x = 0) or (x >= sclb), where sclb > 0. Since the XPRSchgcoltype function does not take the semi-continuous lower bound (sclb) as an argument, it defaults to 1.0. Note that the actual lower bound of the variable is set to 0.0. So if you call XPRSgetlb on this variable you will get 0.0.

To change the semi-continuous lower bound to something different from 1.0, you need to XPRSchgglblimit with the indices of the semi-continous (or semi-integer) columns and the new semi-continuous bounds.

Note that the lower bound for a semi-continuous is not allowed to be negative. If you impose a positive lower bound on such a variable, you are forcing it to be in the continuous interval (x >= sclb) so you have effectively made it a pure continuous variable. This is why we automatically change the lower bound to be 0 when you use XPRSchgcoltype to create a semi-continuous variable – this is the natural choice for such a variable.

So I am not much sure about what to do, I will have to wrapp XPRSchgglblimit anyway, but then we might need to do some checking on variable type, don't know if its a good approach.

Any ideas?

joaquimg commented 8 years ago

sorry, closed by accident. Re opening:

mlubin commented 8 years ago

I guess the best option is to just call XPRSchgglblimit explicitly for the semicontinuous variables inside of setvartype!