线性规划
原创 发布时间:2026-05-07 | 更新时间:2026-06-08

线性规划(Linear Programming)在工程领域中随处可见,是在有限资源的情况寻找最优解的方法。

目标函数和限制条件都必须是线性方程 / 线性不等式(最高次项为1)才能称为线性规划

典型场景:

  • 生产计划:有限原料下最大化利润
  • 配送路线:最小化运输成本
  • 投资组合:在风险约束下最大化收益
  • 人力排班:满足需求下最小化人工成本

下面通过一个简单的例子说明

现实例子#

某工厂生产两种产品

  • 产品 A: 利润 3 万元/件,消耗资源1: 2 单位,消耗资源2: 1 单位
  • 产品 B: 利润 5 万元/件,消耗资源1: 1 单位,消耗资源2: 2 单位

资源 1 总量 10 单位,资源 2 总量 8 单位

请问应该如何安排生产,令利润最大化?

数学表达#

线性规划通常把问题拆解如下:

  • 决策变量:就是求解的目标(decision variables),对应上面的产品 A 的生产数量(设为 $x$)和产品 B 的生产数量(设为 $y$),本例就是求 $argmax_{x,y}\left(3x+5y\right)$

    $argmax_{x,y}\left(3x+5y\right)$ 表示 $x$ 和 $y$ 取何值时,函数 $f(x,y)=3x+5y$ 取得最大值

  • 目标函数:最大值(max)或最小值(min),本例中求 $max(3x+5y)$

    $max(3x+5y)$ 表示函数 $f(x,y)=3x+5y$ 的最大值

  • 约束条件:本例是 $2x+y \le 10$,$x+2y \le 8$,$x \ge 0$,$y \ge 0$

完整的数学表达为:$argmax_{x,y}\left(3x+5y\right) \quad \text{s.t.} \quad 2x+y \le 10, x+2y \le 8, x \ge 0, y \ge 0$

$\text{s.t.}$ 为 subject to 的缩写,意思为:约束于、受制于、满足于

单纯形法#

单纯形法(Simplex Method)是 George Dantzig 在 1947 年发表的论文 “Maximization of a Linear Function of Variables Subject to Linear Inequalities” 表述的方法,这是线性规划的第一个通用算法。

下面给出通俗的解读。

核心思想是,以决策变量作为坐标轴,按约束条件在坐标空间中划出一个可行的空间区域,然后移动目标函数等高线,在可行域内寻找是目标函数最优的点

按上面的例子,我们有两个决策变量,$x$ 和 $y$,我们画出以 $x$ 和 $y$ 为轴的平面直角坐标系。

可行域#

接下在画出可行域

  • 有约束条件 1:$2x+y \le 10$,画出直线 $y=-2x+10$(图中的绿线),取其下面的部分
  • 有约束条件 2:$x+2y \le 8$,画出直线 $y=-0.5x+4$(图中的蓝线),取其下面的部分
  • 有约束条件 3:$x \ge 0$,即取 $y$ 轴右边的部分
  • 有约束条件 4:$y \ge 0$,即取 $x$ 轴上面的部分

即可行域为由 $x$ 轴、$y$ 轴、直线 $y=-2x+10$、直线 $y=-0.5x+4$ 所围成的空间(图中黄色区域),是一个凸四边形。

-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 x -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 1 2 3 4 5 6 7 8 9 10 y y=-2x+10 y=-0.5x+4 (4,2) y = -(3/5)x + R/5

目标直线#

接下来我们看目标函数 $f(x,y)=3x+5y$,我们的目标是在约束条件下求函数 $f(x,y)$ 的最大值。

设最大值为 R,即 $R=3x+5y$ ,整理得 $y=-\frac{3}{5}x+\frac{R}{5}$。

也就是说,$R$ 无论最终取什么值,解一定落在上面这条直线上,而这条直线的斜率固定为 $-\frac{3}{5}$,截距为$\frac{R}{5}$。

如果我们保持直线斜率不变,在与可行域有相交的范围内移动直线 $y=-\frac{3}{5}x + \frac{R}{5}$(图中的红线),使其与 $y$ 轴的截距 $\frac{R}{5}$ 尽可能大,我们将得到最优解 $R$。

我们在原点 (0,0) 开始向右上方移动该直线(图中的红色虚线所示),发现直线与 $y$ 轴的截距越来越大,当直线通过点 (4,2) 时,截距达到最大值,直线与可行域恰恰相交于可行域凸四边形的一个顶点上。

