GurobiModel: Capture static_var_obj_coeffs_quad

dev
Alinson S. Xavier 4 months ago
parent 1c6912cc51
commit 2ca2794457

@ -80,6 +80,7 @@ class MaxCutGenerator:
def _generate_graph(self) -> Graph: def _generate_graph(self) -> Graph:
return nx.generators.random_graphs.binomial_graph(self.n.rvs(), self.p.rvs()) return nx.generators.random_graphs.binomial_graph(self.n.rvs(), self.p.rvs())
def build_maxcut_model_gurobipy( def build_maxcut_model_gurobipy(
data: Union[str, MaxCutData], data: Union[str, MaxCutData],
params: Optional[dict[str, Any]] = None, params: Optional[dict[str, Any]] = None,
@ -97,13 +98,16 @@ def build_maxcut_model_gurobipy(
x = model.addVars(nodes, vtype=gp.GRB.BINARY, name="x") x = model.addVars(nodes, vtype=gp.GRB.BINARY, name="x")
# Add the objective function # Add the objective function
model.setObjective(quicksum( model.setObjective(
- data.weights[i] * x[e[0]] * (1 - x[e[1]]) for (i, e) in enumerate(edges) quicksum(
)) -data.weights[i] * x[e[0]] * (1 - x[e[1]]) for (i, e) in enumerate(edges)
)
)
model.update() model.update()
return GurobiModel(model) return GurobiModel(model)
def _maxcut_read(data: Union[str, MaxCutData]) -> MaxCutData: def _maxcut_read(data: Union[str, MaxCutData]) -> MaxCutData:
if isinstance(data, str): if isinstance(data, str):
data = read_pkl_gz(data) data = read_pkl_gz(data)

@ -264,6 +264,13 @@ class GurobiModel(AbstractModel):
h5.put_array( h5.put_array(
h5_field, np.array(self.inner.getAttr(gp_field, gp_vars), dtype=float) h5_field, np.array(self.inner.getAttr(gp_field, gp_vars), dtype=float)
) )
obj = self.inner.getObjective()
if isinstance(obj, gp.QuadExpr):
nvars = len(self.inner.getVars())
obj_q = np.zeros((nvars, nvars))
for i in range(obj.size()):
obj_q[obj.getVar1(i).index, obj.getVar2(i).index] = obj.getCoeff(i)
h5.put_array("static_var_obj_coeffs_quad", obj_q)
def _extract_after_load_constrs(self, h5: H5File) -> None: def _extract_after_load_constrs(self, h5: H5File) -> None:
gp_constrs = self.inner.getConstrs() gp_constrs = self.inner.getConstrs()

@ -1,17 +1,22 @@
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization # MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020-2025, UChicago Argonne, LLC. All rights reserved. # Copyright (C) 2020-2025, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details. # Released under the modified BSD license. See COPYING.md for more details.
import random import random
from tempfile import TemporaryDirectory
import numpy as np import numpy as np
from scipy.stats import randint, uniform
from miplearn.h5 import H5File
from miplearn.problems.maxcut import MaxCutGenerator, build_maxcut_model_gurobipy from miplearn.problems.maxcut import MaxCutGenerator, build_maxcut_model_gurobipy
from scipy.stats import randint, uniform
def _set_seed(): def _set_seed():
random.seed(42) random.seed(42)
np.random.seed(42) np.random.seed(42)
def test_maxcut_generator_not_fixed() -> None: def test_maxcut_generator_not_fixed() -> None:
_set_seed() _set_seed()
gen = MaxCutGenerator( gen = MaxCutGenerator(
@ -22,12 +27,20 @@ def test_maxcut_generator_not_fixed() -> None:
data = gen.generate(3) data = gen.generate(3)
assert len(data) == 3 assert len(data) == 3
assert list(data[0].graph.nodes()) == [0, 1, 2, 3, 4] assert list(data[0].graph.nodes()) == [0, 1, 2, 3, 4]
assert list(data[0].graph.edges()) == [(0, 2), (0, 3), (0, 4), (2, 3), (2, 4), (3, 4)] assert list(data[0].graph.edges()) == [
(0, 2),
(0, 3),
(0, 4),
(2, 3),
(2, 4),
(3, 4),
]
assert data[0].weights.tolist() == [-1, 1, -1, -1, -1, 1] assert data[0].weights.tolist() == [-1, 1, -1, -1, -1, 1]
assert list(data[1].graph.nodes()) == [0, 1, 2, 3, 4] assert list(data[1].graph.nodes()) == [0, 1, 2, 3, 4]
assert list(data[1].graph.edges()) == [(0, 1), (0, 3), (0, 4), (1, 4), (3, 4)] assert list(data[1].graph.edges()) == [(0, 1), (0, 3), (0, 4), (1, 4), (3, 4)]
assert data[1].weights.tolist() == [-1, -1, -1, 1, -1] assert data[1].weights.tolist() == [-1, -1, -1, 1, -1]
def test_maxcut_generator_fixed() -> None: def test_maxcut_generator_fixed() -> None:
random.seed(42) random.seed(42)
np.random.seed(42) np.random.seed(42)
@ -39,19 +52,67 @@ def test_maxcut_generator_fixed() -> None:
data = gen.generate(3) data = gen.generate(3)
assert len(data) == 3 assert len(data) == 3
assert list(data[0].graph.nodes()) == [0, 1, 2, 3, 4] assert list(data[0].graph.nodes()) == [0, 1, 2, 3, 4]
assert list(data[0].graph.edges()) == [(0, 2), (0, 3), (0, 4), (2, 3), (2, 4), (3, 4)] assert list(data[0].graph.edges()) == [
(0, 2),
(0, 3),
(0, 4),
(2, 3),
(2, 4),
(3, 4),
]
assert data[0].weights.tolist() == [-1, 1, -1, -1, -1, 1] assert data[0].weights.tolist() == [-1, 1, -1, -1, -1, 1]
assert list(data[1].graph.nodes()) == [0, 1, 2, 3, 4] assert list(data[1].graph.nodes()) == [0, 1, 2, 3, 4]
assert list(data[1].graph.edges()) == [(0, 2), (0, 3), (0, 4), (2, 3), (2, 4), (3, 4)] assert list(data[1].graph.edges()) == [
(0, 2),
(0, 3),
(0, 4),
(2, 3),
(2, 4),
(3, 4),
]
assert data[1].weights.tolist() == [-1, -1, -1, 1, -1, -1] assert data[1].weights.tolist() == [-1, -1, -1, 1, -1, -1]
def test_maxcut_model(): def test_maxcut_model():
_set_seed() _set_seed()
data = MaxCutGenerator( data = MaxCutGenerator(
n=randint(low=20, high=21), n=randint(low=10, high=11),
p=uniform(loc=0.5, scale=0.0), p=uniform(loc=0.5, scale=0.0),
fix_graph=True, fix_graph=True,
).generate(1)[0] ).generate(1)[0]
model = build_maxcut_model_gurobipy(data) model = build_maxcut_model_gurobipy(data)
with TemporaryDirectory() as tempdir:
with H5File(f"{tempdir}/data.h5", "w") as h5:
model.extract_after_load(h5)
obj_lin = h5.get_array("static_var_obj_coeffs")
assert obj_lin is not None
assert obj_lin.tolist() == [
3.0,
1.0,
3.0,
1.0,
-1.0,
0.0,
-1.0,
0.0,
-1.0,
0.0,
]
obj_quad = h5.get_array("static_var_obj_coeffs_quad")
assert obj_quad is not None
assert obj_quad.tolist() == [
[0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0],
[0.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, -1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
]
model.optimize() model.optimize()
assert model.inner.ObjVal == -26 assert model.inner.ObjVal == -4

Loading…
Cancel
Save