Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusting mps writer to the correct structure regarding integer variables declaration #2946

Merged
merged 21 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
953607a
Adjusting mps writer to the correct structure regarding binary variab…
gomesraphael7d Aug 11, 2023
9ee408f
Changing is_binary() method to is_integer() to contemplate all intege…
gomesraphael7d Aug 11, 2023
a0b7840
Formatting code to black standard indentation
gomesraphael7d Aug 11, 2023
ff9fb58
Creating tests to cover the adjustments
gomesraphael7d Sep 10, 2023
c1913cd
Merge branch 'main' into bugfix/adjust-mps-structure
Raphael-D-F-Gomes Sep 11, 2023
f818de7
Change mps.baseline name
gomesraphael7d Sep 11, 2023
3458ef3
Merge remote-tracking branch 'origin/bugfix/adjust-mps-structure' int…
gomesraphael7d Sep 11, 2023
ec0a2e9
Merge branch 'main' into bugfix/adjust-mps-structure
Raphael-D-F-Gomes Sep 20, 2023
786f622
Creating integer marker flag for mps file writer // Adjusting integer…
gomesraphael7d Sep 26, 2023
38fb412
Adjusting tests
gomesraphael7d Sep 26, 2023
c93b34c
Merge remote-tracking branch 'origin/bugfix/adjust-mps-structure' int…
gomesraphael7d Sep 26, 2023
de4d455
Merge branch 'main' into bugfix/adjust-mps-structure
Raphael-D-F-Gomes Sep 26, 2023
b8ff42f
Adjusting int_marker flag logic
gomesraphael7d Sep 26, 2023
d1aa233
Merge remote-tracking branch 'origin/bugfix/adjust-mps-structure' int…
gomesraphael7d Sep 26, 2023
14be2cb
Adjusting mps writer marker name logic
gomesraphael7d Sep 26, 2023
cfcb06e
Merge branch 'main' into bugfix/adjust-mps-structure
jsiirola Oct 4, 2023
89f9499
Merge branch 'main' into bugfix/adjust-mps-structure
blnicho Oct 17, 2023
b795481
Merge branch 'main' into bugfix/adjust-mps-structure
blnicho Oct 24, 2023
9e6f996
Merge branch 'main' into bugfix/adjust-mps-structure
Raphael-D-F-Gomes Oct 31, 2023
8d741d4
Merge branch 'main' into bugfix/adjust-mps-structure
Raphael-D-F-Gomes Nov 1, 2023
410e557
Merge branch 'main' into bugfix/adjust-mps-structure
mrmundt Nov 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pyomo/repn/plugins/mps.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,22 @@ def yield_all_constraints():
column_template = " %s %s %" + self._precision_string + "\n"
output_file.write("COLUMNS\n")
cnt = 0
set_integer = False
mrmundt marked this conversation as resolved.
Show resolved Hide resolved
for vardata in variable_list:
col_entries = column_data[variable_to_column[vardata]]
cnt += 1
if len(col_entries) > 0:
if vardata.is_integer() and not set_integer:
set_integer = True
output_file.write(
" %s %s %s\n" % ("INT", "'MARKER'", "'INTORG'")
)
mrmundt marked this conversation as resolved.
Show resolved Hide resolved
if not vardata.is_integer() and set_integer:
mrmundt marked this conversation as resolved.
Show resolved Hide resolved
set_integer = False
output_file.write(
" %s %s %s\n" % ("INTEND", "'MARKER'", "'INTEND'")
)
mrmundt marked this conversation as resolved.
Show resolved Hide resolved

