文章目录
- 1. 线性规划基础
- 1.1 基本概念
- 1.2 求解方法
- 2 线性规划经典问题
- 2.1 生产计划问题
- 2. 2 运输问题
- 案例1:生产计划问题
- 背景
- 模型建立
- 模型求解
- 案例2:运输问题
- 背景
- 模型建立
- 模型求解
- 案例3:货机货物装载问题
- 问题背景
- 假设条件
- 问题要求
- 模型建立
- 模型求解
1. 线性规划基础
1.1 基本概念
线性规划(Linear Programming, LP)是一种数学优化方法,用于在给定的约束条件下,最大化或最小化一个线性目标函数。它在运筹学、经济学、工程学等领域中有广泛的应用。线性规划的基本形式可以表示为:
max (or min) z = c 1 x 1 + c 2 x 2 + ⋯ + c n x n \text{max (or min)} \quad z = c_1x_1 + c_2x_2 + \cdots + c_nx_n max (or min)z=c1x1+c2x2+⋯+cnxn
Subject to a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n ≤ b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n ≤ b 2 ⋮ a m 1 x 1 + a m 2 x 2 + ⋯ + a m n x n ≤ b m \text{Subject to} \quad \begin{aligned} a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n & \leq b_1 \\ a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n & \leq b_2 \\ & \vdots \\ a_{m1}x_1 + a_{m2}x_2 + \cdots + a_{mn}x_n & \leq b_m \end{aligned} Subject toa11x1+a12x2+⋯+a1nxna21x1+a22x2+⋯+a2nxnam1x1+am2x2+⋯+amnxn≤b1≤b2⋮≤bm
x 1 , x 2 , … , x n ≥ 0 x_1, x_2, \dots, x_n \geq 0 x1,x2,…,xn≥0
其中,z是目标函数, x 1 , x 2 , … , x n x_1, x_2, \dots, x_n x1,x2,…,xn 是决策变量, c 1 , c 2 , … , c n c_1, c_2, \dots, c_n c1,c2,…,cn是目标函数的系数, a i j a_{ij} aij是约束条件的系数, b i b_i bi 是约束条件的常数。线性规划的目标是找到决策变量的最优值,使得目标函数达到最大化(或最小化),同时满足所有约束条件。
1.2 求解方法
线性规划的求解方法主要包括图解法和单纯形法(Simplex Method)。图解法适用于决策变量个数较少(一般为两个)的情况,通过绘制可行解空间图,寻找目标函数的最优解。对于更复杂的多变量问题,单纯形法是一种更为通用和高效的求解方法。单纯形法通过在多面体的顶点之间移动,逐步寻找最优解。
此外,随着计算机技术的发展,内点法(Interior Point Method)等其他算法也得到了广泛应用。现代线性规划问题通常通过计算机软件,如MATLAB、LINDO、Gurobi等进行求解。
2 线性规划经典问题
2.1 生产计划问题
在一个工厂中,生产不同产品所需的原材料、劳动力和时间有限,而每种产品的利润不同。通过线性规划,可以在这些限制条件下,确定不同产品的生产数量,使得工厂的总利润最大化。例如,假设工厂需要生产两种产品,每种产品的利润分别为 p1 和 p2,需要的原材料和时间分别受到限制,目标是最大化利润:
Maximize z = p 1 x 1 + p 2 x 2 \text{Maximize} \quad z = p_1x_1 + p_2x_2 Maximizez=p1x1+p2x2
Subject to a 1 x 1 + a 2 x 2 ≤ b 1 (原材料约束) t 1 x 1 + t 2 x 2 ≤ b 2 (时间约束) x 1 , x 2 ≥ 0 \text{Subject to} \quad \begin{aligned} a_1x_1 + a_2x_2 & \leq b_1 \quad \text{(原材料约束)} \\ t_1x_1 + t_2x_2 & \leq b_2 \quad \text{(时间约束)} \\ x_1, x_2 & \geq 0 \end{aligned} Subject toa1x1+a2x2t1x1+t2x2x1,x2≤b1(原材料约束)≤b2(时间约束)≥0
通过求解这个线性规划问题,工厂可以得到在约束条件下的最优生产方案。
2. 2 运输问题
运输问题是线性规划的经典应用之一,旨在确定货物从多个供应点运送到多个需求点的最优方式,以最小化运输成本。假设有 m\个供应点和 n个需求点,每个供应点的供应量为 s i s_i si,每个需求点的需求量为 d j d_j dj,每单位货物从供应点 (i) 运输到需求点 (j) 的费用为 (c_{ij})。问题可以表述为:
Minimize z = ∑ i = 1 m ∑ j = 1 n c i j x i j \text{Minimize} \quad z = \sum_{i=1}^{m} \sum_{j=1}^{n} c_{ij}x_{ij} Minimizez=i=1∑mj=1∑ncijxij
Subject to ∑ j = 1 n x i j = s i ( i = 1 , 2 , … , m ) ∑ i = 1 m x i j = d j ( j = 1 , 2 , … , n ) x i j ≥ 0 for all i , j \text{Subject to} \quad \begin{aligned} \sum_{j=1}^{n} x_{ij} & = s_i \quad (i = 1, 2, \dots, m) \\ \sum_{i=1}^{m} x_{ij} & = d_j \quad (j = 1, 2, \dots, n) \\ x_{ij} & \geq 0 \quad \text{for all } i, j \end{aligned} Subject toj=1∑nxiji=1∑mxijxij=si(i=1,2,…,m)=dj(j=1,2,…,n)≥0for all i,j
通过求解这个问题,企业可以确定货物从供应点到需求点的最优运输方案。
案例1:生产计划问题
背景
某制造公司生产两种产品:产品A和产品B。公司希望在每月的生产计划中最大化利润。每种产品的生产需要耗费不同的资源,包括机器时间和人工时间,且公司有一定的资源限制。
-
资源限制:
- 每月可用的机器时间为2400小时。
- 每月可用的人工时间为1600小时。
-
产品生产:
- 生产1单位的产品A需要4小时的机器时间和2小时的人工时间,利润为每单位3元。
- 生产1单位的产品B需要2小时的机器时间和4小时的人工时间,利润为每单位4元。
目标:
公司希望确定每月应该生产多少单位的产品A和B,以最大化总利润。
模型建立
Maximize z = 3 x 1 + 4 x 2 \text{Maximize} \quad z = 3x_1 + 4x_2 Maximizez=3x1+4x2
Subject to 4 x 1 + 2 x 2 ≤ 2400 (机器时间约束) 2 x 1 + 4 x 2 ≤ 1600 (人工时间约束) x 1 , x 2 ≥ 0 \text{Subject to} \quad \begin{aligned} 4x_1 + 2x_2 & \leq 2400 \quad \text{(机器时间约束)} \\ 2x_1 + 4x_2 & \leq 1600 \quad \text{(人工时间约束)} \\ x_1, x_2 & \geq 0 \end{aligned} Subject to4x1+2x22x1+4x2x1,x2≤2400(机器时间约束)≤1600(人工时间约束)≥0
其中,x1 表示产品A的生产数量,x2 表示产品B的生产数量。
模型求解
参考代码如下:
from pulp import LpMaximize, LpProblem, LpVariable, LpStatus
# 创建线性规划问题对象,目标是最大化利润
model = LpProblem(name="production-planning", sense=LpMaximize)
# 决策变量
x1 = LpVariable(name="x1", lowBound=0) # 产品A的生产数量
x2 = LpVariable(name="x2", lowBound=0) # 产品B的生产数量
# 目标函数
model += 3 * x1 + 4 * x2, "Profit"
# 约束条件
model += (4 * x1 + 2 * x2 <= 2400), "Machine_Time_Constraint"
model += (2 * x1 + 4 * x2 <= 1600), "Labor_Time_Constraint"
# 求解问题
model.solve()
# 输出结果
print(f"Status: {LpStatus[model.status]}")
print(f"Optimal production of Product A: {x1.value()} units")
print(f"Optimal production of Product B: {x2.value()} units")
print(f"Maximum Profit: {model.objective.value()} units")
运行如下:
求解后得到的最优解为:
- 生产产品A的数量为 533.33 单位
- 生产产品B的数量为 133.33 单位
则最大利润为:
z = 3 × 533.33 + 4 × 133.33 = 1600 + 533.33 = 2133.33 元 z = 3 \times 533.33 + 4 \times 133.33 = 1600 + 533.33 = 2133.33 \, \text{元} z=3×533.33+4×133.33=1600+533.33=2133.33元
即每月生产 533.33 单位的产品A和 133.33 单位的产品B,可以实现最大利润 2133.33 元。
案例2:运输问题
背景
某物流公司有两个仓库A和B,分别供应商品给三个客户C1、C2、C3。每个仓库的库存和每个客户的需求量如下:
-
仓库库存:
- 仓库A:供应量为500单位。
- 仓库B:供应量为600单位。
-
客户需求:
- 客户C1:需求量为300单位。
- 客户C2:需求量为400单位。
- 客户C3:需求量为400单位。
-
运输费用(每单位):
- 从仓库A到C1、C2、C3的费用分别为2元、4元、5元。
- 从仓库B到C1、C2、C3的费用分别为3元、1元、6元。
目标:
确定从每个仓库运输到每个客户的数量,以最小化总运输费用。
模型建立
Minimize z = 2 x A 1 + 4 x A 2 + 5 x A 3 + 3 x B 1 + 1 x B 2 + 6 x B 3 \text{Minimize} \quad z = 2x_{A1} + 4x_{A2} + 5x_{A3} + 3x_{B1} + 1x_{B2} + 6x_{B3} Minimizez=2xA1+4xA2+5xA3+3xB1+1xB2+6xB3
Subject to x A 1 + x A 2 + x A 3 ≤ 500 (仓库A的供应量) x B 1 + x B 2 + x B 3 ≤ 600 (仓库B的供应量) x A 1 + x B 1 = 300 (客户C1的需求) x A 2 + x B 2 = 400 (客户C2的需求) x A 3 + x B 3 = 400 (客户C3的需求) x A 1 , x A 2 , x A 3 , x B 1 , x B 2 , x B 3 ≥ 0 \text{Subject to} \quad \begin{aligned} x_{A1} + x_{A2} + x_{A3} & \leq 500 \quad \text{(仓库A的供应量)} \\ x_{B1} + x_{B2} + x_{B3} & \leq 600 \quad \text{(仓库B的供应量)} \\ x_{A1} + x_{B1} & = 300 \quad \text{(客户C1的需求)} \\ x_{A2} + x_{B2} & = 400 \quad \text{(客户C2的需求)} \\ x_{A3} + x_{B3} & = 400 \quad \text{(客户C3的需求)} \\ x_{A1}, x_{A2}, x_{A3}, x_{B1}, x_{B2}, x_{B3} & \geq 0 \end{aligned} Subject toxA1+xA2+xA3xB1+xB2+xB3xA1+xB1xA2+xB2xA3+xB3xA1,xA2,xA3,xB1,xB2,xB3≤500(仓库A的供应量)≤600(仓库B的供应量)=300(客户C1的需求)=400(客户C2的需求)=400(客户C3的需求)≥0
模型求解
参考代码:
from pulp import LpMinimize, LpProblem, LpVariable, lpSum, LpStatus
# 创建线性规划问题对象,目标是最小化运输费用
model = LpProblem(name="transportation-problem", sense=LpMinimize)
# 决策变量
x_A1 = LpVariable(name="x_A1", lowBound=0) # 从仓库A到客户C1
x_A2 = LpVariable(name="x_A2", lowBound=0) # 从仓库A到客户C2
x_A3 = LpVariable(name="x_A3", lowBound=0) # 从仓库A到客户C3
x_B1 = LpVariable(name="x_B1", lowBound=0) # 从仓库B到客户C1
x_B2 = LpVariable(name="x_B2", lowBound=0) # 从仓库B到客户C2
x_B3 = LpVariable(name="x_B3", lowBound=0) # 从仓库B到客户C3
# 目标函数
model += lpSum([2*x_A1 + 4*x_A2 + 5*x_A3 + 3*x_B1 + 1*x_B2 + 6*x_B3]), "Total_Transport_Cost"
# 约束条件
model += (x_A1 + x_A2 + x_A3 <= 500), "Supply_Constraint_A"
model += (x_B1 + x_B2 + x_B3 <= 600), "Supply_Constraint_B"
model += (x_A1 + x_B1 == 300), "Demand_Constraint_C1"
model += (x_A2 + x_B2 == 400), "Demand_Constraint_C2"
model += (x_A3 + x_B3 == 400), "Demand_Constraint_C3"
# 求解问题
model.solve()
# 输出结果
print(f"Status: {LpStatus[model.status]}")
print(f"Optimal transport from A to C1: {x_A1.value()} units")
print(f"Optimal transport from A to C2: {x_A2.value()} units")
print(f"Optimal transport from A to C3: {x_A3.value()} units")
print(f"Optimal transport from B to C1: {x_B1.value()} units")
print(f"Optimal transport from B to C2: {x_B2.value()} units")
print(f"Optimal transport from B to C3: {x_B3.value()} units")
print(f"Minimum Transport Cost: {model.objective.value()} units")
运行如下:
求解后的最优方案为:
- 从仓库A向客户C1运送100单位,向客户C3运送400单位,不向客户C2运送。
- 从仓库B向客户C1运送200单位,向客户C2运送400单位,不向客户C3运送。
此时的最小总运输费用为:
z = 2 × 100 + 4 × 0 + 5 × 400 + 3 × 200 + 1 × 400 + 6 × 0 = 200 + 0 + 2000 + 600 + 400 + 0 = 3200 元 z = 2 \times 100 + 4 \times 0 + 5 \times 400 + 3 \times 200 + 1 \times 400 + 6 \times 0 = 200 + 0 + 2000 + 600 + 400 + 0 = 3200 \, \text{元} z=2×100+4×0+5×400+3×200+1×400+6×0=200+0+2000+600+400+0=3200元
案例3:货机货物装载问题
问题背景
一架货机有三个货舱:前舱、中舱和后舱。每个货舱能够装载的货物的最大重量和体积有限制,具体如表1.1所示。为了保证飞机的平衡,三个货舱装载的货物重量必须与其最大承载的容量成比例。
表1.1 货舱数据
货舱 | 重量限制 (吨) | 体积限制 (m³) |
---|---|---|
前舱 | 10 | 6800 |
中舱 | 16 | 8700 |
后舱 | 8 | 5300 |
现有四类货物可用该货机进行装运,货物的规格及装运后获得的利润如表1.2所列。
表1.2 货物规格及利润表
货物种类 | 重量 (吨) | 空间 (m³/吨) | 利润 (元/吨) |
---|---|---|---|
货物1 | 18 | 480 | 3100 |
货物2 | 15 | 650 | 3800 |
货物3 | 23 | 580 | 3500 |
货物4 | 12 | 390 | 2850 |
假设条件
- 每种货: 物可以无限细分;
- 每种货物可以分布在一个或多个货舱内;
- 不同的货物可以放在同一个货舱内,并且可以保证不留空隙。
问题要求
在满足各货舱重量和体积限制的前提下,如何安排货物装载,使得货机飞行后的总利润最大化?
根据您提供的图片中的内容,我们可以得到一个完整的线性规划问题,具体如下:
模型建立
-
决策变量:
每种货物放在每个货舱内的重量。用 x i j x_{ij} xij 表示第 i种货物放在第 j 个货舱内的重量,其中 i = 1, 2, 3, 4 分别表示货物1、货物2、货物3和货物4;j = 1, 2, 3 分别表示前舱、中舱和后舱。 -
目标函数:
最大化总利润:
Z = 3100 ( x 11 + x 12 + x 13 ) + 3800 ( x 21 + x 22 + x 23 ) + 3500 ( x 31 + x 32 + x 33 ) + 2850 ( x 41 + x 42 + x 43 ) Z = 3100(x_{11} + x_{12} + x_{13}) + 3800(x_{21} + x_{22} + x_{23}) + 3500(x_{31} + x_{32} + x_{33}) + 2850(x_{41} + x_{42} + x_{43}) Z=3100(x11+x12+x13)+3800(x21+x22+x23)+3500(x31+x32+x33)+2850(x41+x42+x43) -
约束条件:
-
每种货物的重量限制:
x 11 + x 12 + x 13 ≤ 18 ( 货物1的重量限制 ) x 21 + x 22 + x 23 ≤ 15 ( 货物2的重量限制 ) x 31 + x 32 + x 33 ≤ 23 ( 货物3的重量限制 ) x 41 + x 42 + x 43 ≤ 12 ( 货物4的重量限制 ) \begin{aligned} x_{11} + x_{12} + x_{13} & \leq 18 \quad (\text{货物1的重量限制}) \\ x_{21} + x_{22} + x_{23} & \leq 15 \quad (\text{货物2的重量限制}) \\ x_{31} + x_{32} + x_{33} & \leq 23 \quad (\text{货物3的重量限制}) \\ x_{41} + x_{42} + x_{43} & \leq 12 \quad (\text{货物4的重量限制}) \end{aligned} x11+x12+x13x21+x22+x23x31+x32+x33x41+x42+x43≤18(货物1的重量限制)≤15(货物2的重量限制)≤23(货物3的重量限制)≤12(货物4的重量限制) -
三个货舱的空间限制:
480 x 11 + 650 x 21 + 580 x 31 + 390 x 41 ≤ 6800 ( 前舱体积限制 ) 480 x 12 + 650 x 22 + 580 x 32 + 390 x 42 ≤ 8700 ( 中舱体积限制 ) 480 x 13 + 650 x 23 + 580 x 33 + 390 x 43 ≤ 5300 ( 后舱体积限制 ) \begin{aligned} 480x_{11} + 650x_{21} + 580x_{31} + 390x_{41} & \leq 6800 \quad (\text{前舱体积限制}) \\ 480x_{12} + 650x_{22} + 580x_{32} + 390x_{42} & \leq 8700 \quad (\text{中舱体积限制}) \\ 480x_{13} + 650x_{23} + 580x_{33} + 390x_{43} & \leq 5300 \quad (\text{后舱体积限制}) \end{aligned} 480x11+650x21+580x31+390x41480x12+650x22+580x32+390x42480x13+650x23+580x33+390x43≤6800(前舱体积限制)≤8700(中舱体积限制)≤5300(后舱体积限制) -
三个货舱的重量限制:
x 11 + x 21 + x 31 + x 41 ≤ 10 ( 前舱重量限制 ) x 12 + x 22 + x 32 + x 42 ≤ 16 ( 中舱重量限制 ) x 13 + x 23 + x 33 + x 43 ≤ 8 ( 后舱重量限制 ) \begin{aligned} x_{11} + x_{21} + x_{31} + x_{41} & \leq 10 \quad (\text{前舱重量限制}) \\ x_{12} + x_{22} + x_{32} + x_{42} & \leq 16 \quad (\text{中舱重量限制}) \\ x_{13} + x_{23} + x_{33} + x_{43} & \leq 8 \quad (\text{后舱重量限制}) \end{aligned} x11+x21+x31+x41x12+x22+x32+x42x13+x23+x33+x43≤10(前舱重量限制)≤16(中舱重量限制)≤8(后舱重量限制) -
三个货舱装入重量的平衡约束:
x 11 + x 21 + x 31 + x 41 10 = x 12 + x 22 + x 32 + x 42 16 = x 13 + x 23 + x 33 + x 43 8 \frac{x_{11} + x_{21} + x_{31} + x_{41}}{10} = \frac{x_{12} + x_{22} + x_{32} + x_{42}}{16} = \frac{x_{13} + x_{23} + x_{33} + x_{43}}{8} 10x11+x21+x31+x41=16x12+x22+x32+x42=8x13+x23+x33+x43
-
模型求解
参考Python代码:
from pulp import LpMaximize, LpProblem, LpVariable, LpStatus
# 创建线性规划问题对象,目标是最大化利润
model = LpProblem(name="cargo-loading", sense=LpMaximize)
# 决策变量,每种货物在每个舱内的重量
x11 = LpVariable(name="x11", lowBound=0) # 货物1在前舱的重量
x12 = LpVariable(name="x12", lowBound=0) # 货物1在中舱的重量
x13 = LpVariable(name="x13", lowBound=0) # 货物1在后舱的重量
x21 = LpVariable(name="x21", lowBound=0) # 货物2在前舱的重量
x22 = LpVariable(name="x22", lowBound=0) # 货物2在中舱的重量
x23 = LpVariable(name="x23", lowBound=0) # 货物2在后舱的重量
x31 = LpVariable(name="x31", lowBound=0) # 货物3在前舱的重量
x32 = LpVariable(name="x32", lowBound=0) # 货物3在中舱的重量
x33 = LpVariable(name="x33", lowBound=0) # 货物3在后舱的重量
x41 = LpVariable(name="x41", lowBound=0) # 货物4在前舱的重量
x42 = LpVariable(name="x42", lowBound=0) # 货物4在中舱的重量
x43 = LpVariable(name="x43", lowBound=0) # 货物4在后舱的重量
# 目标函数:最大化利润
model += (3100 * (x11 + x12 + x13) +
3800 * (x21 + x22 + x23) +
3500 * (x31 + x32 + x33) +
2850 * (x41 + x42 + x43)), "Total_Profit"
# 约束条件
# 1. 货物重量约束
model += (x11 + x12 + x13) <= 18, "Weight_Limit_Item1"
model += (x21 + x22 + x23) <= 15, "Weight_Limit_Item2"
model += (x31 + x32 + x33) <= 23, "Weight_Limit_Item3"
model += (x41 + x42 + x43) <= 12, "Weight_Limit_Item4"
# 2. 货舱的空间限制
model += (480 * x11 + 650 * x21 + 580 * x31 + 390 * x41) <= 6800, "Volume_Limit_Front"
model += (480 * x12 + 650 * x22 + 580 * x32 + 390 * x42) <= 8700, "Volume_Limit_Middle"
model += (480 * x13 + 650 * x23 + 580 * x33 + 390 * x43) <= 5300, "Volume_Limit_Back"
# 3. 货舱的重量限制
model += (x11 + x21 + x31 + x41) <= 10, "Weight_Limit_Front"
model += (x12 + x22 + x32 + x42) <= 16, "Weight_Limit_Middle"
model += (x13 + x23 + x33 + x43) <= 8, "Weight_Limit_Back"
# 4. 平衡约束
model += (x11 + x21 + x31 + x41) / 10 == (x12 + x22 + x32 + x42) / 16 == (x13 + x23 + x33 + x43) / 8, "Balance_Constraint"
# 求解模型
model.solve()
# 输出结果
print(f"Status: {model.status}, {LpStatus[model.status]}")
print(f"x11 = {x11.value()}")
print(f"x12 = {x12.value()}")
print(f"x13 = {x13.value()}")
print(f"x21 = {x21.value()}")
print(f"x22 = {x22.value()}")
print(f"x23 = {x23.value()}")
print(f"x31 = {x31.value()}")
print(f"x32 = {x32.value()}")
print(f"x33 = {x33.value()}")
print(f"x41 = {x41.value()}")
print(f"x42 = {x42.value()}")
print(f"x43 = {x43.value()}")
print(f"Total Profit = {model.objective.value()} 元")
运行代码得到最优结果。
最优装载方案:
- 前舱:
- 货物1:0.0 吨
- 货物2:10.0 吨
- 货物3:0.0 吨
- 货物4:0.0 吨
- 中舱:
- 货物1:0.0 吨
- 货物2:0.0 吨
- 货物3:12.947 吨
- 货物4:3.053 吨
- 后舱:
- 货物1:0.0 吨
- 货物2:5.0 吨
- 货物3:3.0 吨
- 货物4:0.0 吨
总利润:
最大化后的总利润为 121515.79 元。