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

Add penalty parameter to linear program pulp

我正在用纸浆写 LP 问题 python。我对 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',如果容器到达 late/early,它会给容器一个 'penalty value'。我的 objective 功能是尽量减少未使用的 space,因此将惩罚总和乘以一个大数应该 'push' 程序会尝试在正确的时间 window 获取所有内容。

现在是我的问题;我知道这有效,只是不知道如何编程。

到目前为止我做了什么;

我的objective函数如下

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]

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

因为 x 是一个 LpVariable

x[(i,v)]

在问题解决之前总是0,所以tardy总是1。

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

亲切的问候

您不能“有条件地”制定您的模型...意思是 Tardy 是您模型中的一个变量,您不能在一个线性程序,因为在制定问题并将其移交给求解器时,因变量的值(在本例中为 x)是未知的,因此我们需要尝试其他方法并重新制定。

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

Tardy[i] >= (arrival_time[v] - due_time[i]) * x[i,v]

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