PyGuLP Package

Submodules

glp.constraint module

class glp.constraint.Constraint(name: str, expression: Any, sense: ConstraintSense, rhs: float)[source]

Bases: object

Represents 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.

Type:

glp.enums.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: object

Core Goal Linear Programming (GLP) model.

This class wraps a PuLP LpProblem and 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: Enum

Relational 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: Enum

Goal 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: object

Represents 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:

glp.enums.GoalSense

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
sense: GoalSense = 'attain'
target: float
weight: float = 1.0

Module contents