如何在Pulp运输优化模型中添加最小运输量约束?
用Pulp实现工厂运输量的最小阈值约束
要实现「若某工厂存在运输量(总运输值>0),则该运输量必须至少为5000」的约束,需要引入二进制变量建模逻辑关系,具体步骤如下:
建模思路
对每个工厂定义一个二进制变量(取值0或1):
- 变量为1时:表示工厂有运输行为,此时总运输量需≥5000
- 变量为0时:表示工厂无运输行为,此时总运输量必须=0
通过两个约束实现逻辑控制:
- 工厂总运输量 ≤ 二进制变量 × 工厂最大产能:确保二进制变量为0时,运输量只能是0
- 工厂总运输量 ≥ 5000 × 二进制变量:确保二进制变量为1时,运输量至少为5000
修改后的完整代码
from pulp import * capacityFactory = { "Factory01": 56000, "Factory02": 50000, "Factory03": 40000, "Factory04": 30000, "Factory05": 37000, "Factory06": 42000, "Factory07": 45000, "Factory08": 52000, "Factory09": 57000 } factories = capacityFactory.keys() orderBalance = { "Order01": 14000, "Order02": 35000, "Order03": 76000, "Order04": 36000, "Order05": 72000, "Order06": 41000, "Order07": 12000, "Order08": 56000, "Order09": 10000, "Order10": 7000 } orders = orderBalance.keys() # 运输路径成本矩阵 cost = [ # 列对应订单 [3.26, 9.31, 8.49, 5.96, 8.61, 5.45, 6.2, 7.31, 4.89, 8.34], # Factory01 [5.5, 8.75, 9.67, 5.05, 8.54, 5.5, 6.3, 7.36, 4.35, 8.51], # Factory02 [4.66, 8.36, 8.13, 4.33, 8.59, 5.6, 6.4, 7.42, 4.91, 9.71], # Factory03 [1.66, 1.36, 1.88, 2.77, 100, 5.65, 6.5, 7.89, 5.21, 7.01], # Factory04 [2.456, 6.54, 7.4, 3.54, 7.98, 5.44, 6.4, 7.89, 5.21, 7.01], # Factory05 [3.54, 6.98, 8.24, 3.12, 7.77, 5.12, 6.52, 7.12, 5.16, 7.5], # Factory06 [2.15, 4.54, 7.87, 3.15, 7.45, 5.396, 6.98, 7.02, 5, 7.4], # Factory07 [2.48, 5.55, 8.341, 3.19, 7.48, 5.9, 6.21, 7.23, 5.08, 7.36], # Factory08 [3.41, 5.69, 8.14, 3.22, 7.66, 5.87, 6.35, 8.23, 5.39, 7.99], # Factory09 ] cost = makeDict([factories, orders], cost, 0) prob = LpProblem("Material_Shipment_Problem", LpMinimize) Routes = [(w, b) for w in factories for b in orders] vars = LpVariable.dicts("Receive", (factories, orders), 0, None, LpInteger) # 新增:为每个工厂定义二进制变量,标记是否启用运输 factory_used = LpVariable.dicts("Factory_Used", factories, cat=LpBinary) # 目标函数:最小化总运输成本 prob += ( lpSum([vars[w][b] * cost[w][b] for (w, b) in Routes]), "Sum_of_Transporting_cost", ) # 工厂产能上限约束 for w in factories: prob += ( lpSum([vars[w][b] for b in orders]) <= capacityFactory[w], "Max_Capacity_%s" % w, ) # 订单需求下限约束 for b in orders: prob += ( lpSum([vars[w][b] for w in factories]) >= orderBalance[b], "Min_Demand_%s" % b, ) # 新增:运输量阈值约束 MIN_SHIPMENT = 5000 for w in factories: total_shipment = lpSum([vars[w][b] for b in orders]) # 约束1:未启用的工厂运输量必须为0 prob += total_shipment <= capacityFactory[w] * factory_used[w], f"Shipment_Cap_If_Used_{w}" # 约束2:启用的工厂运输量至少为5000 prob += total_shipment >= MIN_SHIPMENT * factory_used[w], f"Shipment_Min_If_Used_{w}" # 非负约束 for w in factories: for b in orders: prob += ( vars[w][b] >= 0, "Non_Negative_%s_to_%s" % (w, b), ) # 求解并输出结果 prob.solve() for v in prob.variables(): if v.varValue > 0: print(v.name, "=", v.varValue) print("总运输成本 = ", value(prob.objective))
关键修改说明
- 新增二进制变量:
factory_used字典,每个工厂对应一个0/1变量,标记是否有运输行为 - 添加阈值约束:
- 第一个约束通过工厂最大产能乘以二进制变量,限制未启用工厂的运输量为0
- 第二个约束通过最小阈值乘以二进制变量,确保启用的工厂运输量不低于5000
- 输出时只打印非零变量,简化结果展示
内容的提问来源于stack exchange,提问作者Maurício Rosa
相关产品推荐
相关产品推荐

