PuLP:规范化多个决策变量并分配权重

问题描述

我有 4 组不同规模的决策变量。

dgp,dgm,(y_s1+y_s2),v

dgp,(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",cat='Continuous')
eoh = LpVariable.dicts("eoh",cat='Continuous')
v = LpVariable.dicts("cost",(part),lowBound=-100000,cat='Continuous')
w = LpVariable.dicts("w",cat='Continuous')
y_s1max = LpVariable.dicts("deltay_s1max",cat='Continuous')
y_s2max = LpVariable.dicts("deltay_s2max",cat='Continuous')
y_s1min = LpVariable.dicts("deltay_s1min",cat='Continuous')
y_s2min = LpVariable.dicts("deltay_s2min",cat='Continuous')
y_s1 = LpVariable.dicts("deltay_s1",cat='Continuous')
y_s2 = LpVariable.dicts("deltay_s2",cat='Continuous')
y_s = LpVariable.dicts("deltay_sall",cat='Continuous')
dgp = LpVariable.dicts("doigap_part",cat='Continuous')
dgm = LpVariable.dicts("doigap_mth",(month),cat='Continuous')
z = LpVariable.dicts("z",cat='Continuous')
z1 = LpVariable.dicts("z1",cat='Continuous')
u1 = LpVariable.dicts("util_s1",process),cat='Continuous')
u2 = LpVariable.dicts("util_s2",cat='Continuous')
totcost = LpVariable("total_cost",lowBound = 0,cat='Continuous')
totgapp = LpVariable("total_gapp",cat='Continuous')
totgapm = LpVariable("total_gapm",cat='Continuous')
totrangep = LpVariable("total_rangep",cat='Continuous')
scalegapp = LpVariable("scalegapp",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]

解决方法

如果总和不是常数,则归一化不是线性的:

 y[i] = x[i]/sum(x)

PuLP 只做线性程序,所以这很困难。还要注意

    prob += u1[m][pr] <= 1
    prob += u2[m][pr] <= 1

可以通过在 u1 和 u2 上设置上限来替换

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...