Lazy: Rename fields

This commit is contained in:
2023-10-27 08:53:38 -05:00
parent c1adc0b79e
commit 7079a36203
14 changed files with 42 additions and 42 deletions

View File

@@ -58,11 +58,11 @@ class BasicCollector:
# Add lazy constraints to model
if (
hasattr(model, "fix_violations")
and model.fix_violations is not None
hasattr(model, "lazy_enforce")
and model.lazy_enforce is not None
):
model.fix_violations(model, model.violations_, "aot")
h5.put_scalar("mip_constr_violations", repr(model.violations_))
model.lazy_enforce(model, model.lazy_constrs_, "aot")
h5.put_scalar("mip_lazy", repr(model.lazy_constrs_))
# Save MPS file
model.write(mps_filename)

View File

@@ -24,30 +24,30 @@ class MemorizingLazyConstrComponent:
def __init__(self, clf: Any, extractor: FeaturesExtractor) -> None:
self.clf = clf
self.extractor = extractor
self.violations_: List[Hashable] = []
self.constrs_: List[Hashable] = []
self.n_features_: int = 0
self.n_targets_: int = 0
def fit(self, train_h5: List[str]) -> None:
logger.info("Reading training data...")
n_samples = len(train_h5)
x, y, violations, n_features = [], [], [], None
violation_to_idx: Dict[Hashable, int] = {}
x, y, constrs, n_features = [], [], [], None
constr_to_idx: Dict[Hashable, int] = {}
for h5_filename in train_h5:
with H5File(h5_filename, "r") as h5:
# Store lazy constraints
sample_violations_str = h5.get_scalar("mip_constr_violations")
assert sample_violations_str is not None
assert isinstance(sample_violations_str, str)
sample_violations = eval(sample_violations_str)
assert isinstance(sample_violations, list)
sample_constrs_str = h5.get_scalar("mip_lazy")
assert sample_constrs_str is not None
assert isinstance(sample_constrs_str, str)
sample_constrs = eval(sample_constrs_str)
assert isinstance(sample_constrs, list)
y_sample = []
for v in sample_violations:
if v not in violation_to_idx:
violation_to_idx[v] = len(violation_to_idx)
violations.append(v)
y_sample.append(violation_to_idx[v])
for c in sample_constrs:
if c not in constr_to_idx:
constr_to_idx[c] = len(constr_to_idx)
constrs.append(c)
y_sample.append(constr_to_idx[c])
y.append(y_sample)
# Extract features
@@ -62,8 +62,8 @@ class MemorizingLazyConstrComponent:
logger.info("Constructing matrices...")
assert n_features is not None
self.n_features_ = n_features
self.violations_ = violations
self.n_targets_ = len(violation_to_idx)
self.constrs_ = constrs
self.n_targets_ = len(constr_to_idx)
x_np = np.vstack(x)
assert x_np.shape == (n_samples, n_features)
y_np = MultiLabelBinarizer().fit_transform(y)
@@ -82,8 +82,8 @@ class MemorizingLazyConstrComponent:
model: GurobiModel,
stats: Dict[str, Any],
) -> None:
assert self.violations_ is not None
if model.fix_violations is None:
assert self.constrs_ is not None
if model.lazy_enforce is None:
return
# Read features
@@ -99,7 +99,7 @@ class MemorizingLazyConstrComponent:
y = y.reshape(-1)
# Enforce constraints
violations = [self.violations_[i] for (i, yi) in enumerate(y) if yi > 0.5]
violations = [self.constrs_[i] for (i, yi) in enumerate(y) if yi > 0.5]
logger.info(f"Enforcing {len(violations)} constraints ahead-of-time...")
model.fix_violations(model, violations, "aot")
model.lazy_enforce(model, violations, "aot")
stats["Lazy Constraints: AOT"] = len(violations)

View File

@@ -142,7 +142,7 @@ def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel:
name="eq_degree",
)
def find_violations(model: GurobiModel) -> List[Any]:
def lazy_separate(model: GurobiModel) -> List[Any]:
violations = []
x = model.inner.cbGetSolution(model.inner._x)
selected_edges = [e for e in model.inner._edges if x[e] > 0.5]
@@ -159,7 +159,7 @@ def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel:
violations.append(cut_edges)
return violations
def fix_violations(model: GurobiModel, violations: List[Any], where: str) -> None:
def lazy_enforce(model: GurobiModel, violations: List[Any], where: str) -> None:
for violation in violations:
constr = quicksum(model.inner._x[e[0], e[1]] for e in violation) >= 2
if where == "cb":
@@ -172,6 +172,6 @@ def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel:
return GurobiModel(
model,
find_violations=find_violations,
fix_violations=fix_violations,
lazy_separate=lazy_separate,
lazy_enforce=lazy_enforce,
)

View File

@@ -21,13 +21,13 @@ class GurobiModel(AbstractModel):
def __init__(
self,
inner: gp.Model,
find_violations: Optional[Callable] = None,
fix_violations: Optional[Callable] = None,
lazy_separate: Optional[Callable] = None,
lazy_enforce: Optional[Callable] = None,
) -> None:
self.fix_violations = fix_violations
self.find_violations = find_violations
self.lazy_separate = lazy_separate
self.lazy_enforce = lazy_enforce
self.inner = inner
self.violations_: Optional[List[Any]] = None
self.lazy_constrs_: Optional[List[Any]] = None
def add_constrs(
self,
@@ -125,18 +125,18 @@ class GurobiModel(AbstractModel):
stats["Fixed variables"] = n_fixed
def optimize(self) -> None:
self.violations_ = []
self.lazy_constrs_ = []
def callback(m: gp.Model, where: int) -> None:
assert self.find_violations is not None
assert self.violations_ is not None
assert self.fix_violations is not None
assert self.lazy_separate is not None
assert self.lazy_constrs_ is not None
assert self.lazy_enforce is not None
if where == GRB.Callback.MIPSOL:
violations = self.find_violations(self)
self.violations_.extend(violations)
self.fix_violations(self, violations, "cb")
violations = self.lazy_separate(self)
self.lazy_constrs_.extend(violations)
self.lazy_enforce(self, violations, "cb")
if self.fix_violations is not None:
if self.lazy_enforce is not None:
self.inner.Params.lazyConstraints = 1
self.inner.optimize(callback)
else: