将惩罚参数添加到线性程序纸浆
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 将其构建到纸浆模型中
我正在用纸浆写 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 将其构建到纸浆模型中