我正在解决纸浆运输优化问题,我有一定的工厂和订单,并且根据每个工厂的运输成本,我必须生成旨在成本最小化的最佳优化。 我的算法有效,但我需要创建一个约束,例如,如果有工厂移动,则最小移动必须为 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()
# Creates a list of cost of each transportation path
cost = [ # orders
[3.26, 9.31, 8.49, 5.96, 8.61, 5.45, 6.2, 7.31, 4.89, 8.34], # A factories
[5.5, 8.75, 9.67, 5.05, 8.54, 5.5, 6.3, 7.36, 4.35, 8.51], # B
[4.66, 8.36, 8.13, 4.33, 8.59, 5.6, 6.4, 7.42, 4.91, 9.71], # C
[1.66, 1.36, 1.88, 2.77, 100, 5.65, 6.5, 7.89, 5.21, 7.01], # D
[2.456, 6.54, 7.4, 3.54, 7.98, 5.44, 6.4, 7.89, 5.21, 7.01], # E
[3.54, 6.98, 8.24, 3.12, 7.77, 5.12, 6.52, 7.12, 5.16, 7.5], # F
[2.15, 4.54, 7.87, 3.15, 7.45, 5.396, 6.98, 7.02, 5, 7.4], # G
[2.48, 5.55, 8.341, 3.19, 7.48, 5.9, 6.21, 7.23, 5.08, 7.36], # H
[3.41, 5.69, 8.14, 3.22, 7.66, 5.87, 6.35, 8.23, 5.39, 7.99], # I
]
cost = makeDict([factories, orders], cost, 0)
prob = LpProblem("Material capacityFactory Problem", LpMinimize)
Routes = [(w, b) for w in factories for b in orders]
vars = LpVariable.dicts("Receive", (factories, orders), 0, None, LpInteger)
prob += (
lpSum([vars[w][b] * cost[w][b] for (w, b) in Routes]),
"Sum_of_Transporting_cost",
)
# The capacityFactory maximum constraints are added to prob for each capacityFactory node (factories)
for w in factories:
prob += (
lpSum([vars[w][b] for b in orders]) <= capacityFactory[w],
"Sum_of_Products_out_of_factories_%s" % w,
)
# The orderBalance minimum constraints are added to prob for each orderBalance node (project)
for b in orders:
prob += (
lpSum([vars[w][b] for w in factories]) >= orderBalance[b],
"Sum_of_Products_into_orders%s" % b,
)
# Add non-negativity constraints for all variables
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():
print(v.name, "=", v.varValue)
print("Value of Objective Function = ", value(prob.objective))
如何使用 Pulp 来实现此约束?
您正在寻找的概念是“半连续”变量的实现,其中变量为 0 或在某个范围内。这个网站上有很多例子。
我假设一家工厂要么根本不使用,要么必须用于至少 5000 个任何类型的订单,所以...
本质上你想要:
引入另一个二进制指示变量来指示工厂是否用于任何订单
use[factory] ∈ {0, 1} 1 if used, 0 else
然后您需要将每个工厂的工厂活动限制为零或相关范围
∑ receive[factory, order] for all orders ≤ use[factory] * max_orders[factory]
和
∑ receive[factory, order] for all orders ≥ use[factory] * min_orders[factory]
如果您的程序开始变慢,我还鼓励您考虑将
receive
设置为连续变量而不是整数。使用连续变量求解总是更快,并且当您的情况下数字“很大”达到 10,000 时,通常连续近似就可以了。