var_label = variable_symbol_dictionary[id(vardata)]
for i, (row_label, coef) in enumerate(col_entries):
output_file.write(
Expand Down
27 changes: 27 additions & 0 deletions pyomo/repn/tests/mps/integer_variable_declaration.mps.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
* Source: Pyomo MPS Writer
* Format: Free MPS
*
NAME Example-mix-integer-linear-problem
OBJSENSE
MIN
ROWS
N obj
G c_l_const1_
L c_u_const2_
COLUMNS
INT 'MARKER' 'INTORG'
x1 obj 3
x1 c_l_const1_ 4
x1 c_u_const2_ 1
INTEND 'MARKER' 'INTEND'
x2 obj 2
x2 c_l_const1_ 3
x2 c_u_const2_ 2
RHS
RHS c_l_const1_ 10
RHS c_u_const2_ 7
BOUNDS
LI BOUND x1 0
UI BOUND x1 10E20
LO BOUND x2 0
ENDATA
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
* Source: Pyomo MPS Writer
* Format: Free MPS
*
NAME knapsack problem
OBJSENSE
MIN
ROWS
N obj
G c_l_const1_
COLUMNS
INT 'MARKER' 'INTORG'
x(_1_) obj 3
x(_1_) c_l_const1_ 30
x(_2_) obj 2
x(_2_) c_l_const1_ 24
x(_3_) obj 2
x(_3_) c_l_const1_ 11
x(_4_) obj 4
x(_4_) c_l_const1_ 35
x(_5_) obj 5
x(_5_) c_l_const1_ 29
x(_6_) obj 4
x(_6_) c_l_const1_ 8
x(_7_) obj 3
x(_7_) c_l_const1_ 31
x(_8_) obj 1
x(_8_) c_l_const1_ 18
mrmundt marked this conversation as resolved.
Show resolved Hide resolved
RHS
RHS c_l_const1_ 60
BOUNDS
BV BOUND x(_1_)
BV BOUND x(_2_)
BV BOUND x(_3_)
BV BOUND x(_4_)
BV BOUND x(_5_)
BV BOUND x(_6_)
BV BOUND x(_7_)
BV BOUND x(_8_)
ENDATA
59 changes: 58 additions & 1 deletion pyomo/repn/tests/mps/test_mps.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@
from filecmp import cmp
import pyomo.common.unittest as unittest

from pyomo.environ import ConcreteModel, Var, Objective, Constraint, ComponentMap
from pyomo.environ import (
ConcreteModel,
Var,
Objective,
Constraint,
ComponentMap,
minimize,
Binary,
NonNegativeReals,
NonNegativeIntegers,
)

thisdir = os.path.dirname(os.path.abspath(__file__))

Expand All @@ -41,6 +51,7 @@ def _check_baseline(self, model, **kwds):
io_options = {"symbolic_solver_labels": True}
io_options.update(kwds)
model.write(test_fname, format="mps", io_options=io_options)

self.assertTrue(
cmp(test_fname, baseline_fname),
msg="Files %s and %s differ" % (test_fname, baseline_fname),
Expand Down Expand Up @@ -185,6 +196,52 @@ def test_row_ordering(self):
row_order[model.con4[2]] = -1
self._check_baseline(model, row_order=row_order)

def test_knapsack_problem_binary_variable_declaration(self):
elements_size = [30, 24, 11, 35, 29, 8, 31, 18]
elements_weight = [3, 2, 2, 4, 5, 4, 3, 1]
capacity = 60

model = ConcreteModel("knapsack problem")
var_names = [f"{i + 1}" for i in range(len(elements_size))]

model.x = Var(var_names, within=Binary)

model.obj = Objective(
expr=sum(
model.x[var_names[i]] * elements_weight[i]
for i in range(len(elements_size))
),
sense=minimize,
name="obj",
)

model.const1 = Constraint(
expr=sum(
model.x[var_names[i]] * elements_size[i]
for i in range(len(elements_size))
)
>= capacity,
name="const",
)

self._check_baseline(model)

def test_integer_variable_declaration(self):
model = ConcreteModel("Example-mix-integer-linear-problem")

# Define the decision variables
model.x1 = Var(within=NonNegativeIntegers) # Integer variable
model.x2 = Var(within=NonNegativeReals) # Continuous variable

# Define the objective function
model.obj = Objective(expr=3 * model.x1 + 2 * model.x2, sense=minimize)

# Define the constraints
model.const1 = Constraint(expr=4 * model.x1 + 3 * model.x2 >= 10)
model.const2 = Constraint(expr=model.x1 + 2 * model.x2 <= 7)

self._check_baseline(model)


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