小白零基础学数学建模系列-Day4-线性规划基础与案例分析

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++amnxnb1b2bm

x 1 , x 2 , … , x n ≥ 0 x_1, x_2, \dots, x_n \geq 0 x1,x2,,xn0

其中,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,x2b1(原材料约束)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=1mj=1ncijxij

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=1nxiji=1mxijxij=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,x22400(机器时间约束)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,xB3500(仓库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³)
前舱106800
中舱168700
后舱85300

现有四类货物可用该货机进行装运,货物的规格及装运后获得的利润如表1.2所列。

表1.2 货物规格及利润表

货物种类重量 (吨)空间 (m³/吨)利润 (元/吨)
货物1184803100
货物2156503800
货物3235803500
货物4123902850

假设条件

  1. 每种货: 物可以无限细分;
  2. 每种货物可以分布在一个或多个货舱内;
  3. 不同的货物可以放在同一个货舱内,并且可以保证不留空隙。

问题要求

在满足各货舱重量和体积限制的前提下,如何安排货物装载,使得货机飞行后的总利润最大化?

根据您提供的图片中的内容,我们可以得到一个完整的线性规划问题,具体如下:

模型建立

  • 决策变量
    每种货物放在每个货舱内的重量。用 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)

  • 约束条件

    1. 每种货物的重量限制
      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+x4318(货物1的重量限制)15(货物2的重量限制)23(货物3的重量限制)12(货物4的重量限制)

    2. 三个货舱的空间限制
      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+390x436800(前舱体积限制)8700(中舱体积限制)5300(后舱体积限制)

    3. 三个货舱的重量限制
      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+x4310(前舱重量限制)16(中舱重量限制)8(后舱重量限制)

    4. 三个货舱装入重量的平衡约束
      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 元

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川川菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值