PuLP:规范化多个决策变量并分配权重
Posted
技术标签:
【中文标题】PuLP:规范化多个决策变量并分配权重【英文标题】:PuLP: Normalizing multiple decision variables and assigning weights 【发布时间】:2021-10-02 08:12:39 【问题描述】:我有 4 组不同规模的决策变量。
dgp, dgm, (y_s1+y_s2), v
dgp, dgm, (y_s1+y_s2) 低于 1000 v 在 6000 到 16000 的范围内。 我想为目标函数中的 4 个变量中的每一个分配一定的权重,并考虑在添加权重之前将每个变量标准化为 0 到 1 之间。 你能告诉我应该怎么做吗?
from pulp import *
prob = LpProblem("SupplyAllocation", LpMinimize)
pairs = [(m, p) for m in month for p in part]
supply_s1 = LpVariable.dicts("supply_s1", (month, part), lowBound=0, cat='Continuous')
supply_s2 = LpVariable.dicts("supply_s2", (month, part), lowBound=0, cat='Continuous')
eoh = LpVariable.dicts("eoh", (month, part), lowBound=0, cat='Continuous')
v = LpVariable.dicts("cost", (part), lowBound=-100000, cat='Continuous')
w = LpVariable.dicts("w", (part), lowBound=-100000, cat='Continuous')
y_s1max = LpVariable.dicts("deltay_s1max", (part), lowBound=-100000, cat='Continuous')
y_s2max = LpVariable.dicts("deltay_s2max", (part), lowBound=-100000, cat='Continuous')
y_s1min = LpVariable.dicts("deltay_s1min", (part), lowBound=-100000, cat='Continuous')
y_s2min = LpVariable.dicts("deltay_s2min", (part), lowBound=-100000, cat='Continuous')
y_s1 = LpVariable.dicts("deltay_s1", (part), lowBound=-100000, cat='Continuous')
y_s2 = LpVariable.dicts("deltay_s2", (part), lowBound=-100000, cat='Continuous')
y_s = LpVariable.dicts("deltay_sall", (part), lowBound=-100000, cat='Continuous')
dgp = LpVariable.dicts("doigap_part", (part), lowBound=0, cat='Continuous')
dgm = LpVariable.dicts("doigap_mth", (month), lowBound=0, cat='Continuous')
z = LpVariable.dicts("z", (month, part), lowBound=0, cat='Continuous')
z1 = LpVariable.dicts("z1", (month, part), lowBound=-100000, cat='Continuous')
u1 = LpVariable.dicts("util_s1", (month, process), lowBound=-100000, cat='Continuous')
u2 = LpVariable.dicts("util_s2", (month, process), lowBound=-100000, cat='Continuous')
totcost = LpVariable("total_cost", lowBound = 0, cat='Continuous')
totgapp = LpVariable("total_gapp", lowBound = 0, cat='Continuous')
totgapm = LpVariable("total_gapm", lowBound = 0, cat='Continuous')
totrangep = LpVariable("total_rangep", lowBound = 0, cat='Continuous')
scalegapp = LpVariable("scalegapp", lowBound = 0, cat='Continuous')
prob += lpSum([dgp[p] for p in part])*1 + lpSum([dgm[m] for m in month])*1 + lpSum([y_s1[p]+y_s2[p] for p in part])*1 + lpSum([v[p] for p in part])*1
for p in part:
for m in month:
if month.index(m)==0:
prob += eoh[m][p] == boh[part.index(p)] + supply_s1[m][p] + supply_s2[m][p] - demand[month.index(m)][part.index(p)]
if month.index(m)>0:
prob += eoh[m][p] == eoh[month[month.index(m)-1]][p] + supply_s1[m][p] + supply_s2[m][p] - demand[month.index(m)][part.index(p)]
prob += z[m][p] >= - eoh[m][p] + target_eoh[month.index(m)][part.index(p)]
prob += z[m][p] >= eoh[m][p] - target_eoh[month.index(m)][part.index(p)]
prob += dgp[p] >= z[m][p]
prob += y_s1max[p] >= supply_s1[m][p]
prob += y_s1min[p] <= supply_s1[m][p]
prob += y_s2max[p] >= supply_s2[m][p]
prob += y_s2min[p] <= supply_s2[m][p]
prob += eoh[m][p] >= 0
prob += (supply_s2[m][p] * (alloc_max[month.index(m)][part.index(p)]/(1-alloc_max[month.index(m)][part.index(p)]))) - supply_s1[m][p] >= 0
prob += supply_s1[m][p] - (supply_s2[m][p] * (alloc_min[month.index(m)][part.index(p)]/(1-alloc_min[month.index(m)][part.index(p)]))) >= 0
prob += (supply_s1[m][p] * (alloc_max[month.index(m)][part.index(p)]/(1-alloc_max[month.index(m)][part.index(p)]))) - supply_s2[m][p] >= 0
prob += supply_s2[m][p] - (supply_s1[m][p] * (alloc_min[month.index(m)][part.index(p)]/(1-alloc_min[month.index(m)][part.index(p)]))) >= 0
for p in part:
prob += lpSum(supply_s1[m][p] + supply_s2[m][p] for m in month) >= tot_supply_min[part.index(p)]
prob += v[p] == [supply_s1[m][p]*price_s1[part.index(p)] for m in month]+ [supply_s2[m][p]*price_s2[part.index(p)] for m in month]
prob += y_s1[p] >= y_s1max[p] - y_s1min[p]
prob += y_s2[p] >= y_s2max[p] - y_s2min[p]
prob += y_s[p] >= y_s1[p]
prob += y_s[p] >= y_s2[p]
for m in month:
for p in part:
prob += dgm[m] >= z[m][p]
for m in month:
for pr in process:
prob += u1[m][pr] == lpSum(supply_s1[m][p] * steps_s1[process.index(pr)][part.index(p)] for p in part) / cap[process.index(pr)][supplier.index('S1')]
prob += u1[m][pr] <= 1
prob += u2[m][pr] == lpSum(supply_s2[m][p] * steps_s2[process.index(pr)][part.index(p)] for p in part) / cap[process.index(pr)][supplier.index('S2')]
prob += u2[m][pr] <= 1
prob += totcost == lpSum([v[p] for p in part])
prob += totgapp == lpSum([dgp[p] for p in part])
prob += totgapm == lpSum([dgm[m] for m in month])
prob += totrangep == lpSum([y_s1[p]+y_s2[p] for p in part])
prob.solve()
print ("Status:", LpStatus[prob.status])
for (m,p) in pairs:
solver_s1[m,p] = supply_s1[m][p].varValue
solver_s2[m,p] = supply_s2[m][p].varValue
for p in part:
cost[p] = v[p].varValue
SolverResult = LpStatus[prob.status]
【问题讨论】:
【参考方案1】:如果和不是常数,归一化不是线性的:
y[i] = x[i]/sum(x)
PuLP 只做线性程序,所以这很困难。还要注意
prob += u1[m][pr] <= 1
prob += u2[m][pr] <= 1
可以通过设置 u1 和 u2 的上限来替换
【讨论】:
以上是关于PuLP:规范化多个决策变量并分配权重的主要内容,如果未能解决你的问题,请参考以下文章
错误代码OpenAI权衡规范化get_variable tf1.4
Python:规范化权重的约束,使得没有权重大于 1/sqrt(n)