Skip to content

Commit 5e280dc

Browse files
committed
gurobi refactor: bugs
1 parent 5073ba0 commit 5e280dc

File tree

6 files changed

+25
-73
lines changed

6 files changed

+25
-73
lines changed

pyomo/contrib/solver/common/base.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -321,22 +321,6 @@ def set_objective(self, obj: ObjectiveData):
321321
f"Derived class {self.__class__.__name__} failed to implement required method 'set_objective'."
322322
)
323323

324-
def add_variables(self, variables: List[VarData]):
325-
"""
326-
Add variables to the model.
327-
"""
328-
raise NotImplementedError(
329-
f"Derived class {self.__class__.__name__} failed to implement required method 'add_variables'."
330-
)
331-
332-
def add_parameters(self, params: List[ParamData]):
333-
"""
334-
Add parameters to the model.
335-
"""
336-
raise NotImplementedError(
337-
f"Derived class {self.__class__.__name__} failed to implement required method 'add_parameters'."
338-
)
339-
340324
def add_constraints(self, cons: List[ConstraintData]):
341325
"""
342326
Add constraints to the model.
@@ -353,22 +337,6 @@ def add_block(self, block: BlockData):
353337
f"Derived class {self.__class__.__name__} failed to implement required method 'add_block'."
354338
)
355339

356-
def remove_variables(self, variables: List[VarData]):
357-
"""
358-
Remove variables from the model.
359-
"""
360-
raise NotImplementedError(
361-
f"Derived class {self.__class__.__name__} failed to implement required method 'remove_variables'."
362-
)
363-
364-
def remove_parameters(self, params: List[ParamData]):
365-
"""
366-
Remove parameters from the model.
367-
"""
368-
raise NotImplementedError(
369-
f"Derived class {self.__class__.__name__} failed to implement required method 'remove_parameters'."
370-
)
371-
372340
def remove_constraints(self, cons: List[ConstraintData]):
373341
"""
374342
Remove constraints from the model.

pyomo/contrib/solver/solvers/gurobi/gurobi_direct.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,14 @@ def _create_solver_model(self, pyomo_model):
114114
self._gurobi_vars = x.tolist()
115115

116116
var_map = ComponentMap(zip(repn.columns, self._gurobi_vars))
117-
con_map = dict(zip([i.constraint for i in repn.rows], A.tolist()))
117+
con_map = {}
118+
for row, gc in zip(repn.rows, A.tolist()):
119+
pc = row.constraint
120+
if pc in con_map:
121+
# range constraint
122+
con_map[pc] = (con_map[pc], gc)
123+
else:
124+
con_map[pc] = gc
118125
solution_loader = GurobiDirectSolutionLoader(
119126
solver_model=gurobi_model, var_map=var_map, con_map=con_map,
120127
)

pyomo/contrib/solver/solvers/gurobi/gurobi_direct_base.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,20 @@ def _get_duals(solver_model, con_map, cons_to_load):
181181
duals = {}
182182
for c in cons_to_load:
183183
gurobi_con = con_map[c]
184-
if gurobi_con in qcons:
185-
duals[c] = gurobi_con.QCPi
184+
if type(gurobi_con) is tuple:
185+
# only linear range constraints are supported
186+
gc1, gc2 = gurobi_con
187+
d1 = gc1.Pi
188+
d2 = gc2.Pi
189+
if abs(d1) > abs(d2):
190+
duals[c] = d1
191+
else:
192+
duals[c] = d2
186193
else:
187-
duals[c] = gurobi_con.Pi
194+
if gurobi_con in qcons:
195+
duals[c] = gurobi_con.QCPi
196+
else:
197+
duals[c] = gurobi_con.Pi
188198

189199
return duals
190200

pyomo/contrib/solver/solvers/gurobi/gurobi_persistent.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -437,22 +437,13 @@ def _get_expr_from_pyomo_repn(self, repn):
437437
)
438438

439439
if len(repn.linear_vars) > 0:
440-
#missing_vars = [v for v in repn.linear_vars if id(v) not in self._vars]
441-
#self._add_variables(missing_vars)
442440
coef_list = [value(i) for i in repn.linear_coefs]
443441
vlist = [self._pyomo_var_to_solver_var_map[v] for v in repn.linear_vars]
444442
new_expr = gurobipy.LinExpr(coef_list, vlist)
445443
else:
446444
new_expr = 0.0
447445

