coin-or / coin-or/pulp

Reading MPS Files

Open
#459 15 comments 0 reactions 0 assignees View on GitHub
lp/mps
Dominant language
Python
Stars
2.5k
Forks
432
PR merge metrics
No merged PRs in 30d

Description

Hi,

I am trying to read an MPS file as part of an optimisation competition (https://github.com/ds4dm/ml4co-competition). The dataset is located in instances.tar.gz (https://drive.google.com/file/d/1MytdY3IwX_aFRWdoc0mMfDN9Xg1EKUuq/view). This is quite a big data set, so here's a single 300kB .mps file from the data set which I am trying to read in as a pulp LpProblem: https://drive.google.com/file/d/1rpOx4GomiPzSry733hIXtCW1yccmG1iD/view?usp=sharing

Once downloaded, I am using the below to load the .mps instance:

```python
import pulp

path = '../milp/datasets/instances/1_item_placement/train/item_placement_1.mps'
variables, instance = pulp.LpProblem.fromMPS(path)
```

This appears to read the .mps file without crashing, however it seems to load the problem as a maximisation problem when I believe it is meant to be a minimisation problem. Furthermore, when I run:

```python
status = instance.solve()
```

I get the following error:

```
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in
----> 1 status = instance.solve()
2 print(f'status: {status}')
3 print(f"objective: {instance.objective.value()}")
4 # for var in instance.variables():
5 # print(f"{var.name}: {var.value()}")

/scratch/zciccwf/py36/envs/rlgnn/lib/python3.7/site-packages/pulp/pulp.py in solve(self, solver, **kwargs)
1735 #time it
1736 self.solutionTime = -clock()
-> 1737 status = solver.actualSolve(self, **kwargs)
1738 self.solutionTime += clock()
1739 self.restoreObjective(wasNone, dummyVar)

/scratch/zciccwf/py36/envs/rlgnn/lib/python3.7/site-packages/pulp/apis/coin_api.py in actualSolve(self, lp, **kwargs)
99 def actualSolve(self, lp, **kwargs):
100 """Solve a well formulated lp problem"""
--> 101 return self.solve_CBC(lp, **kwargs)
102
103 def available(self):

/scratch/zciccwf/py36/envs/rlgnn/lib/python3.7/site-packages/pulp/apis/coin_api.py in solve_CBC(self, lp, use_mps)
112 tmpLp, tmpMps, tmpSol, tmpMst = self.create_tmp_files(lp.name, 'lp', 'mps', 'sol', 'mst')
113 if use_mps:
--> 114 vs, variablesNames, constraintsNames, objectiveName = lp.writeMPS(tmpMps, rename = 1)
115 cmds = ' '+tmpMps+" "
116 if lp.sense == constants.LpMaximize:

/scratch/zciccwf/py36/envs/rlgnn/lib/python3.7/site-packages/pulp/pulp.py in writeMPS(self, filename, mpsSense, rename, mip)
1609 - The file is created
1610 """
-> 1611 return mpslp.writeMPS(self, filename, mpsSense = mpsSense, rename = rename, mip = mip)
1612
1613

/scratch/zciccwf/py36/envs/rlgnn/lib/python3.7/site-packages/pulp/mps_lp.py in writeMPS(LpProblem, filename, mpsSense, rename, mip)
222
223 with open(filename, "w") as f:
--> 224 f.write("*SENSE:"+ const.LpSenses[mpsSense]+"\n")
225 f.write("NAME " + model_name + "\n")
226 f.write("ROWS\n")

KeyError: 0
```

Setting `sense=1` seems to prevent the above crash, however it results in `pulp` saying the problem is infeasible:

```python
variables, instance = pulp.LpProblem.fromMPS(path, sense=1)
status = instance.solve()
print(f'status: {status}')
print(f"objective: {instance.objective.value()}")
```

```
status: -1
objective: 13303590269.825811
```

I do not think the problem is with the .mps file, because the following code appears to work with the `mip` library:

```python
import mip
path = '../milp/datasets/instances/1_item_placement/train/item_placement_1.mps'

instance = mip.Model()
instance.read(path)

status = instance.optimize(max_seconds=300)

if status == mip.OptimizationStatus.OPTIMAL:
print('optimal solution cost {} found'.format(instance.objective_value))
elif status == mip.OptimizationStatus.FEASIBLE:
print('sol.cost {} found, best possible: {}'.format(instance.objective_value, instance.objective_bound))
elif status == mip.OptimizationStatus.NO_SOLUTION_FOUND:
print('no feasible solution found, lower bound is: {}'.format(instance.objective_bound))
```

```
sol.cost 60.796965159000024 found, best possible: 28.922094929823203
```

Do you know if there might be any bugs with `pulp.LpProblem.fromMPS()`?

Contributor guide

Open the contributing guide

Research direction

Reproduce the failure with LpProblem.fromMPS(path) using the supplied MPS file, then inspect pulp/pulp.py, mps_lp.py, and the fromMPS/writeMPS path shown in the traceback. Compare the parsed objective sense and solver behavior with the mip result; done means valid minimization input no longer raises KeyError or reports the supplied feasible instance as infeasible, with regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.