Constraints Guide¶
Constraints define the feasible region of your optimization model.
Overview¶
Constraints restrict the values that variables can take. In LumiX, LXConstraint
represents constraint families that expand automatically based on data.
Constraint Structure¶
Every constraint has three parts:
LXConstraint("name")
.expression(lhs_expr) # Left-hand side
.le() # Sense: <=, >=, or ==
.rhs(value) # Right-hand side
Mathematical Form: LHS {<=, >=, ==} RHS
Constraint Senses¶
Less-Than-Or-Equal (<=)¶
For upper limits and capacity constraints:
capacity = (
LXConstraint("capacity")
.expression(
LXLinearExpression().add_term(production, lambda p: p.resource_usage)
)
.le() # <=
.rhs(max_capacity)
)
Use for: Capacity limits, maximum bounds, budget constraints
Greater-Than-Or-Equal (>=)¶
For lower limits and requirements:
demand = (
LXConstraint("demand")
.expression(
LXLinearExpression().add_term(production, 1.0)
)
.ge() # >=
.rhs(minimum_demand)
)
Use for: Minimum requirements, demand satisfaction, quotas
Equality (==)¶
For exact requirements and balance equations:
flow_balance = (
LXConstraint("balance")
.expression(
LXLinearExpression()
.add_term(inflow, 1.0)
.add_term(outflow, -1.0)
)
.eq() # ==
.rhs(0)
)
Use for: Flow conservation, balance equations, exact targets
Single vs. Family Constraints¶
Single Constraint¶
One constraint for the entire model:
total_budget = (
LXConstraint("budget")
.expression(
LXLinearExpression().add_term(production, lambda p: p.cost)
)
.le()
.rhs(max_budget)
)
Constraint Family¶
One constraint per data instance:
resource_limits = (
LXConstraint[Resource]("capacity")
.expression(
LXLinearExpression()
.add_term(production, lambda p, r: p.usage[r.id])
)
.le()
.rhs(lambda r: r.capacity) # Data-driven RHS
.from_data(resources)
.indexed_by(lambda r: r.id)
)
This creates one constraint per resource.
Right-Hand Side (RHS)¶
Constant RHS¶
.rhs(100) # Fixed value
Data-Driven RHS¶
.rhs(lambda r: r.capacity) # From data attribute
Expression RHS¶
.rhs(lambda r: r.base_capacity * r.efficiency_factor)
Multi-Model Constraints¶
Constraints can reference multiple variable families:
# Balance constraint: production + inventory_start = demand + inventory_end
balance = (
LXConstraint[Product]("balance")
.expression(
LXLinearExpression()
.add_term(production, 1.0)
.add_term(inventory_start, 1.0)
.add_term(demand_var, -1.0)
.add_term(inventory_end, -1.0)
)
.eq()
.rhs(0)
.from_data(products)
.indexed_by(lambda p: p.id)
)
Goal Programming¶
Mark constraints as goals for multi-objective optimization:
profit_goal = (
LXConstraint("profit")
.expression(profit_expr)
.ge()
.rhs(target_profit)
.as_goal(priority=1, weight=1.0) # High priority goal
)
quality_goal = (
LXConstraint("quality")
.expression(quality_expr)
.ge()
.rhs(target_quality)
.as_goal(priority=2, weight=0.5) # Lower priority
)
See: Examples for goal programming examples
Common Patterns¶
Resource Capacity¶
LXConstraint[Resource]("capacity")
.expression(
LXLinearExpression()
.add_term(production, lambda p, r: p.resource_usage[r.id])
)
.le()
.rhs(lambda r: r.capacity)
.from_data(resources)
.indexed_by(lambda r: r.id)
Demand Satisfaction¶
LXConstraint[Customer]("demand")
.expression(
LXLinearExpression()
.add_term(shipment, lambda s, c: 1.0 if s.destination == c else 0)
)
.ge()
.rhs(lambda c: c.demand)
.from_data(customers)
.indexed_by(lambda c: c.id)
Assignment Constraints¶
# Each task assigned to exactly one worker
LXConstraint[Task]("assign_task")
.expression(
LXLinearExpression()
.add_multi_term(assignment, lambda w, t2, t1=task: 1.0 if t1 == t2 else 0)
)
.eq()
.rhs(1)
.from_data(tasks)
.indexed_by(lambda t: t.id)
Best Practices¶
Use Descriptive Names
# Good resource_capacity = LXConstraint[Resource]("resource_capacity") # Bad c1 = LXConstraint("c1")
Choose Appropriate Sense
Use LE for upper limits
Use GE for lower limits
Use EQ only when necessary (more restrictive)
Index by Data
# Good: One constraint per resource .from_data(resources).indexed_by(lambda r: r.id) # Bad: Manual loops
Data-Driven RHS
# Good: RHS from data .rhs(lambda r: r.capacity) # Less flexible: Hard-coded .rhs(1000)
Next Steps¶
Expressions Guide - Build constraint expressions
Models Guide - Add constraints to models
Core Module API - Full API reference