向线性程序纸浆添加惩罚参数

时间:2021-05-19 10:14:12

标签: python pulp

我正在用纸浆 python 写一个 LP 问题。我对 LP 并不陌生,但我对纸浆很陌生。到目前为止,我得到了一些正确实施的约束。它们很简单,我知道它们是如何工作的。问题是关于将集装箱分配给航次;

# All containers asigned to only 1 voyage
for i in cntrs:
    prob += lpSum([x[(i,v)] for v in voyages]) <= 1
    
# Contaienr to right destination
for v in voyages:
    prob += lpSum([x[(i,v)] * posibleDest.loc[i,v] for i in cntrs]) == 1

# Weight capacity of voyages
for v in voyages:
    for b in barges:
        prob += lpSum([weight[i] * x[(i,v)] for i in cntrs]) <= voyWCap[v]
        
# Type capacity of voyages
for c in cats:
    for v in voyages:
        prob += cntrCat.loc[i,c] * x[(i,v)] <= bargeCATCAP.loc[c,b] * voyBarge.loc[b,v]
        
# TEU cap of voyages
for v in voyages:
    for b in barges:
        prob += lpSum([cntrTEU[i] * x[(i,v)] for i in cntrs]) <= voyTEUCap[v]

我测试了这个程序,它运行得很好,但是我卡在了一个特定的部分。我想添加一个参数“Tardy”,如果容器迟到/早到达,它会给容器一个“惩罚值”。我的目标函数是最小化未使用的空间,因此将惩罚的总和乘以一个大数字应该会“推动”程序尝试在正确的时间窗口内获取所有内容。

现在是我的问题;我知道这行得通,只是不知道如何编程。

到目前为止我做了什么;

我的目标函数如下

prob += lpSum([(TEUcap[b] * voyBarge.loc[b,v]) - (x[(i,v)] * cntrTEU[i]) + Tardy[i] * M]  
              for i in cntrs
              for b in barges
              for v in voyages)

其中 M 是一个非常大的数字

我创建了一个带有 0 的字典 (Tardy) 和一个循环来填充该字典;

Tardy = dict.fromkeys(cntrs,0)

for i in cntrs:
    for v in voyages:
        if cntrDest.dot(voyArive).loc[i,v] != 0:
            if cntrDest.dot(voyArive).loc[i,v] * x[(i,v)] <= (cntrOpen.dot(voyDest)).loc[i,v] * x[(i,v)]:
                Tardy[i] = 1
            elif cntrDest.dot(voyArive).loc[i,v] * x[(i,v)] >= (cntrClose.dot(voyDest)).loc[i,v] * x[(i,v)]:
                Tardy[i] = 1
            else:
                Tardy[i] = 0
          

换句话说:我的大部分参数都是矩阵,如果有一个值(不是 0)

cntrDest.dot(voyArive).loc[i,v]

表示第 v 航次的集装箱 i 有一个到达日期时间,如果该值大于关闭日期时间,或小于打开日期时间,则该集装箱应受到惩罚 (Tardy[container] =1)

因为 x 是一个 LpVariable

x[(i,v)]

在问题解决之前总是0,因此,tardy总是1。

我想我必须在某处“粘贴”一个 prob+=,但我不知道如何让程序考虑到它。如果有人能帮助我让它工作,或者对如何编程有其他建议,那将不胜感激!

亲切的问候

1 个答案:

答案 0 :(得分:0)

你不能“有条件地”制定你的模型......意思是 Tardy 是你的模型中的一个变量,你不能在一个线性的条件语句(if-elif-else)中给它赋值因为当问题被公式化并移交给求解器时,因变量(在本例中为 x)的值是未知的,所以我们需要尝试其他方法并重新公式化。

您在模型中如何处理时间并不完全清楚,但似乎集装箱有到期日,航程有到达时间,这将是计算{的基础{1}}。因此,您应该将 Tardy 引入为非负实数值,并将其限制为大于到达时间和截止日期之间的差值。假设集装箱“i”继续那个特定的航次“v”。因此,我们需要将该增量乘以选择二进制变量 Tardy[i] 以仅适用于选择的情况。在伪代码中:

x

然后为模型中的每个 i,v 将其构建到您的纸浆模型中