PyGuLP Package
Submodules
glp.constraint module
- class glp.constraint.Constraint(name: str, expression: Any, sense: ConstraintSense, rhs: float)[source]
Bases:
objectRepresents a single algebraic constraint.
- name
Identifier for the constraint. Useful for reporting and debugging.
- Type:
str
- expression
The left-hand side expression of the constraint. This can be a symbolic expression, an expression tree, or any object understood by the modeling layer consuming this dataclass.
- Type:
Any
- sense
The relational direction of the constraint, as a ConstraintSense.
- rhs
The numeric right-hand side against which the expression is compared.
- Type:
float
Notes
This class does not evaluate expressions; it only carries structure.
Validation in __post_init__ ensures type safety for ‘sense’ and ‘rhs’.
- expression: Any
- name: str
- rhs: float
- sense: ConstraintSense
glp.core module
Core structures for Goal Linear Programming (GLP).
This module provides the fundamental building blocks to formulate and solve Goal Linear Programming problems using PuLP, including:
Decision variable management
Variable grouping and group-level bounds
Goal definitions with deviation variables
Hard constraints
Weighted Goal Programming solver
This file is intentionally minimal and generic, forming the foundation for higher-level problem-specific models (e.g., diet optimization).
- class glp.core.GLPModel(name: str = 'glp', minimize: bool = True)[source]
Bases:
objectCore Goal Linear Programming (GLP) model.
This class wraps a PuLP
LpProblemand provides a structured API to:Add decision variables (individually or in groups)
Organize variables into named groups
Apply collective lower/upper bounds to groups of variables
Define goals with deviation variables (under- and over-achievement)
Add hard constraints
Solve the model using Weighted Goal Programming
The design is intentionally generic and problem-agnostic, allowing this core model to be reused across diverse optimization problems.
- add_constraint(c: Constraint) None[source]
Add a hard constraint to the model.
Hard constraints must always be satisfied; infeasible models will fail unless relaxed externally.
- Parameters:
c (Constraint) – Constraint object defining the expression, sense, and RHS.
- Raises:
ValueError – If a constraint with the same name already exists.
- add_goal(g: Goal) Tuple[LpVariable, LpVariable][source]
Add a goal to the model and create its deviation variables.
- For a goal of the form:
expression ≈ target
- The following linking constraint is added:
expression + n - p = target
- where:
n = under-achievement deviation (>= 0) p = over-achievement deviation (>= 0)
These deviation variables are later penalized in the objective during Weighted Goal Programming.
- Parameters:
g (Goal) – Goal definition including expression, target, and weight.
- Returns:
(negative_deviation_variable, positive_deviation_variable)
- Return type:
tuple
- Raises:
ValueError – If a goal with the same name already exists.
- add_group_bounds(group: str, lower: float | None = None, upper: float | None = None) None[source]
Apply collective lower and/or upper bounds to a group of variables.
- Internally, this creates constraints of the form:
sum(group_variables) >= lower sum(group_variables) <= upper
- Parameters:
group (str) – Name of the variable group.
lower (float, optional) – Collective lower bound for the group.
upper (float, optional) – Collective upper bound for the group.
- Raises:
KeyError – If the specified group does not exist.
- add_to_group(group: str, variables: Iterable[str]) None[source]
Add existing variables to a named variable group.
Variable groups allow collective operations such as applying group-level lower and upper bounds.
- Parameters:
group (str) – Name of the group.
variables (iterable of str) – Names of variables to add to the group.
- Raises:
KeyError – If any variable does not exist in the model.
- add_variable(name: str, low_bound: float | None = 0, up_bound: float | None = None, cat: str = 'Continuous') LpVariable[source]
Add a single decision variable to the model.
If a variable with the same name already exists, the existing variable is returned.
- Parameters:
name (str) – Name of the decision variable.
low_bound (float, optional) – Lower bound for the variable (default is 0).
up_bound (float, optional) – Upper bound for the variable (default is None).
cat (str, optional) – Variable category: “Continuous”, “Integer”, or “Binary”.
- Returns:
The created (or existing) PuLP variable.
- Return type:
pulp.LpVariable
- add_variables(names: Iterable[str], low_bound: float | None = 0, up_bound: float | None = None, cat: str = 'Continuous', group: str | None = None) Dict[str, LpVariable][source]
Add multiple decision variables at once.
All variables share the same bounds and category. Optionally, the variables can be assigned to a named group for later group-level operations (e.g., collective bounds).
- Parameters:
names (iterable of str) – Names of the variables to be added.
low_bound (float, optional) – Lower bound for all variables.
up_bound (float, optional) – Upper bound for all variables.
cat (str, optional) – Variable category (“Continuous”, “Integer”, “Binary”).
group (str, optional) – Name of a variable group to assign these variables to.
- Returns:
Mapping from variable name to PuLP variable.
- Return type:
dict
- solve_weighted(goal_weights: Dict[str, Tuple[float, float]] | None = None, cost_expr: LpAffineExpression | None = None, cost_weight: float = 0.0) Dict[str, Any][source]
Solve the model using Weighted Goal Programming (WGP).
- The objective minimized is:
cost_weight * cost_expr + sum(w_minus * n_i + w_plus * p_i) over all goals
- Parameters:
goal_weights (dict, optional) – Mapping: goal_name -> (weight_under, weight_over). If not provided, each goal’s default weight is used.
cost_expr (pulp.LpAffineExpression, optional) – Linear expression representing cost or another primary objective.
cost_weight (float, optional) – Weight applied to the cost expression.
- Returns:
Dictionary containing: - status: solver status string - variables: values of all decision and deviation variables - deviations: (n, p) values for each goal - objective: final objective value
- Return type:
dict
glp.enums module
- class glp.enums.ConstraintSense(*values)[source]
Bases:
EnumRelational senses for constraints.
Each member maps to the corresponding mathematical operator represented as a string. These are commonly used to annotate constraints of the form expression (sense) rhs.
Members: - LE: “<=” Left-hand side must be less than or equal to the right-hand side. - GE: “>=” Left-hand side must be greater than or equal to the right-hand side. - EQ: “==” Left-hand side must be equal to the right-hand side. - LT: “<” Left-hand side must be strictly less than the right-hand side. - GT: “>” Left-hand side must be strictly greater than the right-hand side.
- EQ = '=='
- GE = '>='
- GT = '>'
- LE = '<='
- LT = '<'
- class glp.enums.GoalSense(*values)[source]
Bases:
EnumGoal semantics for goal programming.
These senses describe how deviations from a target are interpreted and penalized in a goal-programming model.
Members: - ATTAIN: “attain”
Aim to match the target value as closely as possible (both under- and over-target deviations may be penalized).
- MINIMIZE_UNDER: “minimize_under”
Prefer values at or below the target (value <= target). Typically interpreted as penalizing over-target (positive) deviations only.
- MINIMIZE_OVER: “minimize_over”
Prefer values at or above the target (value >= target). Typically interpreted as penalizing under-target (negative) deviations only.
- ATTAIN = 'attain'
- MINIMIZE_OVER = 'minimize_over'
- MINIMIZE_UNDER = 'minimize_under'
glp.goal module
- class glp.goal.Goal(name: str, expression: Any, target: float, sense: GoalSense = GoalSense.ATTAIN, weight: float = 1.0, priority: int = 1)[source]
Bases:
objectRepresents a goal-programming objective component.
- name
Identifier for the goal. Used for reporting and analysis.
- Type:
str
- expression
The quantity whose deviation from ‘target’ is considered. Can be a symbolic expression or any object supported by the modeling layer.
- Type:
Any
- target
The target value the expression should attain or relate to.
- Type:
float
- sense
A GoalSense describing which deviations are penalized (e.g., ATTAIN, MINIMIZE_UNDER, MINIMIZE_OVER).
- Type:
- weight
Non-negative weight applied to this goal’s deviation in the objective.
- Type:
float
- priority
Lexicographic priority (integer >= 1). Lower numbers typically indicate higher priority in preemptive goal programming.
- Type:
int
Notes
This class validates weight non-negativity, priority type/range, and the sense enum in __post_init__.
- Interpretation of ‘sense’:
ATTAIN: penalize both under- and over-target deviations.
MINIMIZE_UNDER: prefer value <= target; penalize over-target deviations.
MINIMIZE_OVER: prefer value >= target; penalize under-target deviations.
- expression: Any
- name: str
- priority: int = 1
- target: float
- weight: float = 1.0