Python Package for Goal Linear Programming
Project description
📦 PyGuLP — Python Package for Goal Linear Programming
PyGuLP is a Python package for Goal Linear Programming (GLP) with an initial focus on Weighted Goal Programming (WGP).
The package is intended for multi-target linear optimization problems, where several desired outcomes must be balanced simultaneously under linear constraints. Such problems commonly arise in health and public health planning, environmental management, resource allocation, and policy analysis. The package itself is domain-agnostic and can be applied wherever linear models with multiple targets are appropriate.
The documentation of PyGuLP can be accessed from the AIDE Lab website.
Installation
pip install pygulp
Dependencies
Required:
- pulp
Optional:
- pandas
- matplotlib
Project structure
src/glp/
├── core.py # GLPModel and solver logic
├── goal.py # Goal dataclass
├── constraint.py # Constraint dataclass
├── enums.py # GoalSense and ConstraintSense enums
└── __init__.py
What is Goal Linear Programming?
Goal Linear Programming (GLP) is an extension of classical Linear Programming (LP) that allows multiple, potentially conflicting targets to be handled within a single linear optimization model.
In standard LP, a problem is formulated to optimize a single objective function subject to a set of constraints. In many real-world planning problems, however, the central question is not how to optimize one quantity, but how to achieve several targets as closely as possible while still satisfying feasibility conditions.
GLP addresses this by introducing deviation variables that explicitly measure how far the achieved solution deviates from each target. The objective function then minimizes these deviations according to their relative importance.
Conceptual overview
Traditional linear optimization optimizes a single objective function subject to a set of constraints.
GLP makes these trade-offs explicit by introducing deviation variables that measure how far the achieved solution departs from each target, and by minimizing these deviations according to their relative importance.
Goals, expressions, and deviation variables
Each goal in a GLP model specifies:
- what quantity is being measured
- what value is desired
- how important it is to meet that value
To formalize this, GLP constructs the following relationship for each goal:
expression + d- - d+ = target
where:
- expression is a linear function of decision variables
- target is the desired aspiration level
- d- measures under-achievement of the target
- d+ measures over-achievement of the target
The deviation variables satisfy:
d- >= 0, d+ >= 0
Only one of d- or d+ will be positive in an optimal solution, indicating whether the achieved value falls below or exceeds the target.
What is meant by an expression?
An expression defines how the achieved value of a goal is computed from the model’s decision variables.
Formally, an expression is a linear combination of decision variables:
expression = a1*x1 + a2*x2 + ... + an*xn
where:
- x1, x2, ..., xn are decision variables
- a1, a2, ..., an are known coefficients
The expression represents the achieved value of a quantity of interest as implied by the current choice of decision variables. The goal-linking equation then compares this achieved value to the specified target and measures any mismatch using deviation variables.
Expressions do not encode priorities or penalties. They only define how the model computes a quantity. Trade-offs are handled entirely through deviation variables and their associated weights.
Expressions can be as complex as multiple decision variable with associated co-efficients as shown above or as simple as a sum of two decision variables.
Weights and the optimization objective
Weights quantify the relative importance of goals.
In Weighted Goal Programming (as implemented in version 0.0.1), the optimization problem minimizes the weighted sum of deviations across all goals:
minimize sum( w * (d- + d+) ) where:
- w is the non-negative weight assigned to a goal
- larger weights enforce closer adherence to the corresponding target
Weights do not affect feasibility. They only determine how the solver trades off deviations between competing goals.
This formulation preserves linearity and keeps priorities explicit and interpretable.
Core modeling elements
Decision variables
Decision variables represent the quantities the model is allowed to choose. They are standard linear programming variables and may be:
- continuous
- integer
- binary
Decision variables define the degrees of freedom of the optimization problem.
Constraints
Constraints restrict the feasible region of the problem and must be satisfied by all solutions.
They take the standard linear form:
a1x1 + a2x2 + ... + an*xn <= / = / >= b
where x1..xn are decision variables and a1..an are fixed coefficients.
Constraints represent non-negotiable conditions such as limits, capacities, or regulatory bounds. Constraints define feasibility and do not introduce deviation variables.
Goals
Goals represent desired outcomes or aspiration levels that the model attempts to achieve as closely as possible.
A goal consists of:
- a linear expression
- a numeric target value
- a goal sense (attainment in version 0.0.1)
- a weight indicating importance
Goals may be under- or over-achieved, with deviations explicitly measured by d- and d+ and penalized in the objective.
In version 0.0.1, all goals are linked using the attainment form:
expression + d- - d+ = target
The direction and magnitude of deviation are governed entirely by the weights.
Weights
Weights quantify the relative importance of goals.
A higher weight implies that the optimization prioritizes bringing the achieved value closer to the target, allowing less deviation relative to other goals. Weights do not affect feasibility; they only govern trade-offs among goals.
Current features (Version 0.0.1)
- Weighted Goal Programming (WGP)
- Automatic creation of under- and over-deviation variables (d-, d+)
- Automatic construction of goal-linking constraints
- Constraints with senses: ≤, =, ≥
- Optional inclusion of a linear cost term in the objective
- Transparent linear programming backend via PuLP
- Deterministic solving with the CBC solver
Solver support
PyGuLP uses PuLP as its modeling layer.
- Default solver: CBC (bundled with PuLP)
Output
The solver returns a structured result containing:
- solver status
- decision variable values
- per-goal deviations (( d^{-}, d^{+} ))
- final objective value
This structure supports diagnostics, scenario comparison, and sensitivity analysis.
Essential classes
GLPModel
GLPModel is the central wrapper around a PuLP LpProblem. It maintains registries for decision variables, constraints, goals, and deviation variables.
Key responsibilities include:
- registering decision variables
- adding feasibility constraints
- adding goals and constructing deviation variables
- building and solving the weighted goal programming objective
Goal
A Goal defines one target to be approached:
name: unique identifierexpression: PuLP linear expressiontarget: numeric target valueweight: importance (nonnegative)
Defaults:
weight = 1.0priority = 1sense = GoalSense.ATTAIN
The target is treated as a fixed aspiration level, with deviations captured by d^- and d^+.
Constraint
A Constraint defines a feasibility restriction:
name: unique identifierexpression: PuLP linear expressionsense: <=, =, or >=rhs: numeric right-hand side
Quick start
Create a model
from glp.core import GLPModel
model = GLPModel("example_model")
Add decision variables
x = model.add_variable("Rice", low_bound=0)
y = model.add_variable("Dal", low_bound=0)
Variables may be continuous, integer, or binary via the cat argument.
Add constraints
from glp.constraint import Constraint
from glp.enums import ConstraintSense
budget = Constraint(
name="budget",
expression=2*x + 3*y,
sense=ConstraintSense.LE,
rhs=100
)
model.add_constraint(budget)
Add goals
from glp.goal import Goal
from glp.enums import GoalSense
energy_goal = Goal(
name="energy",
expression=5*x + 10*y,
target=200,
sense=GoalSense.ATTAIN,
weight=1.0
)
model.add_goal(energy_goal)
When a goal is added, GLP automatically creates the deviation variables d^- and d^+ and the corresponding goal-linking constraint.
Solve the model
result = model.solve_weighted()
Inspecting results
result["status"]
result["variables"]
result["deviations"]
result["objective"]
Each entry in result["deviations"] is a tuple:
(d_minus, d_plus)
indicating under- and over-achievement of the corresponding goal.
Typical use cases
- Health and public health planning
- Environmental and resource allocation
- Coverage versus cost trade-offs
- Policy target balancing
- Teaching and research in optimization
Reproducibility and transparency
- All models are standard linear programs
- No heuristics or hidden transformations
- Full access to the underlying PuLP model
- Deterministic solutions given solver settings
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pygulp-0.1.2.tar.gz.
File metadata
- Download URL: pygulp-0.1.2.tar.gz
- Upload date:
- Size: 17.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4fdcac0931ead20e9034673e5c5e4e1e5ee8190847760282cde6db474c87eb33
|
|
| MD5 |
0ff14941337b38adab8028ce4f8af8c7
|
|
| BLAKE2b-256 |
283e33e7f648a904c548127f4e13f1ed3306e7bcb89be5055da8b0c193ef75a0
|
File details
Details for the file pygulp-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pygulp-0.1.2-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9dd8becf65c175562e1818958e3addcb6e6c399e2cb1d3bdc3d7e74685e0540
|
|
| MD5 |
6e60c3ed7e0d8ddea46b08c37ead20b2
|
|
| BLAKE2b-256 |
9d810d3ffc614a018af492b6be74af16ec5d5d25c519a5b1c80c9049e93c326f
|