Skip to content

Commit

Permalink
Merge pull request Pyomo#3281 from kutlay/issue-3127
Browse files Browse the repository at this point in the history
Sort indices while removing constraints to fix Pyomo#3127
  • Loading branch information
mrmundt authored Jul 9, 2024
2 parents e01e74b + 072c2c5 commit 86aa282
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pyomo/contrib/appsi/solvers/highs.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ def _remove_constraints(self, cons: List[ConstraintData]):
indices_to_remove.append(con_ndx)
self._mutable_helpers.pop(con, None)
self._solver_model.deleteRows(
len(indices_to_remove), np.array(indices_to_remove)
len(indices_to_remove), np.sort(np.array(indices_to_remove))
)
con_ndx = 0
new_con_map = dict()
Expand Down
37 changes: 37 additions & 0 deletions pyomo/contrib/appsi/solvers/tests/test_highs_persistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,43 @@ def test_mutable_params_with_remove_vars(self):
res = opt.solve(m)
self.assertAlmostEqual(res.best_feasible_objective, -9)

def test_fix_and_unfix(self):
# Tests issue https://github.com/Pyomo/pyomo/issues/3127

m = pe.ConcreteModel()
m.x = pe.Var(domain=pe.Binary)
m.y = pe.Var(domain=pe.Binary)
m.fx = pe.Var(domain=pe.NonNegativeReals)
m.fy = pe.Var(domain=pe.NonNegativeReals)
m.c1 = pe.Constraint(expr=m.fx <= m.x)
m.c2 = pe.Constraint(expr=m.fy <= m.y)
m.c3 = pe.Constraint(expr=m.x + m.y <= 1)

m.obj = pe.Objective(expr=m.fx * 0.5 + m.fy * 0.4, sense=pe.maximize)

opt = Highs()

# solution 1 has m.x == 1 and m.y == 0
r = opt.solve(m)
self.assertAlmostEqual(m.fx.value, 1, places=5)
self.assertAlmostEqual(m.fy.value, 0, places=5)
self.assertAlmostEqual(r.best_feasible_objective, 0.5, places=5)

# solution 2 has m.x == 0 and m.y == 1
m.y.fix(1)
r = opt.solve(m)
self.assertAlmostEqual(m.fx.value, 0, places=5)
self.assertAlmostEqual(m.fy.value, 1, places=5)
self.assertAlmostEqual(r.best_feasible_objective, 0.4, places=5)

# solution 3 should be equal solution 1
m.y.unfix()
m.x.fix(1)
r = opt.solve(m)
self.assertAlmostEqual(m.fx.value, 1, places=5)
self.assertAlmostEqual(m.fy.value, 0, places=5)
self.assertAlmostEqual(r.best_feasible_objective, 0.5, places=5)

def test_capture_highs_output(self):
# tests issue #3003
#
Expand Down

0 comments on commit 86aa282

Please sign in to comment.