我正在处理类似于pulp example
的混合问题我有这个约束来确保生产的数量是期望的数量
prob += lpSum([KG[i] * deposit_vars[i] for i in deposit]) == 64, "KGRequirement"
但是我还需要为最小值(不等于零)添加另一个约束,这是因为例如我服用0.002KG一种成分并不方便,所以我必须服用0或至少2kg,因此有效案例例如0、2、2.3、6、3.23。
我试图做到这一点:
for i in deposit:
prob += (KG[i] * deposit_vars[i] == 0) or (TM[i] * deposit_vars[i] >= 30)
但这不起作用,只会使问题变得不可行
编辑
这是我当前的代码:
import pulp
from pulp import *
import pandas as pd
food = ["f1","f2","f3","f4"]
KG = [10,20,50,80]
Protein = [18,12,16,18]
Grass = [13,14,13,16]
price_per_kg = [15,11,10,22]
## protein,carbohydrates,kg
df = pd.DataFrame({"tkid":food,"KG":KG,"Protein":Protein,"Grass":Grass,"value":price_per_kg})
deposit = df["tkid"].values.tolist()
factor_volumen = 1
costs = dict((k,v) for k,v in zip(df["tkid"],df["value"]))
Protein = dict((k,v) for k,v in zip(df["tkid"],df["Protein"]))
Grass = dict((k,v) for k,v in zip(df["tkid"],df["Grass"]))
KG = dict((k,v) for k,v in zip(df["tkid"],df["KG"]))
prob = LpProblem("The Whiskas Problem", LpMinimize)
deposit_vars = LpVariable.dicts("Ingr",deposit,0)
prob += lpSum([costs[i]*deposit_vars[i] for i in deposit]), "Total Cost of Ingredients per can"
#prob += lpSum([deposit_vars[i] for i in deposit]) == 1.0, "PercentagesSum"
prob += lpSum([Protein[i] *KG[i] * deposit_vars[i] for i in deposit]) >= 17.2*14, "ProteinRequirement"
prob += lpSum([Grass[i] *KG[i] * deposit_vars[i] for i in deposit]) >= 12.8*14, "FatRequirement"
prob += lpSum([KG[i] * deposit_vars[i] for i in deposit]) == 14, "KGRequirement"
prob += lpSum([KG[i] * deposit_vars[i] for i in deposit]) <= 80, "KGRequirement1"
prob.writeLP("WhiskasModel.lp")
prob.solve()
# The status of the solution is printed to the screen
print ("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print (v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen
print ("Total Cost of Ingredients per can = ", value(prob.objective))
我要添加的新禁忌素在这一部分:
prob += lpSum([KG[i] * deposit_vars[i] for i in deposit]) <= 80, "KGRequirement1"
我希望乘积KG [i] * deposit_vars [i]为0或介于 a 和 b
答案 0 :(得分:2)
在传统的线性规划公式中,所有变量,目标函数和约束都必须连续。您要问的是如何使此变量成为离散变量,即它只能接受值a,b,...,而不能接受两者之间的任何值。当您具有连续变量和离散变量的组合时,这称为混合整数问题(MIP)。 See PuLP documentation that reflects this explanation.我建议您仔细阅读“整数”中提到的混合问题。他们分散在页面上。根据PuLP的文档,它可以通过调用外部MIP求解器来解决MIP问题,其中一些已经包括在内。
在没有最低限度的工作示例的情况下,解释如何实现这一点有些棘手。一种方法是将变量指定为整数,并将其作为dict的值。保留默认的求解器COIN-OR's CBC solver求解器,即可求解MIP。同时,这里有一些可供您前进的资源:
答案 1 :(得分:1)
' or '不能直接在LP / MIP模型中使用。请记住,LP / MIP由线性目标和线性约束组成。
要建模x=0 or x≥L
,您可以使用所谓的半连续变量。最高级的求解器支持它们。我不认为Pulp支持这一点。作为解决方法,您还可以使用二进制变量δ:
δ*L ≤ x ≤ δ*U
其中U
是x
的上限。很容易看到这个效果:
δ = 0 ⇒ x = 0
δ = 1 ⇒ L ≤ x ≤ U
半连续变量不需要这些约束。只需告诉求解器变量x
是半连续的,边界为[L,U](如果没有上限,则为L)。
约束
a*x=0 or L ≤ a*x ≤ U
可以改写为
δ*L ≤ x*a ≤ δ*U
δ binary variable
这是一个相当标准的表述。半连续变量通常在财务(投资组合模型)中用于防止小额分配。
所有这些使模型保持完美的线性(不是二次方),因此可以使用标准的MIP求解器和标准的LP / MIP建模工具,例如Pulp。