I can successfully read the MPS file and solve it using Gurobi, which confirms the feasibility of the problem. But I'm striving to utilize or-tools, particularly the "PDLP" solver for specific reasons, and I'm encountering an infeasibility error from or-tools. Here's my approach:
from ortools.linear_solver import pywraplp
import gurobipy as gp
from collections import defaultdict
file_path = "237794.mps"
def parse_mps_updated(file_path):
with open(file_path, 'r') as file:
mode = None
objective = {}
constraints = defaultdict(lambda: {'sense': None, 'rhs': None, 'coefficients': {}})
variables = {}
for line in file:
line = line.strip()
if not line:
continue
if line in ['ROWS', 'COLUMNS', 'RHS', 'BOUNDS', 'SOS', 'RANGES']:
mode = line
continue
fields = line.split()
if mode == 'ROWS':
sense, name = fields[0], fields[1]
if sense == 'N':
continue
else:
constraints[name]['sense'] = sense
elif mode == 'COLUMNS':
if fields[2] in ['INTORG', 'INTEND']:
continue
var_name = fields[0]
try:
constr_name, coeff = fields[1], float(fields[2])
except ValueError:
continue
if constr_name == 'OBJ':
objective[var_name] = coeff
else:
constraints[constr_name]['coefficients'][var_name] = coeff
if var_name not in variables:
variables[var_name] = {'lb': 0.0, 'ub': float('inf')}
elif mode == 'RHS':
constr_name, rhs = fields[1], float(fields[2])
constraints[constr_name]['rhs'] = rhs
elif mode == 'BOUNDS':
bound_type, bound_name, var_name = fields[0], fields[1], fields[2]
bound_value = float(fields[3]) if len(fields) > 3 else None
if bound_type == 'LO':
variables[var_name]['lb'] = bound_value
elif bound_type == 'UP':
variables[var_name]['ub'] = bound_value
elif bound_type == 'FX':
variables[var_name]['lb'] = bound_value
variables[var_name]['ub'] = bound_value
return objective, constraints, variables
parsed_objective, parsed_constraints, parsed_variables = parse_mps_updated(file_path)
len(parsed_objective), len(parsed_constraints), len(parsed_variables)
solver = pywraplp.Solver.CreateSolver('PDLP')
ortools_variables = {}
for var_name, bounds in parsed_variables.items():
lb, ub = bounds['lb'], bounds['ub']
ortools_variables[var_name] = solver.NumVar(lb, ub, var_name)
for constr_name, constr_data in parsed_constraints.items():
coefficients = constr_data['coefficients']
rhs = constr_data['rhs']
if rhs is None:
rhs = 0
sense = constr_data['sense']
if sense == 'E':
constraint = solver.RowConstraint(rhs, rhs, constr_name)
elif sense == 'L':
constraint = solver.RowConstraint(-solver.infinity(), rhs, constr_name)
elif sense == 'G':
constraint = solver.RowConstraint(rhs, solver.infinity(), constr_name)
for var_name, coeff in coefficients.items():
constraint.SetCoefficient(ortools_variables[var_name], coeff)
objective_expr = solver.Objective()
for var_name, coeff in parsed_objective.items():
objective_expr.SetCoefficient(ortools_variables[var_name], coeff)
ort_num_vars = solver.NumVariables()
ort_num_constraints = solver.NumConstraints()
ort_num_vars, ort_num_constraints
status = solver.Solve()
if status == pywraplp.Solver.OPTIMAL:
optimal_value = solver.Objective().Value()
print(f"Optimal Objective Value: {optimal_value}")
elif status == pywraplp.Solver.INFEASIBLE:
print("The problem is infeasible.")
elif status == pywraplp.Solver.UNBOUNDED:
print("The problem is unbounded.")
else:
print("The solver did not find an optimal solution.")
The problem becomes feasible for or-tools When I exclude the following code snippet:
if sense == 'E': constraint = solver.RowConstraint(rhs, rhs, constr_name)
However, even with this change, the optimal solution provided by or-tools is incorrect. I appreciate any insights.
Using model_builder API simplifies this quite a bit.
Example use: