对于线性优化问题,我想加个惩罚。如果总和大于0,则每个选项的罚款(罚金[[i]])应为1,如果罚款为零,则罚金为0。有没有办法做到这一点?
惩罚定义为:
penalties = {}
for i in A:
penalties[(i)]=(lpSum(choices[i][k] for k in B))/len(C)
prob += Objective Function + sum(penalties)
例如:
penalties[(0)]=0
penalties[(1)]=2
penalties[(3)]=6
penalties[(4)]=0
处罚总和应为:
sum(penalties)=0+1+1+0= 2
答案 0 :(得分:1)
是的。您需要做的是创建二进制变量:use_ith_row
。如果==1
行的任何choices[i][k]
> = 0(否则为0),则此变量的解释为i
。
目标函数中的惩罚项只需为sum(use_ith_row[i] for i in A)
。
您需要做的最后一件事是执行上述规则的一组约束:
for i in A:
lpSum(choices[i][k] for k in B) <= use_ith_row[i]*M
最后,您需要选择足够大的M,以便在use_ith_row
为1时上述约束没有限制作用(通常可以很容易地计算出该界限)。选择一个太大的M
也可以,但会导致问题解决的速度变慢。
p.s。我不知道C
是什么,也不知道为什么要除以它的长度-但是通常,如果此惩罚是您对其他/主要目标的次要要求,则应对其进行加权,以便始终对主要目标的改进给予更大的重视。