Use np.ndarray for constraint names

master
Alinson S. Xavier 4 years ago
parent 45667ac2e4
commit 9ddda7e1e2
No known key found for this signature in database
GPG Key ID: DCA0DAD4D2F58624

@ -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=[

Loading…
Cancel
Save