在PuLP中设置最小与最大辅助变量的问题求解
问题分析
你的代码中min_weight始终为0的核心原因是:你将min_weight与所有货物的重量×分配变量做了<=约束,但未被选中的货物对应的重量×分配变量值为0,因此求解器会选择满足所有约束的最小可能值(0),而非实际分配的三个货物重量的最小值。
解决方案
正确的做法是先计算每辆卡车的实际装载重量(即该卡车选中货物的重量),再让max_weight大于等于所有卡车的实际重量,min_weight小于等于所有卡车的实际重量。这样max_weight会自动取三个卡车重量的最大值,min_weight取最小值。
修改后的完整代码如下:
import pulp # Example toy data cargo = { "truck1":{ "c1":{ "price":100, "weight":20 }, "c2":{ "price":150, "weight":10 }, "c3":{ "price":90, "weight":30 }, "c4":{ "price":500, "weight":80 } }, "truck2":{ "c5":{ "price":50, "weight":10 }, "c6":{ "price":100, "weight":80 }, "c7":{ "price":200, "weight":150 }, "c8":{ "price":50, "weight":30 } }, "truck3":{ "c9":{ "price":100, "weight":50 }, "c10":{ "price":200, "weight":200 } } } # Create a problem variable: prob = pulp.LpProblem("Cargo", pulp.LpMaximize) # Decision variables truck_allocation_vars = {truck: pulp.LpVariable.dicts("cargo", cargo[truck], 0, 1, pulp.LpBinary) for truck in cargo} # Constraint: Only one cargo can be chosen for each truck for truck in truck_allocation_vars: prob += pulp.lpSum(list(truck_allocation_vars[truck].values())) == 1 # Objective function: Maximize price prob += pulp.lpSum([cargo[truck_idx][cargo_idx]['price'] * truck_allocation_vars[truck_idx][cargo_idx] for truck_idx in truck_allocation_vars for cargo_idx in truck_allocation_vars[truck_idx]]) # 计算每辆卡车的实际装载重量 truck_weights = {} for truck in cargo: truck_weights[truck] = pulp.lpSum( cargo[truck][c]['weight'] * truck_allocation_vars[truck][c] for c in cargo[truck] ) # 定义最大、最小重量变量,并添加正确约束 max_weight = pulp.LpVariable("max_weight", cat=pulp.LpContinuous) min_weight = pulp.LpVariable("min_weight", cat=pulp.LpContinuous) # max_weight >= 每辆卡车的实际重量 for truck in truck_weights: prob += max_weight >= truck_weights[truck] # min_weight <= 每辆卡车的实际重量 for truck in truck_weights: prob += min_weight <= truck_weights[truck] # 添加重量差约束:最大值与最小值之差不超过50kg(LP中不能用<,改用<=) prob += (max_weight - min_weight) <= 50 # Solve the problem prob.solve() # Print the solution for truck_idx in truck_allocation_vars: for cargo_idx in truck_allocation_vars[truck_idx].keys(): if pulp.value(truck_allocation_vars[truck_idx][cargo_idx]) == 1: print(f"Cargo {cargo_idx} in truck {truck_idx} with price {cargo[truck_idx][cargo_idx]['price']} and weight {cargo[truck_idx][cargo_idx]['weight']}") print(f"Max weight: {pulp.value(max_weight)}") print(f"Min weight: {pulp.value(min_weight)}")
关键修改说明
- 计算卡车实际重量:通过
lpSum对每辆卡车的选中货物重量求和,得到该卡车的真实装载重量,而非单独处理每个货物项。 - 修正max/min约束:让
max_weight和min_weight直接与每辆卡车的实际重量绑定,确保它们取的是三个分配货物重量的极值。 - 约束符号修正:线性规划中不允许使用严格小于号
<,因此将max_weight - min_weight < 50改为<= 50。
内容的提问来源于stack exchange,提问作者jpsca1293
相关产品推荐
相关产品推荐

