运筹学练习Python精解——整数规划
练习1
一汽车厂生产小、中、大三种类型的汽车,已知各类型每辆车对钢材、劳动时间的需求,利润以及每月工厂钢材、劳动时间的现有量如下表所示,试制定月生产计划,使工厂的利润最大。进一步讨论:由于各种条件限制,如果生产某一类型汽车,则至少要生产80辆,那么最优的生产计划应作何改变。
资源/利润 | 小型汽车 | 中型汽车 | 大型汽车 | 现有量 |
---|---|---|---|---|
钢材 (吨) | 1.5 | 3 | 5 | 600 |
劳动时间(小时) | 280 | 250 | 400 | 60000 |
利润 (万元) | 2 | 3 | 4 |
目标是最大化利润,在满足钢材和劳动时间的约束条件下,决定每个月生产的小、中、大型汽车的数量。
1.1 不考虑如果生产某一类型汽车,则至少要生产80辆
-
定义决策变量:
表示生产小型车的数量;表示生产中型车的数量; 表示生产大型车的数量 -
目标函数:
最大化利润 -
约束条件:
钢材约束:
劳动时间约束: -
非负性约束:
from pulp import LpMaximize, LpProblem, LpVariable, lpSum, value, LpInteger
# 定义问题
problem = LpProblem("Maximize Profit", LpMaximize)
# 定义变量
x1 = LpVariable("x1", lowBound=0, cat=LpInteger)
x2 = LpVariable("x2", lowBound=0, cat=LpInteger)
x3 = LpVariable("x3", lowBound=0, cat=LpInteger)
# 目标函数
problem += 2 * x1 + 3 * x2 + 4 * x3
# 约束条件
problem += 1.5 * x1 + 3 * x2 + 5 * x3 <= 600
problem += 280 * x1 + 250 * x2 + 400 * x3 <= 60000
# 求解问题
problem.solve()
# 打印结果
print('Optimal production plan:')
print(f'Small cars: {value(x1):.0f}')
print(f'Medium cars: {value(x2):.0f}')
print(f'Large cars: {value(x3):.0f}')
print(f'Maximum Profit: {value(problem.objective):.2f} 万元')
Optimal production plan:
Small cars: 64
Medium cars: 168
Large cars: 0
Maximum Profit: 632.00 万元
1.2 考虑如果生产某一类型汽车,则至少要生产80辆
-
定义决策变量:需要添加3个0-1变量表示某一类型汽车是否生产
表示是否生产小型车(0 或 1); 表示是否生产中型车(0 或 1); 表示是否生产大型车(0 或 1) -
若生产某种类型的汽车,则至少生产80辆:
- 变量的约束:
from pulp import LpMaximize, LpProblem, LpVariable, lpSum, value
# 定义问题
problem = LpProblem("Maximize Profit", LpMaximize)
# 定义变量
x1 = LpVariable("x1", lowBound=0, cat='Integer')
x2 = LpVariable("x2", lowBound=0, cat='Integer')
x3 = LpVariable("x3", lowBound=0, cat='Integer')
y1 = LpVariable("y1", cat='Binary')
y2 = LpVariable("y2", cat='Binary')
y3 = LpVariable("y3", cat='Binary')
# 目标函数
problem += 2 * x1 + 3 * x2 + 4 * x3
# 约束条件
problem += 1.5 * x1 + 3 * x2 + 5 * x3 <= 600
problem += 280 * x1 + 250 * x2 + 400 * x3 <= 60000
problem += x1 >= 80 * y1
problem += x2 >= 80 * y2
problem += x3 >= 80 * y3
# 求解问题
problem.solve()
# 打印结果
print('Optimal production plan:')
print(f'Small cars: {value(x1):.0f}')
print(f'Medium cars: {value(x2):.0f}')
print(f'Large cars: {value(x3):.0f}')
print(f'Maximum Profit: {value(problem.objective):.2f} 万元')
Optimal production plan:
Small cars: 64
Medium cars: 168
Large cars: 0
Maximum Profit: 632.00 万元
练习2
固定成本问题:高压容器公司制造小、中、大三种尺寸的金属容器,所用资源为金属板、劳动力和机器设备,制造一个容器所需的各种资源数量如下表。不考虑固定费用,每种容器单位利润分别为4万元、5万元、6万元,可使用的金属板500吨,劳动力300人/月,机器100台/月,此外只要生产,需支付固定费用:小号是100万元,中号为150万元,大号为200万元。试制定一个生产计划,使获利最大。
资源 | 小号容器 | 中号容器 | 大号容器 |
---|---|---|---|
金属板 (t) | 2 | 4 | 8 |
劳动力 (人/月) | 3 | 4 | 2 |
机器设备 (台/月) | 1 | 0 | 1 |
-
定义决策变量:
表示生产小号容器的数量;表示生产中号容器的数量; 表示生产大号容器的数量
表示是否生产小号容器(0 或 1);表示是否生产中号容器(0 或 1);表示是否生产大号容器(0 或 1) -
目标函数:
最大化利润 -
约束条件:
金属板约束:
劳动力约束:
机器设备约束:
- 若生产某种类型的容器,则至少支付固定费用:
其中是一个足够大的常数。
- 变量的约束:
- 非负性约束:
from pulp import LpMaximize, LpProblem, LpVariable, lpSum, value, LpInteger, LpBinary
# 定义问题
problem = LpProblem("Maximize Profit", LpMaximize)
# 定义变量
x1 = LpVariable("x1", lowBound=0, cat=LpInteger)
x2 = LpVariable("x2", lowBound=0, cat=LpInteger)
x3 = LpVariable("x3", lowBound=0, cat=LpInteger)
y1 = LpVariable("y1", cat=LpBinary)
y2 = LpVariable("y2", cat=LpBinary)
y3 = LpVariable("y3", cat=LpBinary)
# 目标函数
problem += 4 * x1 + 5 * x2 + 6 * x3 - 100 * y1 - 150 * y2 - 200 * y3
# 约束条件
problem += 2 * x1 + 4 * x2 + 8 * x3 <= 500
problem += 3 * x1 + 4 * x2 + 2 * x3 <= 300
problem += x1 + x3 <= 100
# 固定费用约束
M = 10000 # 这里 M 取一个足够大的常数
problem += x1 <= M * y1
problem += x2 <= M * y2
problem += x3 <= M * y3
# 求解问题
problem.solve()
# 打印结果
print('Optimal production plan:')
print(f'Small containers: {value(x1):.0f}')
print(f'Medium containers: {value(x2):.0f}')
print(f'Large containers: {value(x3):.0f}')
print(f'Maximum Profit: {value(problem.objective):.2f} 万元')
Optimal production plan:
Small containers: 100
Medium containers: 0
Large containers: 0
Maximum Profit: 300.00 万元
练习3
设某企业在A地有一工厂,其产品的生产能力为30千箱,为扩大生产,打算在A2,A3,A4,A5地中再选择几个地方建厂。已知在A2,A3,A4,A5地建厂的固定成本分别为175千元、300千元、375千元、500千元,另外,A1产量及A2,A3,A4,A5建成厂的产量,销地的销量以及产地到销地的单位运价(每千箱运费)如下表。
产地\销地 | B1 | B2 | B3 | 产量/千箱 |
---|---|---|---|---|
A1 | 8 | 4 | 3 | 30 |
A2 | 5 | 2 | 3 | 10 |
A3 | 4 | 3 | 4 | 20 |
A4 | 9 | 7 | 5 | 30 |
A5 | 10 | 4 | 2 | 40 |
需求 | 30 | 20 | 20 | 70\130 |
该在哪几个地方建厂,在满足销量的前提下,使总固定成本和运输费用之和最小?
要解决这个问题,我们需要使用混合整数线性规划 (MILP)。我们需要引入 0-1 变量以确定在哪些地方建厂,并计算总固定成本和运输费用之和最小。
- 定义变量
表示在第个地方是否建厂,。
- 目标函数
最小化总成本,包括建厂的固定成本和运输成本:
其中:是第个地方的固定成本,是从第个地方向第个销售地运输的单位运输成本。
- 约束条件
- 每个销售地的需求必须满足:
其中:是第个销售地的需求。
- 每个生产地的供应不能超过其生产能力:
其中:是第个地方的生产能力。
-
初始工厂一定存在,生产能力为 30 千箱。
-
说明
变量 表示从第 个地方向第个销售地运输的箱数。需要进一步的数据来具体实现模型,包括固定成本,单位运输成本,销售地需求,以及每个地方的生产能力。
import pulp
# 固定成本
fixed_cost = [0, 175, 300, 375, 500]
# 生产能力
production_capacity = [30, 10, 20, 30, 40]
# 需求
demand = [30, 20, 20]
# 运输成本
transport_cost = [
[8, 4, 3],
[5, 2, 3],
[4, 3, 4],
[9, 7, 5],
[10, 4, 2]
]
# 创建模型
model = pulp.LpProblem("Factory_Expansion", pulp.LpMinimize)
# 定义变量
x = [pulp.LpVariable(f"x{i}", cat='Binary') for i in range(5)]
y = [[pulp.LpVariable(f"y{i}{j}", lowBound=0, cat='Continuous') for j in range(3)] for i in range(5)]
# 目标函数
model += pulp.lpSum(fixed_cost[i] * x[i] for i in range(1, 5)) + pulp.lpSum(transport_cost[i][j] * y[i][j] for i in range(5) for j in range(3))
# 需求约束
for j in range(3):
model += pulp.lpSum(y[i][j] for i in range(5)) >= demand[j]
# 生产能力约束
for i in range(5):
model += pulp.lpSum(y[i][j] for j in range(3)) <= production_capacity[i] * x[i]
# 初始工厂必须存在
model += x[0] == 1
# 解决问题
model.solve()
# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Build factory decisions (x):")
for i in range(5):
print(f"A{i+1}: {int(pulp.value(x[i]))}")
print("Transport decisions (y):")
transport_solution = [[pulp.value(y[i][j]) for j in range(3)] for i in range(5)]
for i in range(5):
print(f"A{i+1}: {transport_solution[i]}")
# 总成本
total_cost = pulp.value(model.objective)
print("Total Cost:", total_cost)
Transport decisions (y):
A1: [30.0, 0.0, 0.0]
A2: [0.0, 0.0, 0.0]
A3: [0.0, 0.0, 0.0]
A4: [0.0, 0.0, 0.0]
A5: [0.0, 20.0, 20.0]
Total Cost: 860.0
练习4
某公司考虑在北京、上海、广州、武汉四个城市中选择1-2个城市建设销售集散库房,负责向华北、华中、华南三个地区供货。每个库房每月可以处理货物1500件。有关的发货费用、建库成本和需求量见下表:
地点 | 华北(元/月) | 华中(元/月) | 华南(元/月) | 东北(元/月) | 仓库成本(元/月) |
---|---|---|---|---|---|
北京 | 200 | 400 | 500 | 300 | 45000 |
上海 | 300 | 250 | 400 | 500 | 50000 |
广州 | 600 | 350 | 300 | 750 | 70000 |
武汉 | 350 | 150 | 350 | 650 | 40000 |
需求量 | 500 | 800 | 750 | 400 |
在满足需求的前提下,请设计一个成本(发货成本+仓库成本)最省的建库方案。
import pulp
# 仓库成本
warehouse_cost = [45000, 50000, 70000, 40000]
# 运输成本
transport_cost = [
[200, 400, 500, 300],
[300, 250, 400, 500],
[600, 350, 300, 750],
[350, 150, 350, 650]
]
# 需求量
demand = [500, 800, 750, 400]
# 创建模型
model = pulp.LpProblem("Warehouse_Optimization", pulp.LpMinimize)
# 定义变量
x = [pulp.LpVariable(f"x{i}", cat='Binary') for i in range(4)]
y = [[pulp.LpVariable(f"y{i}{j}", lowBound=0, cat='Continuous') for j in range(4)] for i in range(4)]
# 目标函数
model += pulp.lpSum(warehouse_cost[i] * x[i] for i in range(4)) + pulp.lpSum(transport_cost[i][j] * y[i][j] for i in range(4) for j in range(4))
# 需求约束
for j in range(4):
model += pulp.lpSum(y[i][j] for i in range(4)) >= demand[j]
# 仓库处理能力约束
for i in range(4):
model += pulp.lpSum(y[i][j] for j in range(4)) <= 1500 * x[i]
# 必须在1-2个城市建库
model += pulp.lpSum(x[i] for i in range(4)) >= 1
model += pulp.lpSum(x[i] for i in range(4)) <= 2
# 解决问题
model.solve()
# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Build warehouse decisions (x):")
for i in range(4):
print(f"City {i+1}:", int(pulp.value(x[i])))
print("Transport decisions (y):")
transport_solution = [[pulp.value(y[i][j]) for j in range(4)] for i in range(4)]
for i in range(4):
print(f"City {i+1}: {transport_solution[i]}")
# 总成本
total_cost = pulp.value(model.objective)
print("Total Cost:", total_cost)
Transport decisions (y):
City 1: [500.0, 0.0, 50.0, 400.0]
City 2: [0.0, 0.0, 0.0, 0.0]
City 3: [0.0, 0.0, 0.0, 0.0]
City 4: [0.0, 800.0, 700.0, 0.0]
Total Cost: 695000.0
建议:
对于货费用和仓库成本较高的地区,企业应考虑优化物流网络,通过集中配送、提高装载率等方式降低成本。
对于需求量较高的地区,企业应考虑增加库存,提高响应速度,以满足市场需求。
综合考虑各地区的货费用、仓库成本和需求量,企业可以制定更为合理的区域发展策略,以实现资源的优化配置。
此外,企业还可以通过加强供应链管理、提高运营效率等方式,进一步降低整体物流成本,提高市场竞争力。
练习5
为了生产的需要,某工厂的一条生产线需要每天24小时不间断运转,但是每天不同时间段所需要的工人最低数量不同。具体数据如下表所示。已知每名工人的连续工作时间为8小时,则该工厂应该为该生产线配备多少名工人,才能保证生产线的正常运转?
班次 | 时间段 | 工人数量 |
---|---|---|
1 | 0:00-4:00 | 35 |
2 | 4:00-8:00 | 40 |
3 | 8:00-12:00 | 50 |
4 | 12:00-16:00 | 45 |
5 | 16:00-20:00 | 55 |
6 | 20:00-24:00 | 30 |
为了求解这个问题,我们可以将其视为覆盖问题(covering problem)。具体而言,我们需要为每天的6个时间段安排工人,使得每个时间段的工人数量需求得到满足。每名工人的连续工作时间为8小时,因此每名工人可以覆盖三个连续的时间段。
- 定义变量
表示在第 个班次开始时段安排的工人人数。
- 目标函数
最小化总工人人数:
- 约束条件
每个时间段的工人数量需求必须满足:
import pulp
# 定义问题
model = pulp.LpProblem("Shift_Scheduling", pulp.LpMinimize)
# 定义变量
x = [pulp.LpVariable(f"x{i}", lowBound=0, cat='Integer') for i in range(6)]
# 目标函数
model += pulp.lpSum(x[i] for i in range(6))
# 约束条件
model += x[0] + x[5] >= 35 # 0:00-4:00
model += x[0] + x[1] >= 40 # 4:00-8:00
model += x[1] + x[2] >= 50 # 8:00-12:00
model += x[2] + x[3] >= 45 # 12:00-16:00
model += x[3] + x[4] >= 55 # 16:00-20:00
model += x[4] + x[5] >= 30 # 20:00-24:00
# 解决问题
model.solve()
# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Number of workers starting at each shift:")
for i in range(6):
print(f"Shift {i+1}: {pulp.value(x[i])}")
# 总工人人数
total_workers = sum(pulp.value(x[i]) for i in range(6))
print("Total number of workers required:", total_workers)
Status: Optimal
Number of workers starting at each shift:
Shift 1: 0.0
Shift 2: 50.0
Shift 3: 0.0
Shift 4: 55.0
Shift 5: 0.0
Shift 6: 35.0
Total number of workers required: 140.0
练习6
社区理事会要决定在社区建设哪种娱乐设施,有四种备选方案:游泳池、网球场、运动场、健身房。理事会希望建立的设施使居民的预期日使用量最大。以下是每个设施的预期日使用量和成本约束条件。
娱乐设施 | 预期使用(人/天) | 成本($) | 土地需求(英亩) | 决策变量 |
---|---|---|---|---|
游泳池 | 300 | 35000 | 4 | x1 |
网球场 | 90 | 10000 | 2 | x2 |
运动场 | 400 | 25000 | 7 | x3 |
健身房 | 150 | 90000 | 3 | x4 |
理事会有120000美元的建设预算和12英亩土地。游泳池和网球场只能建一个,理事会如何建设娱乐设施组合能最大化预期使用量。
-
决策变量
:是否建设游泳池(1表示建设,0表示不建设)
:是否建设网球场(1表示建设,0表示不建设)
:是否建设运动场(1表示建设,0表示不建设)
:是否建设健身房(1表示建设,0表示不建设) -
目标函数
最大化预期使用量:
- 约束条件
- 成本约束
- 土地约束
- 互斥约束(游泳池和网球场只能建一个)
- 决策变量限制
import pulp
# 定义问题
model = pulp.LpProblem("Community_Facilities", pulp.LpMaximize)
# 定义变量
x1 = pulp.LpVariable('x1', cat='Binary')
x2 = pulp.LpVariable('x2', cat='Binary')
x3 = pulp.LpVariable('x3', cat='Binary')
x4 = pulp.LpVariable('x4', cat='Binary')
# 目标函数
model += 300 * x1 + 90 * x2 + 400 * x3 + 150 * x4
# 约束条件
model += 35000 * x1 + 10000 * x2 + 25000 * x3 + 90000 * x4 <= 120000, "Cost_Constraint"
model += 4 * x1 + 2 * x2 + 7 * x3 + 3 * x4 <= 12, "Land_Constraint"
model += x1 + x2 <= 1, "Mutual_Exclusion_Constraint"
# 解决问题
model.solve()
# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Optimal decisions:")
print("Build Swimming Pool (x1):", int(pulp.value(x1)))
print("Build Tennis Court (x2):", int(pulp.value(x2)))
print("Build Sports Field (x3):", int(pulp.value(x3)))
print("Build Gym (x4):", int(pulp.value(x4)))
print("Maximum Expected Daily Usage:", pulp.value(model.objective))
Status: Optimal
Optimal decisions:
Build Swimming Pool (x1): 1
Build Tennis Court (x2): 0
Build Sports Field (x3): 1
Build Gym (x4): 0
Maximum Expected Daily Usage: 700.0
练习7
某食品厂在西南部和中西部有种植和收获土豆的农场,然后把土豆运到A、B、C三个加工厂,在这些加工厂中生产包括薯条在内的不同种类的土豆产品。公司正在考虑购买6个新的农场来生产更多的土豆产品。
新农场固定成本和预计产量
农场 | 固定年成本(千美元) | 预计年产量(千吨) |
---|---|---|
1 | 405 | 11.2 |
2 | 390 | 10.5 |
3 | 450 | 12.8 |
4 | 368 | 9.3 |
5 | 520 | 10.8 |
6 | 465 | 9.6 |
三个工厂的剩余加工能力
工厂 | 可用加工能力(千吨) |
---|---|
A | 12 |
B | 10 |
C | 14 |
农场到加工厂的运输成本
农场 \ 加工厂 | A | B | C |
---|---|---|---|
1 | 18 | 15 | 12 |
2 | 13 | 10 | 17 |
3 | 16 | 14 | 18 |
4 | 19 | 15 | 16 |
5 | 17 | 19 | 12 |
6 | 14 | 16 | 12 |
公司应该购买哪几个农场能以最小的总成本满足可用的加工能力?(总成本包括固定成本和运输成本)
整数线性规划问题建模
-
决策变量
:是否购买农场(1表示购买,0表示不购买),。
:从农场向加工厂运输的土豆数量(千吨),。 -
目标函数
最小化总成本,包括固定成本和运输成本:
- 约束条件
- 加工厂的需求约束
- 每个农场的供应量约束
- 非负约束和整数约束
import pulp
# 定义问题
model = pulp.LpProblem("Farm_Selection", pulp.LpMinimize)
# 定义数据
fixed_costs = [405, 390, 450, 368, 520, 465]
productions = [11.2, 10.5, 12.8, 9.3, 10.8, 9.6]
capacities = [12, 10, 14]
transport_costs = [
[18, 15, 12],
[13, 10, 17],
[16, 14, 18],
[19, 15, 16],
[17, 19, 12],
[14, 16, 12]
]
# 定义决策变量
y = [pulp.LpVariable(f"y{i+1}", cat='Binary') for i in range(6)]
x = [[pulp.LpVariable(f"x{i+1}_{j+1}", lowBound=0) for j in range(3)] for i in range(6)]
# 目标函数
model += pulp.lpSum(fixed_costs[i] * y[i] for i in range(6)) + \
pulp.lpSum(transport_costs[i][j] * x[i][j] for i in range(6) for j in range(3))
# 约束条件
# 加工厂的需求约束
for j in range(3):
model += pulp.lpSum(x[i][j] for i in range(6)) >= capacities[j]
# 农场的供应量约束
for i in range(6):
model += pulp.lpSum(x[i][j] for j in range(3)) <= productions[i] * y[i]
# 解决问题
model.solve()
# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Optimal decisions:")
for i in range(6):
print(f"Purchase farm {i+1}:", int(pulp.value(y[i])))
# 以 transport_costs 格式输出结果
transport_plan = [[pulp.value(x[i][j]) for j in range(3)] for i in range(6)]
print("Transportation plan (transport_costs format):")
for i in range(6):
print(f"Farm {i+1}: {transport_plan[i]}")
print("Total cost:", pulp.value(model.objective))
Transportation plan (transport_costs format):
Farm 1: [0.0, 0.0, 11.2]
Farm 2: [2.4, 8.1, 0.0]
Farm 3: [0.0, 0.0, 0.0]
Farm 4: [0.0, 1.9, 2.8]
Farm 5: [0.0, 0.0, 0.0]
Farm 6: [9.6, 0.0, 0.0]
Total cost: 2082.3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!