线性规划数学模型精解

线性规划(Linear Programming, LP)是一种数学优化方法,用于在给定约束条件下最大化或最小化目标函数。线性规划广泛应用于经济、工程、管理等领域,通过建立数学模型,帮助决策者找到最优解决方案。

一、线性规划数学模型

1.1 模型三要素

  • 目标函数(Objective Function)
    目标函数是线性规划中需要优化的函数,通常表示为线性形式。目标函数可以是需最大化的利润或最小化的成本。例如,在一个生产问题中,目标函数可以是某种商品的总利润,需要通过调整生产量来最大化这个值。目标函数的一般形式为:

Z=c1x1+c2x2++cnxn

其中:Z是目标值;c1,c2,,cn是目标函数的系数;x1,x2,,xn 是决策变量。

  • 约束条件(Constraints)
    约束条件是限制决策变量取值范围的线性不等式或等式。这些条件通常反映了资源的有限性、技术限制等。例如,在生产问题中,约束条件可能包括生产时间、原材料、资金等的限制。约束条件的一般形式为:

a11x1+a12x2++a1nxnb1a21x1+a22x2++a2nxnb2am1x1+am2x2++amnxnbm

其中:aij是约束条件的系数;bi是约束条件的右端常数;m是约束条件的数量。

  • 非负性约束(Non-negativity Constraints)
    在大多数实际问题中,决策变量通常需要非负,即每个变量必须大于或等于零。这反映了实际情况中物理量(如生产量、时间等)不能为负值。非负性约束的一般形式为:x10,x20,,xn0

1.2 建模过程

问题描述:某公司生产两种产品A和B,每生产一单位A可获利3元,每生产一单位B可获利5元。生产A需要2小时工作时间和1单位原材料,生产B需要1小时工作时间和2单位原材料。现公司有100小时工作时间和80单位原材料。问公司应如何安排生产才能使利润最大化?

  • 决策变量

    • x1为产品A的生产数量,
    • x2为产品B的生产数量。
  • 目标函数
    需要最大化利润,目标函数为:

Maximize Z=3x1+5x2

  • 约束条件

    • 2x1+x2100(工作时间约束)
    • x1+2x280 (原材料约束)
  • 可行性约束

    • x10,x20

通过上述步骤,建立了一个完整的线性规划数学模型。该模型可以通过图解法、单纯形法或其他优化算法求解,从而找到最优生产方案。线性规划不仅为决策者提供了一种系统化的决策工具,而且在资源优化配置方面具有重要意义。

1.3 图解法

maxz=2x1+2x2s.t.5x1+2x2156x1+2x224x1+x25x1,x20

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import linprog

# 定义绘图的范围
x1 = np.linspace(0, 10, 400)

# 定义约束条件
y1 = 15 / 5
y2 = (24 - 6 * x1) / 2
y3 = 5 - x1

# 绘制可行域
plt.figure(figsize=(10, 8))
plt.plot(x1, y2, label=r'$6x_1 + 2x_2 \leq 24$')
plt.plot(x1, y3, label=r'$x_1 + x_2 \leq 5$')
plt.axhline(y=y1, color='r', linestyle='-', label=r'$5x_2 \leq 15$')
plt.xlim((0, 10))
plt.ylim((0, 10))
plt.xlabel(r'$x_1$')
plt.ylabel(r'$x_2$')

# 填充可行域
plt.fill_between(x1, 0, np.minimum(np.minimum(y1, y2), y3), where=(x1<=10), color='grey', alpha=0.5)

# 标记可行域
plt.legend()

# 求解线性规划问题
c = [-2, -1]  # 因为linprog求解的是最小化问题,所以目标函数取反
A = [[6, 2], [1, 1], [0, 5]]
b = [24, 5, 15]

# 使用linprog求解
res = linprog(c, A_ub=A, b_ub=b, bounds=(0, None), method='highs')

if res.success:
    # 绘制目标函数的最优解点
    plt.plot(res.x[0], res.x[1], 'ro', label='Optimal Solution')
    plt.legend()
    plt.show()

    print(f"Optimal value: {res.fun * -1:.2f}")  # 最大化目标函数的最优值
    print(f"Optimal solution: x1 = {res.x[0]:.2f}, x2 = {res.x[1]:.2f}")
else:
    print("No solution found")

二、建模示例

1.1 例1

某公司在计划期内要安排生产A、B两种产品(假设市场销路很好)。生产单位产品的利润以及所需的劳动力、设备台时以及原材料的消耗资料如下表所示。

