mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-06 01:18:52 -06:00
Use np.ndarray for constraint names
This commit is contained in:
@@ -200,11 +200,11 @@ class FeaturesExtractor:
|
|||||||
) -> None:
|
) -> None:
|
||||||
has_static_lazy = instance.has_static_lazy_constraints()
|
has_static_lazy = instance.has_static_lazy_constraints()
|
||||||
user_features: List[Optional[List[float]]] = []
|
user_features: List[Optional[List[float]]] = []
|
||||||
categories: List[Optional[str]] = []
|
categories: List[Optional[bytes]] = []
|
||||||
lazy: List[bool] = []
|
lazy: List[bool] = []
|
||||||
constr_categories_dict = instance.get_constraint_categories()
|
constr_categories_dict = instance.get_constraint_categories()
|
||||||
constr_features_dict = instance.get_constraint_features()
|
constr_features_dict = instance.get_constraint_features()
|
||||||
constr_names = sample.get_vector("static_constr_names")
|
constr_names = sample.get_array("static_constr_names")
|
||||||
assert constr_names is not None
|
assert constr_names is not None
|
||||||
|
|
||||||
for (cidx, cname) in enumerate(constr_names):
|
for (cidx, cname) in enumerate(constr_names):
|
||||||
@@ -215,8 +215,8 @@ class FeaturesExtractor:
|
|||||||
user_features.append(None)
|
user_features.append(None)
|
||||||
categories.append(None)
|
categories.append(None)
|
||||||
continue
|
continue
|
||||||
assert isinstance(category, str), (
|
assert isinstance(category, bytes), (
|
||||||
f"Constraint category must be a string. "
|
f"Constraint category must be bytes. "
|
||||||
f"Found {type(category).__name__} instead for cname={cname}.",
|
f"Found {type(category).__name__} instead for cname={cname}.",
|
||||||
)
|
)
|
||||||
categories.append(category)
|
categories.append(category)
|
||||||
@@ -242,7 +242,7 @@ class FeaturesExtractor:
|
|||||||
lazy.append(False)
|
lazy.append(False)
|
||||||
sample.put_vector_list("static_constr_features", user_features)
|
sample.put_vector_list("static_constr_features", user_features)
|
||||||
sample.put_vector("static_constr_lazy", lazy)
|
sample.put_vector("static_constr_lazy", lazy)
|
||||||
sample.put_vector("static_constr_categories", categories)
|
sample.put_array("static_constr_categories", np.array(categories, dtype="S"))
|
||||||
|
|
||||||
def _extract_user_features_instance(
|
def _extract_user_features_instance(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class GurobiSolver(InternalSolver):
|
|||||||
raise Exception(f"unknown cbasis: {v}")
|
raise Exception(f"unknown cbasis: {v}")
|
||||||
|
|
||||||
gp_constrs = model.getConstrs()
|
gp_constrs = model.getConstrs()
|
||||||
constr_names = model.getAttr("constrName", gp_constrs)
|
constr_names = np.array(model.getAttr("constrName", gp_constrs), dtype="S")
|
||||||
lhs: Optional[List] = None
|
lhs: Optional[List] = None
|
||||||
rhs, senses, slacks, basis_status = None, None, None, None
|
rhs, senses, slacks, basis_status = None, None, None, None
|
||||||
dual_value, basis_status, sa_rhs_up, sa_rhs_down = None, None, None, None
|
dual_value, basis_status, sa_rhs_up, sa_rhs_down = None, None, None, None
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class Constraints:
|
|||||||
dual_values: Optional[np.ndarray] = None
|
dual_values: Optional[np.ndarray] = None
|
||||||
lazy: Optional[List[bool]] = None
|
lazy: Optional[List[bool]] = None
|
||||||
lhs: Optional[List[List[Tuple[bytes, float]]]] = None
|
lhs: Optional[List[List[Tuple[bytes, float]]]] = None
|
||||||
names: Optional[List[str]] = None
|
names: Optional[np.ndarray] = None
|
||||||
rhs: Optional[np.ndarray] = None
|
rhs: Optional[np.ndarray] = None
|
||||||
sa_rhs_down: Optional[np.ndarray] = None
|
sa_rhs_down: Optional[np.ndarray] = None
|
||||||
sa_rhs_up: Optional[np.ndarray] = None
|
sa_rhs_up: Optional[np.ndarray] = None
|
||||||
@@ -86,7 +86,7 @@ class Constraints:
|
|||||||
dual_values=sample.get_vector("lp_constr_dual_values"),
|
dual_values=sample.get_vector("lp_constr_dual_values"),
|
||||||
lazy=sample.get_vector("static_constr_lazy"),
|
lazy=sample.get_vector("static_constr_lazy"),
|
||||||
# lhs=sample.get_vector("static_constr_lhs"),
|
# lhs=sample.get_vector("static_constr_lhs"),
|
||||||
names=sample.get_vector("static_constr_names"),
|
names=sample.get_array("static_constr_names"),
|
||||||
rhs=sample.get_vector("static_constr_rhs"),
|
rhs=sample.get_vector("static_constr_rhs"),
|
||||||
sa_rhs_down=sample.get_vector("lp_constr_sa_rhs_down"),
|
sa_rhs_down=sample.get_vector("lp_constr_sa_rhs_down"),
|
||||||
sa_rhs_up=sample.get_vector("lp_constr_sa_rhs_up"),
|
sa_rhs_up=sample.get_vector("lp_constr_sa_rhs_up"),
|
||||||
@@ -100,7 +100,7 @@ class Constraints:
|
|||||||
dual_values=(
|
dual_values=(
|
||||||
None if self.dual_values is None else self.dual_values[selected]
|
None if self.dual_values is None else self.dual_values[selected]
|
||||||
),
|
),
|
||||||
names=self._filter(self.names, selected),
|
names=(None if self.names is None else self.names[selected]),
|
||||||
lazy=self._filter(self.lazy, selected),
|
lazy=self._filter(self.lazy, selected),
|
||||||
lhs=self._filter(self.lhs, selected),
|
lhs=self._filter(self.lhs, selected),
|
||||||
rhs=(None if self.rhs is None else self.rhs[selected]),
|
rhs=(None if self.rhs is None else self.rhs[selected]),
|
||||||
@@ -254,7 +254,7 @@ class InternalSolver(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def remove_constraints(self, names: List[str]) -> None:
|
def remove_constraints(self, names: np.ndarray) -> None:
|
||||||
"""
|
"""
|
||||||
Removes the given constraints from the model.
|
Removes the given constraints from the model.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class BasePyomoSolver(InternalSolver):
|
|||||||
else:
|
else:
|
||||||
expr = lhs >= cf.rhs[i]
|
expr = lhs >= cf.rhs[i]
|
||||||
cl = pe.Constraint(expr=expr, name=name)
|
cl = pe.Constraint(expr=expr, name=name)
|
||||||
self.model.add_component(name, cl)
|
self.model.add_component(name.decode(), cl)
|
||||||
self._pyomo_solver.add_constraint(cl)
|
self._pyomo_solver.add_constraint(cl)
|
||||||
self._cname_to_constr[name] = cl
|
self._cname_to_constr[name] = cl
|
||||||
self._termination_condition = ""
|
self._termination_condition = ""
|
||||||
@@ -233,7 +233,7 @@ class BasePyomoSolver(InternalSolver):
|
|||||||
_parse_constraint(constr)
|
_parse_constraint(constr)
|
||||||
|
|
||||||
return Constraints(
|
return Constraints(
|
||||||
names=_none_if_empty(names),
|
names=_none_if_empty(np.array(names, dtype="S")),
|
||||||
rhs=_none_if_empty(np.array(rhs, dtype=float)),
|
rhs=_none_if_empty(np.array(rhs, dtype=float)),
|
||||||
senses=_none_if_empty(senses),
|
senses=_none_if_empty(senses),
|
||||||
lhs=_none_if_empty(lhs),
|
lhs=_none_if_empty(lhs),
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
assert_equals(
|
assert_equals(
|
||||||
solver.get_constraints(),
|
solver.get_constraints(),
|
||||||
Constraints(
|
Constraints(
|
||||||
names=["eq_capacity"],
|
names=np.array(["eq_capacity"], dtype="S"),
|
||||||
rhs=np.array([0.0]),
|
rhs=np.array([0.0]),
|
||||||
lhs=[
|
lhs=[
|
||||||
[
|
[
|
||||||
@@ -110,7 +110,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
Constraints(
|
Constraints(
|
||||||
basis_status=["N"],
|
basis_status=["N"],
|
||||||
dual_values=np.array([13.538462]),
|
dual_values=np.array([13.538462]),
|
||||||
names=["eq_capacity"],
|
names=np.array(["eq_capacity"], dtype="S"),
|
||||||
sa_rhs_down=np.array([-24.0]),
|
sa_rhs_down=np.array([-24.0]),
|
||||||
sa_rhs_up=np.array([2.0]),
|
sa_rhs_up=np.array([2.0]),
|
||||||
slacks=np.array([0.0]),
|
slacks=np.array([0.0]),
|
||||||
@@ -153,7 +153,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
_filter_attrs(
|
_filter_attrs(
|
||||||
solver.get_constraint_attrs(),
|
solver.get_constraint_attrs(),
|
||||||
Constraints(
|
Constraints(
|
||||||
names=["eq_capacity"],
|
names=np.array(["eq_capacity"], dtype="S"),
|
||||||
slacks=np.array([0.0]),
|
slacks=np.array([0.0]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -161,7 +161,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
|
|
||||||
# Build new constraint and verify that it is violated
|
# Build new constraint and verify that it is violated
|
||||||
cf = Constraints(
|
cf = Constraints(
|
||||||
names=["cut"],
|
names=np.array(["cut"], dtype="S"),
|
||||||
lhs=[[(b"x[0]", 1.0)]],
|
lhs=[[(b"x[0]", 1.0)]],
|
||||||
rhs=np.array([0.0]),
|
rhs=np.array([0.0]),
|
||||||
senses=["<"],
|
senses=["<"],
|
||||||
@@ -175,7 +175,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
_filter_attrs(
|
_filter_attrs(
|
||||||
solver.get_constraint_attrs(),
|
solver.get_constraint_attrs(),
|
||||||
Constraints(
|
Constraints(
|
||||||
names=["eq_capacity", "cut"],
|
names=np.array(["eq_capacity", "cut"], dtype="S"),
|
||||||
rhs=np.array([0.0, 0.0]),
|
rhs=np.array([0.0, 0.0]),
|
||||||
lhs=[
|
lhs=[
|
||||||
[
|
[
|
||||||
@@ -198,7 +198,7 @@ def run_basic_usage_tests(solver: InternalSolver) -> None:
|
|||||||
assert_equals(solver.are_constraints_satisfied(cf), [True])
|
assert_equals(solver.are_constraints_satisfied(cf), [True])
|
||||||
|
|
||||||
# Remove the new constraint
|
# Remove the new constraint
|
||||||
solver.remove_constraints(["cut"])
|
solver.remove_constraints(np.array(["cut"], dtype="S"))
|
||||||
|
|
||||||
# New constraint should no longer affect solution
|
# New constraint should no longer affect solution
|
||||||
stats = solver.solve()
|
stats = solver.solve()
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ def sample() -> Sample:
|
|||||||
"type-b",
|
"type-b",
|
||||||
],
|
],
|
||||||
"static_constr_lazy": [True, True, True, True, False],
|
"static_constr_lazy": [True, True, True, True, False],
|
||||||
"static_constr_names": ["c1", "c2", "c3", "c4", "c5"],
|
"static_constr_names": np.array(["c1", "c2", "c3", "c4", "c5"], dtype="S"),
|
||||||
"static_instance_features": [5.0],
|
"static_instance_features": [5.0],
|
||||||
"mip_constr_lazy_enforced": {"c1", "c2", "c4"},
|
"mip_constr_lazy_enforced": {b"c1", b"c2", b"c4"},
|
||||||
"lp_constr_features": [
|
"lp_constr_features": [
|
||||||
[1.0, 1.0],
|
[1.0, 1.0],
|
||||||
[1.0, 2.0],
|
[1.0, 2.0],
|
||||||
@@ -110,7 +110,7 @@ def test_usage_with_solver(instance: Instance) -> None:
|
|||||||
|
|
||||||
# Should ask internal solver to remove some constraints
|
# Should ask internal solver to remove some constraints
|
||||||
assert internal.remove_constraints.call_count == 1
|
assert internal.remove_constraints.call_count == 1
|
||||||
internal.remove_constraints.assert_has_calls([call(["c3"])])
|
internal.remove_constraints.assert_has_calls([call([b"c3"])])
|
||||||
|
|
||||||
# LearningSolver calls after_iteration (first time)
|
# LearningSolver calls after_iteration (first time)
|
||||||
should_repeat = component.iteration_cb(solver, instance, None)
|
should_repeat = component.iteration_cb(solver, instance, None)
|
||||||
@@ -142,7 +142,7 @@ def test_usage_with_solver(instance: Instance) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Should update training sample
|
# Should update training sample
|
||||||
assert sample.get_set("mip_constr_lazy_enforced") == {"c1", "c2", "c3", "c4"}
|
assert sample.get_set("mip_constr_lazy_enforced") == {b"c1", b"c2", b"c3", b"c4"}
|
||||||
#
|
#
|
||||||
# Should update stats
|
# Should update stats
|
||||||
assert stats["LazyStatic: Removed"] == 1
|
assert stats["LazyStatic: Removed"] == 1
|
||||||
@@ -170,7 +170,7 @@ def test_sample_predict(sample: Sample) -> None:
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
pred = comp.sample_predict(sample)
|
pred = comp.sample_predict(sample)
|
||||||
assert pred == ["c1", "c2", "c4"]
|
assert pred == [b"c1", b"c2", b"c4"]
|
||||||
|
|
||||||
|
|
||||||
def test_fit_xy() -> None:
|
def test_fit_xy() -> None:
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ def test_knapsack() -> None:
|
|||||||
["default", "default", "default", "default", None],
|
["default", "default", "default", "default", None],
|
||||||
)
|
)
|
||||||
assert sample.get_vector_list("static_var_features") is not None
|
assert sample.get_vector_list("static_var_features") is not None
|
||||||
assert_equals(sample.get_vector("static_constr_names"), ["eq_capacity"])
|
assert_equals(
|
||||||
|
sample.get_vector("static_constr_names"),
|
||||||
|
np.array(["eq_capacity"], dtype="S"),
|
||||||
|
)
|
||||||
# assert_equals(
|
# assert_equals(
|
||||||
# sample.get_vector("static_constr_lhs"),
|
# sample.get_vector("static_constr_lhs"),
|
||||||
# [
|
# [
|
||||||
@@ -69,7 +72,10 @@ def test_knapsack() -> None:
|
|||||||
assert_equals(sample.get_vector("static_constr_rhs"), [0.0])
|
assert_equals(sample.get_vector("static_constr_rhs"), [0.0])
|
||||||
assert_equals(sample.get_vector("static_constr_senses"), ["="])
|
assert_equals(sample.get_vector("static_constr_senses"), ["="])
|
||||||
assert_equals(sample.get_vector("static_constr_features"), [None])
|
assert_equals(sample.get_vector("static_constr_features"), [None])
|
||||||
assert_equals(sample.get_vector("static_constr_categories"), ["eq_capacity"])
|
assert_equals(
|
||||||
|
sample.get_vector("static_constr_categories"),
|
||||||
|
np.array(["eq_capacity"], dtype="S"),
|
||||||
|
)
|
||||||
assert_equals(sample.get_vector("static_constr_lazy"), [False])
|
assert_equals(sample.get_vector("static_constr_lazy"), [False])
|
||||||
assert_equals(sample.get_vector("static_instance_features"), [67.0, 21.75])
|
assert_equals(sample.get_vector("static_instance_features"), [67.0, 21.75])
|
||||||
assert_equals(sample.get_scalar("static_constr_lazy_count"), 0)
|
assert_equals(sample.get_scalar("static_constr_lazy_count"), 0)
|
||||||
@@ -124,7 +130,7 @@ def test_knapsack() -> None:
|
|||||||
|
|
||||||
def test_constraint_getindex() -> None:
|
def test_constraint_getindex() -> None:
|
||||||
cf = Constraints(
|
cf = Constraints(
|
||||||
names=["c1", "c2", "c3"],
|
names=np.array(["c1", "c2", "c3"], dtype="S"),
|
||||||
rhs=np.array([1.0, 2.0, 3.0]),
|
rhs=np.array([1.0, 2.0, 3.0]),
|
||||||
senses=["=", "<", ">"],
|
senses=["=", "<", ">"],
|
||||||
lhs=[
|
lhs=[
|
||||||
@@ -145,7 +151,7 @@ def test_constraint_getindex() -> None:
|
|||||||
assert_equals(
|
assert_equals(
|
||||||
cf[[True, False, True]],
|
cf[[True, False, True]],
|
||||||
Constraints(
|
Constraints(
|
||||||
names=["c1", "c3"],
|
names=np.array(["c1", "c3"], dtype="S"),
|
||||||
rhs=np.array([1.0, 3.0]),
|
rhs=np.array([1.0, 3.0]),
|
||||||
senses=["=", ">"],
|
senses=["=", ">"],
|
||||||
lhs=[
|
lhs=[
|
||||||
|
|||||||
Reference in New Issue
Block a user