该顶点为直线 $y=-2x+10$ 与直线 $y=-0.5x+4$ 的交点,解以这个两个方程组成的二元一次函数,得到交点为 (4,2)。

把点 (4,2) 代入方程 $R=3x+5y$ 就得到了 $R$ 的最大值 22。

即当产品 A 的生产数量为 4,产品 B 的生产数量为 2 时,可以获得最大利润 22 万元。

以上只是形象化的求解过程,因为线性规划的目标函数和约束条件都是线性的,最优解必定出现在可行域凸多边形的边界顶点上,所以也可以直接把可行域凸多边形的各个顶点直接代入目标函数,直接找出最大值。

程序求解#

方法一:利用 Scipy#

Scipy 有一个 linprog 模块,可以很方便计算出线性规划的最优解。

只需要给出目标函数系数约束条件系数目标变量取值范围

1. 目标函数系数 c#

前面例子的目标函数为 $f(x,y)=3x+5y$,求最大值,即求 $max(3x+5y)$。

Scipy 是固定计算最小值的,我们需要把目标函数转换成求最小值。

把系数取负号(赚得最多=亏得最少),即 $f(x,y)=-3x-5y$,求 $min(-3x-5y)$

所以得到目标函数的系数为

c = [-3, -5]

2. 约束条件系数 $A_{ub}$ $b_{ub}$#

Scipy 要求约束条件必须为 $\le$ 的形式。

本例的约束条件有

  • $2x+y \le 10$
  • $x+2y \le 8$

已满足 $\le$ 的形式,无需再化解。

所以约束条件系数为

A_ub = [[2, 1],   # 不等约束矩阵
        [1, 2]]
b_ub = [10, 8]    # 不等约束上限

本例的约束条件为不等约束($\le$),如果是相等约束,则使用 $A_{eq}$ 和 $b_{eq}$ 参数,写法类似,详情参数参考 API 文档

3. 目标变量取值范围 bounds#

我们再看看目标变量的取值范围。

本例中

  • $x \ge $0
  • $y \ge 0$

所以目标变量 $x$ 和 $y$ 的取值范围为

# None 表示没有限制
bounds = [(0, None), (0, None)]

4. 完整 Python 代码#

# pip install scipy
from scipy.optimize import linprog

# 目标函数系数(scipy是最小化,所以利润取负)
c = [-3, -5]

# 约束矩阵(不等式约束 ≤)
A_ub = [[2, 1],   # 约束条件系数1
        [1, 2]]   # 约束条件系数2
b_ub = [10, 8]    # 约束上限

# 目标变量的取值范围
bounds = [(0, None), (0, None)]

result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds)
print(f"产品 A: {result.x[0]: .2f} 件")
print(f"产品 B: {result.x[1]: .2f} 件")
print(f"最大利润: {-result.fun: .2f} 万元")

输出

产品 A:  4.00 件
产品 B:  2.00 件
最大利润:  22.00 万元

方法二:利用 PuLP#

通过 PuLP 库计算线性规划的最优解更直观, 只需要定义目标变量,然后组装目标函数和约束条件的表达式即可。

# pip install pulp
from pulp import LpProblem, LpMaximize, LpVariable, value

# 定义问题
prob = LpProblem("生产计划", LpMaximize) # LpMaximize 表示求最大值
x1 = LpVariable("产品 A", 0)  # x1 ≥ 0
x2 = LpVariable("产品 B", 0)  # x2 ≥ 0

# 目标函数
prob += 3*x1 + 5*x2     # 利润

# 约束
prob += 2*x1 + x2 <= 10 # 资源1
prob += x1 + 2*x2 <= 8  # 资源2

# 求解
prob.solve()
print(f"产品 A: {value(x1):.2f} 件")
print(f"产品 B: {value(x2):.2f} 件")
print(f"最大利润: {value(prob.objective):.2f} 万元")

输出

产品 A: 4.00 件
产品 B: 2.00 件
最大利润: 22.00 万元

结语#

本文主要讲解了线性规划的数学原理和程序通用解法。现实生活中,有还有很多问题是非线性的,这就会用到下一篇的非线性规划(Nonlinear Programming)


techunder_official 关注「Techunder技术人文」微信公众号,获取最新文章通知

版权所有 © 2026 Techunder (Guanhua Liu) | Copyright All Rights Reserved | 电子邮箱 Email:techunder@163.com

粤公网安备44060502004200号   粤ICP备2026007783号