产品 A B
劳动力(工时) 9 4 360
设备(台时) 4 5 200
原材料(千克) 3 10 300
单位产品利润 70 120
  • 决策变量

    • x1为产品A的生产数量
    • x2为产品B的生产数量
  • 目标函数
    最大化利润,目标函数为:

Maximize Z=70x1+120x2

  • 约束条件
    • 劳动力约束:9x1+4x2360
    • 设备台时约束:4x1+5x2200
    • 原材料约束:3x1+10x2300
    • 非负性约束:x10,x20

将上述内容整合,线性规划的数学模型为:

Maximize Z=70x1+120x2 subject to 9x1+4x2360 4x1+5x2200 3x1+10x2300 x10,x20

这个数学模型可以通过图解法或使用线性规划求解器(如linprog)求解,从而找到最优的生产数量x1x2以使得公司利润最大化。

1.2 例2

已知三种食物P,Q,R的维生素含量与成本如下表所示:

食物 维生素A (单位/kg) 维生素B (单位/kg) 成本 (元/kg)
食物P 400 800 6
食物Q 600 200 5
食物R 400 400 4

现在将的食物P,Q,R混合制成 100 kg 的混合物。要求这 100 kg 的混合物中至少含有维生素A 48000 单位与维生素B 44000 单位,那么如何混合配比该混合物的成本最小?

  • 变量定义

    • x1​: 食物 P 的重量 (kg)
    • x2​: 食物 Q 的重量 (kg)
    • x3 : 食物 R 的重量 (kg)
  • 目标函数

Minimize6x1+5x2+4x3

  • 约束条件

    • 总重量为100 kg: x1+x2+x3=100
    • 维生素A至少含有48000单位: x1+600x2+400x348000
    • 维生素B至少含有44000单位: 800x1+200x2+400x344000
    • 非负约束:x10,x20,x30
  • 数学模型

Minimize6x1+5x2+4x3subject tox1+x2+x3=100,400x1+600x2+400x348000,800x1+200x2+400x344000,x10,x20,x30.

from scipy.optimize import linprog
import numpy as np

# 目标函数系数
c = np.array([6, 5, 4])

# 不等式约束系数矩阵和右端向量
A = np.array([
    [-400, -600, -400],  # 转化为<=约束
    [-800, -200, -400]   # 转化为<=约束
])
b = np.array([-48000, -44000])

# 等式约束系数矩阵和右端向量
A_eq = np.array([
    [1, 1, 1]
])
b_eq = np.array([100])

# 变量非负约束
bounds = [(0, None), (0, None), (0, None)]

