Skip to content

Commit c1396a1

Browse files
committed
Add AMPL.get_iis to return variables and constraints in IIS
1 parent 3e96cdc commit c1396a1

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55
## 0.14.0 - 2024-05-##
66
- Allow assigning values to indexed sets from a dictionary with the lists of members
77
for every index.
8+
- Add AMPL.get_iis() to return dictionaries with variables and constraints in IIS.
89

910
## 0.13.3 - 2024-02-20
1011
- Fix issues with AMPL.solve(verbose=False) when the solver argument was not set.

amplpy/ampl.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,45 @@ def solve_result_num(self):
891891
"""
892892
return self.get_value("solve_result_num")
893893

894+
def get_iis(self):
895+
"""
896+
Get IIS attributes for all variables and constraints.
897+
898+
Returns:
899+
Tuple with a dictionary for variables in the IIS and another for the constraints.
900+
901+
Usage example:
902+
903+
.. code-block:: python
904+
905+
from amplpy import AMPL
906+
ampl = AMPL()
907+
ampl.eval(
908+
r\"\"\"
909+
var x >= 0;
910+
var y >= 0;
911+
maximize obj: x+y;
912+
s.t. s: x+y <= -5;
913+
\"\"\"
914+
)
915+
ampl.option["presolve"] = 0 # disable AMPL presolve
916+
ampl.solve(solver="gurobi", gurobi_options="outlev=1 iis=1")
917+
if ampl.solve_result == "infeasible":
918+
var_iis, con_iis = ampl.get_iis()
919+
print(var_iis, con_iis)
920+
"""
921+
df_var = dict(
922+
self.get_data(
923+
"{i in 1.._nvars: _var[i].iis != 'non'} (_varname[i], _var[i].iis)"
924+
).to_list(skip_index=True)
925+
)
926+
df_con = dict(
927+
self.get_data(
928+
"{i in 1.._ncons: _con[i].iis != 'non'} (_conname[i], _con[i].iis)"
929+
).to_list(skip_index=True)
930+
)
931+
return df_var, df_con
932+
894933
def _start_recording(self, filename):
895934
"""
896935
Start recording the session to a file for debug purposes.

amplpy/tests/test_ampl.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,23 @@ def test_issue56(self):
418418
ampl.get_output("for{i in 0..2} { display i;}"),
419419
)
420420

421+
def test_iis(self):
422+
ampl = self.ampl
423+
ampl.eval(
424+
r"""
425+
var x >= 0;
426+
var y >= 0;
427+
maximize obj: x+y;
428+
s.t. s: x+y <= -5;
429+
"""
430+
)
431+
ampl.option["presolve"] = 0
432+
ampl.solve(solver="gurobi", gurobi_options="outlev=0 iis=1")
433+
if ampl.solve_result == "infeasible":
434+
var_iis, con_iis = ampl.get_iis()
435+
self.assertEqual(var_iis, {"x": "low", "y": "low"})
436+
self.assertEqual(con_iis, {"s": "mem"})
437+
421438

422439
if __name__ == "__main__":
423440
unittest.main()

0 commit comments

Comments
 (0)