diff --git a/pyomo/contrib/appsi/solvers/highs.py b/pyomo/contrib/appsi/solvers/highs.py index 838e4e32cf5..15e1bf6156c 100644 --- a/pyomo/contrib/appsi/solvers/highs.py +++ b/pyomo/contrib/appsi/solvers/highs.py @@ -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, @@ -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 diff --git a/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py b/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py index 5bbfed0ef4e..6230664664d 100644 --- a/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py +++ b/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py @@ -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):