feat: add objective factors/mode defaults and validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Pagwin 2026-06-11 19:20:50 -04:00
parent feb5c1cb76
commit 8a775dd941
No known key found for this signature in database
GPG key ID: 81137023740CA260

View file

@ -67,6 +67,32 @@ FIXED_CHOICES = {
# lambda res: res["E"][3] >= 50 # Ensure at least 50 E at step 3
RESOURCE_CONSTRAINTS = []
# Maximize criteria for solve(). Factor = exponent in "product" mode,
# weight in "sum" mode. Keys: E, B, S, C; missing keys = 0 (resource
# excluded from the objective — it is NOT forced to zero). Negative
# factors are allowed only in "sum" mode (a negative exponent would mean
# division, which integer CP-SAT cannot express).
OBJECTIVE_FACTORS = {"E": 2, "B": 1, "S": 2}
OBJECTIVE_MODE = "product" # "product" or "sum"
def _validate_objective(factors, mode):
if mode not in ("product", "sum"):
raise ValueError(f"objective_mode must be 'product' or 'sum', got {mode!r}")
unknown = set(factors) - {"E", "B", "S", "C"}
if unknown:
raise ValueError(f"unknown objective_factors keys: {sorted(unknown)}")
for k, v in factors.items():
if not isinstance(v, int) or isinstance(v, bool):
raise ValueError(f"objective factor {k}={v!r} must be an int")
if mode == "product" and v < 0:
raise ValueError(
f"objective factor {k}={v} is negative; negative exponents "
"are not expressible in product mode"
)
if not any(factors.values()):
raise ValueError("objective_factors needs at least one nonzero factor")
# Arrival schedule. Key = step (1..5), value = list of city types that arrive
# at the START of that step. Types: 'H' Hub, 'F' Foundry, 'M' Metropolis, 'N' Monument.
# Arriving cities act that same step.