我正在用纸浆 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+=,但我不知道如何让程序考虑到它。如果有人能帮助我让它工作,或者对如何编程有其他建议,那将不胜感激!
亲切的问候
答案 0 :(得分:0)
你不能“有条件地”制定你的模型......意思是 Tardy
是你的模型中的一个变量,你不能在一个线性的条件语句(if-elif-else)中给它赋值因为当问题被公式化并移交给求解器时,因变量(在本例中为 x
)的值是未知的,所以我们需要尝试其他方法并重新公式化。
您在模型中如何处理时间并不完全清楚,但似乎集装箱有到期日,航程有到达时间,这将是计算{的基础{1}}。因此,您应该将 Tardy
引入为非负实数值,并将其限制为大于到达时间和截止日期之间的差值。假设集装箱“i”继续那个特定的航次“v”。因此,我们需要将该增量乘以选择二进制变量 Tardy[i]
以仅适用于选择的情况。在伪代码中:
x
然后为模型中的每个 i,v 将其构建到您的纸浆模型中