iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
scipy.optimize.linprog solves continuous linear programs by minimizing an objective such as c @ x, subject to linear inequalities, equalities, and variable bounds. To use it, put the objective coefficients in c, encode each inequality and equality as a row of its own constraint matrix, set bounds for each decision variable, then check the returned solver status before using the result.
How linprog represents a linear program
The function minimizes a linear objective over a decision vector x. Its standard form is:
minimize c @ x
subject to A_ub @ x <= b_ub
A_eq @ x == b_eq
lb <= x <= ub
c contains one objective coefficient per variable. Each row of A_ub describes one less-than-or-equal constraint and the matching entry in b_ub is its right-hand side. Equalities use the separate pair A_eq and b_eq. Bounds apply to individual variables. The function minimizes; for a maximization model, negate the objective coefficients and interpret the resulting objective with the sign reversed. See the linprog reference for the current API details.
Recommended Free Tools
Translate a model into arrays
Suppose a business chooses quantities x and y to minimize cost, with the constraints x + 2y >= 8 and 3x + y >= 9. Because linprog expects inequalities in less-than-or-equal form, multiply each constraint by -1:
#1 Best Overall
import numpy as np
from scipy.optimize import linprog
# Minimize 2x + 3y
c = np.array([2, 3])
# -(x + 2y) <= -8; -(3x + y) <= -9
A_ub = np.array([
[-1, -2],
[-3, -1],
])
b_ub = np.array([-8, -9])
# x and y are nonnegative
bounds = [(0, None), (0, None)]
result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method="highs")
Array positions must stay aligned: the first column of each constraint matrix corresponds to x, the second to y, and the entries of c and bounds follow that same order. The example is a formulation, not a claim about a computed optimum; run it in your environment and inspect the solver result.
Adding equality constraints
For a requirement such as x + y = 5, provide a row in A_eq and its target in b_eq. If the model has no equalities, omit both arguments.
Rank #2
A_eq = np.array([[1, 1]])
b_eq = np.array([5])
result = linprog(
c,
A_ub=A_ub,
b_ub=b_ub,
A_eq=A_eq,
b_eq=b_eq,
bounds=bounds,
method="highs",
)
The corresponding right-hand-side vector must have one entry per matrix row. SciPy’s optimization tutorial demonstrates assembling these inputs and passing them to linprog.
Set variable bounds deliberately
By default, each variable has bounds (0, None): it cannot be negative and has no finite upper limit. This default fits nonnegative quantities, but not every model. Pass a bounds pair for each variable to allow negative values or impose limits; None means that side has no finite bound.
# x may be negative; y is between 0 and 10
bounds = [(None, None), (0, 10)]
Bounds are not a substitute for the model’s other constraints: use them for individual-variable limits and use A_ub or A_eq for relationships among variables.
Choose a method
The documented default is method="highs". It selects automatically between HiGHS dual simplex ("highs-ds") and HiGHS interior-point ("highs-ipm"). Starting with "highs" is appropriate for a general model; the documentation does not establish one alternative as universally faster or better, so choose a specific method only when you have a workload-specific reason to do so.
Check whether the solver succeeded
linprog returns an OptimizeResult. Check success before treating its solution fields as a valid optimum. An unsuccessful result may reflect an infeasible model or another solver outcome; inspect message and status rather than assuming that a vector exists or is usable.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsif result.success:
print("Solution:", result.x)
print("Objective:", result.fun)
print("Inequality slack:", result.slack)
print("Equality residual:", result.con)
else:
print("Solver did not report success:", result.message)
print("Status:", result.status)
x contains the reported decision-variable values, fun the objective value, slack the inequality slack values, and con the equality residuals. Use these fields to interpret a successful result in light of your original model. A solver’s infeasibility message means the supplied constraints and bounds do not admit the reported feasible solution; revisit their signs, units, right-hand sides, and bounds. The official tutorial includes an infeasible example, underscoring that not every formulation has a feasible solution.
Best Value
When linprog is not the right solver
linprog is for continuous linear programming: its variables are not constrained to integer values. Rounding a continuous solution afterward does not impose integrality during optimization and is not generally equivalent to solving an integer model. For mixed-integer linear programming, SciPy lists scipy.optimize.milp separately from its continuous linear-programming tools. Consult the SciPy optimization reference to choose the appropriate function.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