# 求解线性规划问题
result = linprog(c, A_ub=A, b_ub=b, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

# 输出结果
if result.success:
    print("各食物的最优供应量(kg):")
    print(f"食物 P: {result.x[0]:.2f} kg")
    print(f"食物 Q: {result.x[1]:.2f} kg")
    print(f"食物 R: {result.x[2]:.2f} kg")
    print(f"最小成本: {result.fun:.2f} 元")
else:
    print("未找到最优解")
各食物的最优供应量(kg):
食物 P: 30.00 kg
食物 Q: 40.00 kg
食物 R: 30.00 kg
最小成本: 500.00

三、练习案例

每种蓅菜含有的营养素成份是不同的, 从医学上知道每人每周对每种营养成分的最低需求量。某医院营养室在制定下一周菜单时, 需要确定表中所列六种蔬菜的供应量, 以便使费用最小而又能满足营养素等其它方面的要求。规定白菜的供应一周内不多于 20 kg , 其它蔬菜的供应在一周内不多于 40 kg , 每周共需供应 140 kg 蔬菜, 为了使费用最小又满足营养素等其它方面的要求,问在下一周内应当供应每种疏菜各多少 kg ?

序号 蔬菜 维生素A 维生素C 烟酸 每千克费用
1 青豆 0.45 10 415 8 0.30 5
2 胡萝卜 0.45 28 9065 3 0.35 5
3 菜花 1.05 59 2550 53 0.60 8
4 白菜 0.40 25 75 27 0.15 2
5 甜菜 0.50 22 15 5 0.25 6
6 土豆 0.50 75 235 8 0.80 3
要求蔬菜提供的营养 维生素A 维生素C 烟酸 备注
要求值 6.00 25 17500 245 5.00
  • 决策变量
    x1,x2,x3,x4,x5,x6分别为青豆、胡萝卜、菜花、白菜、甜菜、土豆的供应量(kg)。

  • 目标函数

Minimize Z=5x1+5x2+8x3+2x4+6x5+3x6

  • 约束条件
    满足营养需求,每种蔬菜的供应量上限,以及总供应量。
    • 铁的约束:0.45x1+0.45x2+1.05x3+0.40x4+0.50x5+0.50x66.00
    • 磷的约束:10x1+28x2+59x3+25x4+22x5+75x625
    • 维生素A的约束:415x1+9065x2+2550x3+75x4+15x5+235x617500
    • 维生素C的约束:8x1+3x2+53x3+27x4+5x5+8x6245
    • 烟酸的约束:0.30x1+0.35x2+0.60x3+0.15x4+0.25x5+0.80x65
    • 蔬菜供应量上限:x420x1,x2,x3,x5,x640
    • 总供应量:x1+x2+x3+x4+x5+x6=140
  • 非负性约束:

x1,x2,x3,x4,x5,x60

  • 数学模型

Minimize Z=5x1+5x2+8x3+2x4+6x5+3x6subject to 0.45x1+0.45x2+1.05x3+0.40x4+0.50x5+0.50x66.0010x1+28x2+59x3+25x4+22x5+75x625415x1+9065x2+2550x3+75x4+15x5+235x6175008x1+3x2+53x3+27x4+5x5+8x62450.30x1+0.35x2+0.60x3+0.15x4+0.25x5+0.80x65x420x1,x2,x3,x5,x640x1+x2+x3+x4+x5+x6=140x1,x2,x3,x4,x5,x60

#求解程序

import pulp

# 定义问题
prob = pulp.LpProblem("Vegetable Supply Problem", pulp.LpMinimize)

# 定义变量
x1 = pulp.LpVariable('青豆', lowBound=0)
x2 = pulp.LpVariable('胡萝卜', lowBound=0)
x3 = pulp.LpVariable('菜花', lowBound=0)
x4 = pulp.LpVariable('白菜', lowBound=0, upBound=20)
x5 = pulp.LpVariable('甜菜', lowBound=0)
x6 = pulp.LpVariable('土豆', lowBound=0)

# 目标函数
prob += 5*x1 + 5*x2 + 8*x3 + 2*x4 + 6*x5 + 3*x6, "Total Cost"

# 约束条件
prob += x1 + x2 + x3 + x4 + x5 + x6 == 140, "Total Supply"
prob += 0.45*x1 + 0.45*x2 + 1.05*x3 + 0.40*x4 + 0.50*x5 + 0.50*x6 >= 6, "Iron Requirement"
prob += 10*x1 + 28*x2 + 59*x3 + 25*x4 + 22*x5 + 75*x6 >= 25, "Phosphorus Requirement"
prob += 415*x1 + 9065*x2 + 2550*x3 + 75*x4 + 15*x5 + 235*x6 >= 17500, "Vitamin A Requirement"
prob += 8*x1 + 3*x2 + 53*x3 + 27*x4 + 5*x5 + 8*x6 >= 245, "Vitamin C Requirement"
prob += 0.30*x1 + 0.35*x2 + 0.60*x3 + 0.15*x4 + 0.25*x5 + 0.80*x6 >= 5, "Niacin Requirement"
prob += x1 <= 40, "Green Peas Upper Limit"
prob += x2 <= 40, "Carrots Upper Limit"
prob += x3 <= 40, "Cauliflower Upper Limit"
prob += x4 <= 20, "Chinese Cabbage Upper Limit"
prob += x5 <= 40, "Beet Upper Limit"
prob += x6 <= 40, "Potato Upper Limit"

# 求解问题
prob.solve()

# 打印结果
if pulp.LpStatus[prob.status] == 'Optimal':
    print("每种蔬菜的最优供应量(kg):")
    print(f"青豆: {pulp.value(x1):.2f} kg")
    print(f"胡萝卜: {pulp.value(x2):.2f} kg")
    print(f"菜花: {pulp.value(x3):.2f} kg")
    print(f"白菜: {pulp.value(x4):.2f} kg")
    print(f"甜菜: {pulp.value(x5):.2f} kg")
    print(f"土豆: {pulp.value(x6):.2f} kg")
    print(f"最小费用: {pulp.value(prob.objective):.2f} 元")
else:
    print("未找到最优解")
每种蔬菜的最优供应量(kg):
青豆: 40.00 kg
胡萝卜: 40.00 kg
菜花: 0.00 kg
白菜: 20.00 kg
甜菜: 0.00 kg
土豆: 40.00 kg
最小费用: 560.00

参考资料

  1. 《运筹学》考研考点讲义
  2. 《运筹学》知识点全总结
posted @   郝hai  阅读(793)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
历史上的今天:
2023-07-15 运筹学教学最便利的软件——WinQSB(可惜!)
2023-07-15 集装箱多式联运路径规划——动态规划求解
点击右上角即可分享
微信分享提示