448446
if len(repn.quadratic_vars) > 0:
449-
# missing_vars = {}
450-
# for x, y in repn.quadratic_vars:
451-
# for v in [x, y]:
452-
# vid = id(v)
453-
# if vid not in self._vars:
454-
# missing_vars[vid] = v
455-
# self._add_variables(list(missing_vars.values()))
456447
for coef, (x, y) in zip(repn.quadratic_coefs, repn.quadratic_vars):
457448
gurobi_x = self._pyomo_var_to_solver_var_map[x]
458449
gurobi_y = self._pyomo_var_to_solver_var_map[y]
@@ -582,14 +573,8 @@ def _add_sos_constraints(self, cons: List[SOSConstraintData]):
582573
gurobi_vars = []
583574
weights = []
584575

585-
missing_vars = {
586-
id(v): v for v, w in con.get_items() if id(v) not in self._vars
587-
}
588-
self._add_variables(list(missing_vars.values()))
589-
590576
for v, w in con.get_items():
591-
v_id = id(v)
592-
gurobi_vars.append(self._pyomo_var_to_solver_var_map[v_id])
577+
gurobi_vars.append(self._pyomo_var_to_solver_var_map[v])
593578
weights.append(w)
594579

595580
gurobipy_con = self._solver_model.addSOS(sos_type, gurobi_vars, weights)
@@ -776,8 +761,9 @@ def _update_variables(self, variables: Mapping[VarData, Reason]):
776761
self._update_quadratic_constraint(c)
777762

778763
if reprocess_obj:
779-
self._remove_objectives([self._objective])
780-
self._add_objectives([self._objective])
764+
obj = self._objective
765+
self._remove_objectives([obj])
766+
self._add_objectives([obj])
781767
elif update_obj:
782768
self._mutable_objective_update()
783769

pyomo/contrib/solver/tests/solvers/test_gurobi_persistent.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -584,13 +584,6 @@ def test_basics(self):
584584
self.assertEqual(opt.get_model_attr('NumConstrs'), 1)
585585
self.assertEqual(opt.get_model_attr('NumQConstrs'), 0)
586586

587-
m.z = pyo.Var()
588-
opt.add_variables([m.z])
589-
self.assertEqual(opt.get_model_attr('NumVars'), 3)
590-
opt.remove_variables([m.z])
591-
del m.z
592-
self.assertEqual(opt.get_model_attr('NumVars'), 2)
593-
594587
def test_update1(self):
595588
m = pyo.ConcreteModel()
596589
m.x = pyo.Var()

pyomo/contrib/solver/tests/unit/test_base.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,11 @@ def test_class_method_list(self):
7474
'_load_vars',
7575
'add_block',
7676
'add_constraints',
77-
'add_parameters',
78-
'add_variables',
7977
'api_version',
8078
'available',
8179
'is_persistent',
8280
'remove_block',
8381
'remove_constraints',
84-
'remove_parameters',
85-
'remove_variables',
8682
'set_instance',
8783
'set_objective',
8884
'solve',
@@ -103,18 +99,10 @@ def test_init(self):
10399
self.assertEqual(instance.api_version(), SolverAPIVersion.V2)
104100
with self.assertRaises(NotImplementedError):
105101
self.assertEqual(instance.set_instance(None), None)
106-
with self.assertRaises(NotImplementedError):
107-
self.assertEqual(instance.add_variables(None), None)
108-
with self.assertRaises(NotImplementedError):
109-
self.assertEqual(instance.add_parameters(None), None)
110102
with self.assertRaises(NotImplementedError):
111103
self.assertEqual(instance.add_constraints(None), None)
112104
with self.assertRaises(NotImplementedError):
113105
self.assertEqual(instance.add_block(None), None)
114-
with self.assertRaises(NotImplementedError):
115-
self.assertEqual(instance.remove_variables(None), None)
116-
with self.assertRaises(NotImplementedError):
117-
self.assertEqual(instance.remove_parameters(None), None)
118106
with self.assertRaises(NotImplementedError):
119107
self.assertEqual(instance.remove_constraints(None), None)
120108
with self.assertRaises(NotImplementedError):

0 commit comments

Comments
 (0)