如何将条件约束应用于 Python Pulp 函数

问题描述

我正在使用 Python 中的 Pulp 设置线性优化.我想为这个问题设置一个条件约束.

I'm setting up a linear optimization using Pulp in Python. I would like to set up a conditional constrain to the problem.

比如,我想最大化工厂的利润.对于材料的成本,前 1000 个单位成本为 5 美元,任何更多单位成本为 3 美元.例如,如果工厂订购 1100 台,总成本将为 1000*5+100*3.我有一个材料列表:material_list,一个材料基准字典:benchmark_dic={material_a: 1000, material_b:2000 ....},一个字典如果订单损失超过基准价格:price_A_dic,则价格,如果您订购的价格超过基准价格:price_B_dic,还有价格字典.

Like, I want to Maximize the profit of a factory. For the cost of the material, the first 1000 units cost $5 each, any more unit cost $3. For example, if the factory order 1100 units, total cost will be 1000*5+100*3. I have a list of material: material_list, a dictionary of benchmark for the materials: benchmark_dic={material_a: 1000, material_b:2000 ....}, a dictionary of the price if order loss than benchmark :price_A_dic, and also a dictionary of the price if you order more than benchark:price_B_dic.

这是我的代码:

x=pulp.LpVariable.dicts('x',material_list,lowBound=0 , cat='Integer')  

New_cost_dic=pd.Series(0,index=dat.index).to_dict()

for seg in material_list:

  if x[seg]>benchmark_dic[seg]:

    New_cost_dic[seg]=(x[seg]-benchmark_dic[seg])*price_b_dic[seg]+benchmark[seg]*price_A_dic[seg]

  else:

    New_cost_DIC[seg]=x[seg]*price_A_dic[seg]

我也有类似的销售计算.我可以从中得到结果,但我不知道我是否做得对.当我得到每种材料有多少单位的最终结果时,我尝试使用相同的计算来获得总成本和总销售额,但我获得的利润(总销售额 - 总成本)不等于我获得的最大利润来自纸浆.值(概率.目标).

I also have a similar calculation for sales. I can get a outcome from this but I don't know if I did it right. When I get a final result of how many units for each material I tried to get the total cost and total sales using the same calculation, but the profit I got by (total sales - total cost) is not equal to the Max profit I got from pulp.value(prob.objective).

我应该如何为这个条件约束或条件函数编码.

How should I code for this conditional constrains or conditional function.


解决方案

我不认为你实现的条件约束会起作用.

I don't think conditional constraints they way you have implemented them will work.

对于像这样的条件约束,您需要重新表述问题以利用指标变量,这些变量是跟踪您感兴趣的条件(真或假)的二元变量.

Instead for conditional constraints like this you will need to reformulate the problem to make use of indicator variables, which are binary variables which track the condition (true or false) that you are interested in.

对于您的具体问题,我建议如下所示,设置一组变量,例如 x1[seg] 用于跟踪购买到基准的编号的每种材料,然后是另一个一组变量,比如 x2[seg],它跟踪在基准之上购买的数量,最后是一组二进制变量,比如 z[seg],它跟踪我们是否已经达到价格突破点.

For your specific problem I would suggest something like the following, have a set of variables, say x1[seg] for each material that tracks the No. bought up to the benchmark, and then another set of variables, say x2[seg] that tracks the No. bought above the benchmark, and finally a set of binary variables, say z[seg] which tracks whether we have reached the price break-point.

成本条款将分别为:

x1[seg]*price_A_dic[seg] + x2[seg]*price_B_dic[seg]

然后我们需要添加约束来强制变量采用适当的值.我认为以下应该有效:

We then need to add constraints which enforce the variables to take on appropriate values. I think the following should work:

x1[seg] >= 0
x1[seg] >= benchmark_dic[seg] * z[seg]
x2[seg] >= 0
x2[seg] <= z[seg]*MAX_POSSIBLE_ORDER

其中 MAX_POSSIBLE_ORDER 是我们在购买数量方面永远不会超过的某个上限.您可以看到,为了使 z[seg] 取值 1,我们首先必须订购 benchmark_dic[seg] 数量更高的价格.同样,如果 z[seg] 取值 1,我们只能以较低的价格订购任何产品.

Where MAX_POSSIBLE_ORDER is some upper bound that we would never exceed in terms of purchase quantity. You can see that in order for z[seg] to take on value 1 we first have to order the benchmark_dic[seg] quantity at the higher price. Similarly we can only order any at the lower price if z[seg] taknes on value 1.

可能有一种更简洁/更有效的方法来做到这一点,但上述方法应该可行.

There may be a neater/more efficient way to do this, but the above should work.

相关文章