To solve a linear programming problem in Python, you call scipy.optimize.linprog with an objective vector c, inequality constraints A_ub and b_ub, optional equality constraints A_eq and b_eq, and variable bounds. The function minimizes c @ x under those restrictions. Before you use the returned vector, check whether the solver reported success. The notes below follow the SciPy 1.18.0 manual, so check the documentation for your installed version if it differs.
The model linprog solves
SciPy documents linprog as minimizing a linear objective subject to linear equalities, linear inequalities, and variable bounds, as described in the SciPy linprog reference. In standard notation:
As an Amazon Associate I earn from qualifying purchases.
minimize c @ x
subject to A_ub @ x <= b_ub
A_eq @ x == b_eq
lb <= x <= ub
Here x is the vector of decision variables, c holds the objective coefficients, each row of A_ub is one inequality constraint with its right-hand side in the matching position of b_ub, and the same pairing applies to A_eq and b_eq. Inequalities and equalities always use separate matrix and right-hand-side pairs.
A maximization problem is handled by negating the objective, because the function only minimizes. Likewise, a constraint written as “at least” must be multiplied through by -1 so it fits the <= form.
#1 Best Overall
Translating a problem into linprog inputs
The official SciPy optimization tutorial assembles these pieces as NumPy arrays. Follow the same order:
- Write the objective. List one coefficient per variable, in a fixed variable order, and store it as
c. For maximizingx1 + 2*x2, usec = [-1, -2]. - Write the upper-bound constraints. Put each “less than or equal to” row in
A_uband its right-hand side inb_ub. Convert “greater than or equal to” rows by negating both sides. - Write the equality constraints, if any. Place them in
A_eqandb_eq. Leave both out when the model has none. - Set the bounds. Pass one
(lower, upper)pair per variable. UseNonefor a side with no limit. - Call the solver and inspect the result before using
res.x.
A complete worked example
Consider maximizing x1 + 2*x2 subject to x1 + x2 <= 4, x1 >= 0, and 0 <= x2 <= 3. Because the solver minimizes, the objective becomes -x1 - 2*x2:
Rank #2
import numpy as np
from scipy.optimize import linprog
c = np.array([-1, -2]) # minimize -(x1 + 2*x2)
A_ub = np.array([[1, 1]]) # x1 + x2 <= 4
b_ub = np.array([4])
bounds = [(0, None), (0, 3)] # x1 >= 0; 0 <= x2 <= 3
res = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method='highs')
print(res.success, res.status, res.message)
print(res.x, res.fun)
The optimum of this model is at x = [1, 3], where the objective -x1 - 2*x2 equals -7. The maximum of the original objective is therefore 7. This result is specific to these inputs; a different objective or constraint set will have its own optimum.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesInfeasible models
A model can have no point that satisfies all of its constraints. The official tutorial illustrates this case, and the solver reports the problem through its status and message rather than returning a usable solution. For example, requiring x1 + x2 >= 5 while also requiring x1 + x2 <= 4 cannot be satisfied:
A_ub = np.array([[-1, -1], # -(x1 + x2) <= -5, i.e. x1 + x2 >= 5
[ 1, 1]]) # x1 + x2 <= 4
b_ub = np.array([-5, 4])
res = linprog(c, A_ub=A_ub, b_ub=b_ub, method='highs')
print(res.success, res.message)
Here res.success is false, and res.message describes the failure. Do not read res.x as an answer in this case.
Bounds and nonnegativity
The documented default for every variable is (0, None), meaning nonnegative with no finite upper limit. If a variable can be negative or has a cap, you must state that explicitly. The following forms are the ones the reference’s bounds convention supports:
| Bound entry | Meaning |
|---|---|
(0, None) |
Nonnegative, no upper limit (the default) |
(None, None) |
Free variable, unbounded on both sides |
(-2, None) |
Lower limit of -2, no upper limit |
(0, 3) |
Between 0 and 3 inclusive |
Because the default applies silently, a variable you intended to be free will be restricted to nonnegative values unless you set its bounds. Check the bounds list whenever a solution looks suspiciously clipped at zero.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Choosing a method
The current reference signature uses method='highs', which the reference describes as selecting automatically between two HiGHS algorithms. For most beginner models, leave the default in place or pass method='highs' explicitly, as the example above does.
Best Value
| Method value | What the reference documents |
|---|---|
highs |
Default; chooses between highs-ds and highs-ipm automatically |
highs-ds |
HiGHS dual simplex algorithm |
highs-ipm |
HiGHS interior-point algorithm |
The documentation does not establish that either algorithm is faster or more accurate for every workload, so choose one only when you have a specific reason, and measure on your own model if performance matters.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Reading the result
The returned object is an OptimizeResult. The fields most often used are:
| Field | What it contains |
|---|---|
x |
The solution vector, one entry per variable |
fun |
The objective value c @ x at that solution |
slack |
Slack of each inequality constraint |
con |
Residual of each equality constraint |
success |
Whether the solver reports a successful solve |
status |
Numeric status code from the solver |
message |
Human-readable description of the outcome |
Check success and status first. Fields such as x and fun can be populated in unsuccessful runs too, so a value being present does not establish that the solve worked.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Integer variables
linprog solves continuous linear programs. It does not impose integer restrictions. The official tutorial notes that solving a continuous relaxation and then rounding its values is not the same as requiring integers during the solve, and the rounded result may be infeasible or suboptimal. For models with integer or binary decisions, SciPy’s optimization reference lists milp for mixed-integer linear programming. Use it for those models rather than rounding the output of linprog.
Quick Recap
Checklist before you trust a solution
- The objective is written as a minimization, with maximization converted by negation.
- Every “greater than or equal” constraint has been rewritten in
<=form. - Bounds are set for every variable, and no variable is unintentionally restricted to nonnegative values.
res.successis true andres.statusis zero before you useres.x.- The solution satisfies the original business or modeling constraints, checked by substitution.
“
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.




