Skip to content

Commit

Permalink
Merge pull request #2763 from michaelbynum/highs_fix
Browse files Browse the repository at this point in the history
Better handling of mutable parameters with values of 0 in Highs interface
  • Loading branch information
jsiirola authored Mar 10, 2023
2 parents 87295e4 + 904d04e commit ad2ba13
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
5 changes: 4 additions & 1 deletion pyomo/contrib/appsi/solvers/highs.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]):
for ndx, coef in enumerate(repn.linear_coefs):
v = repn.linear_vars[ndx]
v_id = id(v)
coef_val = value(coef)
if not is_constant(coef):
mutable_linear_coefficient = _MutableLinearCoefficient(pyomo_con=con, pyomo_var_id=v_id,
con_map=self._pyomo_con_to_solver_con_map,
Expand All @@ -352,8 +353,10 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]):
if con not in self._mutable_helpers:
self._mutable_helpers[con] = list()
self._mutable_helpers[con].append(mutable_linear_coefficient)
if coef_val == 0:
continue
var_indices.append(self._pyomo_var_to_solver_var_map[v_id])
coef_values.append(value(coef))
coef_values.append(coef_val)

if con.has_lb():
lb = con.lower - repn.constant
Expand Down
23 changes: 23 additions & 0 deletions pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,29 @@ def test_variables_elsewhere2(self, name: str, opt_class: Type[PersistentSolver]
self.assertIn(m.y, sol)
self.assertNotIn(m.z, sol)

@parameterized.expand(input=all_solvers)
def test_bug_1(self, name: str, opt_class: Type[PersistentSolver]):
opt: PersistentSolver = opt_class()
if not opt.available():
raise unittest.SkipTest

m = pe.ConcreteModel()
m.x = pe.Var(bounds=(3, 7))
m.y = pe.Var(bounds=(-10, 10))
m.p = pe.Param(mutable=True, initialize=0)

m.obj = pe.Objective(expr=m.y)
m.c = pe.Constraint(expr=m.y >= m.p*m.x)

res = opt.solve(m)
self.assertEqual(res.termination_condition, TerminationCondition.optimal)
self.assertAlmostEqual(res.best_feasible_objective, 0)

m.p.value = 1
res = opt.solve(m)
self.assertEqual(res.termination_condition, TerminationCondition.optimal)
self.assertAlmostEqual(res.best_feasible_objective, 3)


@unittest.skipUnless(cmodel_available, 'appsi extensions are not available')
class TestLegacySolverInterface(unittest.TestCase):
Expand Down

0 comments on commit ad2ba13

Please sign in to comment.