PuLP Python - 如何线性化涉及变量的不等式

问题描述

我正在研究应付铜的问题,其中目标函数是最大化一段时间内应付铜的总和,T。

是否可以制定一个约束来动态比较变量与两个常量之间的关系:

lower_bound,operator_1 (>,>=),variable,operator_2(<,<=) up_bound

问题描述

应付的总吨数,即客户将支付的费用取决于销售材料的铜含量。

  1. 每个客户都有许多以铜规格可操作界限表示的应付条款,如以下示例数据所示:

客户数据

import io
import pandas as pd

customer_payables = """customer,tier,specvalue_1,specoperator_1,specvalue_2,\
specoperator_2,coeff
    'abc',1,'>=',20,'<=',96.0
    'abc',2,'>',24,96.5 
    'abc',3,100,96.65
    'def',96.0
    'def',22,96.66
    'def',100',97.0
    """

_cust_data = io.StringIO(customer_payables)
cust_df = pd.read_csv(_cust_data,sep=",")
cust_df = cust_df.set_index('customer')
cust_df
  1. 我有一个可用材料的数据框(以吨为单位),其中包含两个仓库和两个库存中的特定铜含量。请注意,此材料的质量会随时间变化:

##库存数据

stockpile_data_dict = {
    'Warehouse 1':{
        'Stockpile 1': {'cu': 27},'Stockpile 2': {'cu': 18}
        },'Warehouse 2': {
            'Stockpile 1':{'cu': 22},'Stockpile 2': {'cu': 16}}}
  
stockpile_df = pd.concat({k: pd.DataFrame(v).T for k,v in stockpile_data_dict.items()},axis=0) 
stockpile_df

问题 我创建了一个变量来表示每个仓库和库存的铜浓度。这被保留为一个变量,因为目的是随着时间的推移对库存进行建模,允许模型选择何时销售材料以最大化应付账款:

cu_spec_of_sale_material = pulp.LpVariable.dicts(
    'copper spec of sale material',((warehouse,stockpile)
      for warehouse,stockpile in stockpile_df.index),cat='Continuous')

如何创建一个线性约束,返回与该变量的铜浓度 VALUE 相关的正确应付系数?

在伪代码术语中,它计算如下:

for customer,effective_tier in effective_payable_coefficient:
  if customer_lower_bound_val < cu_spec_sales_material[warehouse,stockpile] < customer_up_bound_val:
    PULP += effective_payable_coefficient[customer,effective_tier] == 1

我不经常使用 Pulp,所以请耐心等待。

感谢所有帮助,谢谢。

解决方法

我认为您正在寻找含义的线性公式:

a < x < b => y = 1

其中 a,b 是常数,x 是连续变量,y 是二元变量。

我们可以这样写:

 x ≤ a + M1 ⋅ δ + M1 ⋅ y
 x ≥ b - M2 ⋅ (1-δ) - M2 ⋅ y
 δ,y ∈ {0,1}
 x ∈ [L,U]
 M1 = U-a
 M2 = b-L

δ 是另一个二元变量,LUx 的下限/上限,M1M2 是常量。

直觉:这些约束实现了含义:

 y = 0 =>  x ≤ a or x ≥ b

这意味着如果 a < x < b 我们必须有 y=1

要得出这些限制条件,最好远离计算机并使用老式的笔和纸。