coin-or / python-mip

Python-MIP: collection of Python tools for the modeling and solution of Mixed-Integer Linear programs
Eclipse Public License 2.0
525 stars 92 forks source link

Trying to load generated solution (`.sol` or `.mst`) file as a MIP start #119

Closed vncoelho closed 4 years ago

vncoelho commented 4 years ago

First of all, congratulations for the great project and organization. I would like to thanks @h-g-s for all his teachings and great lessons over this topic, as well as attention with my questions.

I am not expert in Python but I am trying to use the library. The idea is to load a previously generated solution on CBC or GUROBI. Here is the code used:

from mip import *
import sys

file_name = sys.argv[1]
m = Model()
m = Model(sense=mip.MAXIMIZE,solver_name=GUROBI) # use GRB for Gurobi
m.SearchEmphasis = 2
m.read(file_name)
print('model has {} vars, {} constraints and {} nzs'.format(m.num_cols, m.num_rows, m.num_nz))
m.max_gap = 0.05

#This was the try for reading the saved MIP solution
m.read("testToWrite.sol")
print('validating mipstart {}'.format(m.validate_mip_start()))

status = m.optimize(max_seconds=200)
if status == OptimizationStatus.OPTIMAL:
    print('optimal solution cost {} found'.format(m.objective_value))
elif status == OptimizationStatus.FEASIBLE:
    print('sol.cost {} found, best possible: {}'.format(m.objective_value, m.objective_bound))
elif status == OptimizationStatus.NO_SOLUTION_FOUND:
    print('no feasible solution found, upper bound is: {}'.format(m.objective_bound))
if status == OptimizationStatus.OPTIMAL or status == OptimizationStatus.FEASIBLE:
    print('solution:')
    for v in m.vars:
       if abs(v.x) > 1e-6: # only printing non-zeros
          print('{} : {}'.format(v.name, v.x))

m.write("testToWrite.sol")

The example of the .lp and .sol is attached lpAndSol.zip

The following log is being obtained:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    m.read("testToWrite.sol")
  File "/home/vitor/.local/lib/python3.8/site-packages/mip/model.py", line 587, in read
    mip_start = load_mipstart(path)
  File "/home/vitor/.local/lib/python3.8/site-packages/mip/model.py", line 1475, in load_mipstart
    line = f.next()
AttributeError: '_io.TextIOWrapper' object has no attribute 'next'
h-g-s commented 4 years ago

Hi @vncoelho

Thanks for the detailed bug report! I fixed the bug in reading the .mst file (I'll release 1.9.2 soon), but it seems that there is another problem. In the .lp file the names were discarded (all names appear as x()), how the LP was created ?

vncoelho commented 4 years ago

The .lp was created from this .mod: https://github.com/NeoResearch/milp_bft_failures_attacks/blob/master/dbft3.0/MILP_BFTConsensus_dBFT3.0_2P.mod

And converted with this command of GLPK you gave in class some couple of year ago...aehauheua glpsol --model MILP_BFTConsensus_dBFT2.0_withByzantines_liveness.mod --data 4Nodes_TMax20.dat --wcpxlp n4-dbft-2.0-biz.lp --check && mv n4-dbft2.0-biz-liveness.lp

h-g-s commented 4 years ago

Could you add a .dat ? I'll try to generate here and see why variable names are being discarded...

vncoelho commented 4 years ago

The data is short, here it is:

data;
param f := 1;
param N := 4;
param M := 3;
param tMax := 10;
# NO SPEED UP - WORSE CASE
# T1 - NULL
# T2 - SEND PREPREQ
# T3 - RECEIVED PREPREQ - SEND PREPRESPONSE
# T4 - RECEIVED M PREPRESPONSE P-BACKUP (2) OR F+1 FROM P-PRIORITY (1) - SEND PRECOMMIT
# T5 - RECEIVED M PRECOMMIT - SEND COMMIT
# T6 - RECEIVED M COMMIT - RELAYED BLOCK

# SPEED UP - BEST CASE
# T1 - NULL
# T2 - SEND PREPREQ
# T3 - RECEIVED PREPREQ - SEND PREPRESPONSE
# T4 - RECEIVED M PREPRESPONSE P-PRIORITY (1)  - SEND COMMIT
# T5 - RECEIVED M COMMIT - RELAYED BLOCK
h-g-s commented 4 years ago

Hi @vncoelho ,

Generated the lp here, with glpsol -m MILP_BFTConsensus_dBFT3.0_2P.mod -d a.dat --wcpxlp a.lp

and the names appeared correctly . Did you sent me the same .dat ? Tested with the LP with the correct names and mipstart worked. PS: Just released 1.9.2 with the fix for reading MIPStarts

vncoelho commented 4 years ago

I regenerated the .sol using v1.9.2 and it is working.

Warning: Completing partial solution with 6098 unfixed non-continuous variables out of 6201
User MIP start produced solution with objective 995 (0.01s)
Loaded user MIP start with objective 995

Loaded with success, @h-g-s . Let me know if I can do any test from my side that may help here.