我试图解决一个问题,使用clp在prolog。问题如下:
一艘船装载了许多集装箱,我们想把它们卸下来。集装箱被描述为谓词container(I,N,D),其中I是集装箱标识符,N是需要卸货的人数,D是持续时间。例如:容器(1,1)。
容器(b、2、2)。
容器(c 2 2)。
容器(d、3、3)。
容器也可以放在另一个容器的上面,比如:
(a, c)。
在(b, c)。
在(c, d)。
容器a位于容器c之上,依此类推…
问题是如何把卸货的费用降到最低。成本定义为雇用的人数乘以所需的时间。在整个卸货期间,所有人员都是受雇的。
我从问题开始有问题,因为我不熟悉prolog的clp部分。有没有人对如何解决这个问题有任何建议,或者你可以在哪里找到clp prolog如何工作的例子?
如果您为每个作业的开始和结束声明时间变量,那么累积/2可以建模整个过程,而序列化/2可以建模on/2约束:
...
Tasks =
[task(SA,1,EA,1,_)
,task(SB,2,EB,2,_)
,task(SC,2,EC,2,_)
,task(SD,3,ED,3,_)],
cumulative(Tasks, [limit(MAX)]),
serialized([SA,SC,SD],[1,2,3]),
serialized([SB,SC,SD],[2,2,3]),
...
这已经产生了一个合理的解决方案,很容易表达总时间的最小化。
...
labeling([min(max(EA,max(EB,max(EC,ED))))], [SA,SB,SC,SD]).
[SA,SB,SC,SD] = [0,0,2,4]
但是您必须计算计划的成本,将所需工人的数量与总持续时间相乘。实际上,这是一个复杂的计算,因为它依赖于任务的重叠。我们不能简单地在重叠的任务上添加工作者,因为不同持续时间的任务可能使用相同的工作者集。
我认为有一个适用的"技巧":极限迭代深化(MAX),从所需的绝对最小值开始(在这种情况下,容器d为3)。
编辑
对不起,我写错了serialized/2。应该用显式比较代替,如
EA #=< SC,
...
好的,我添加了
EA #=< SC,
EB #=< SC,
EC #=< SD,
解决方案似乎是正确的,所以这很好。但我觉得这应该更普遍。有没有办法生成:
EA #=< SC,
EB #=< SC,
EC #=< SD,
通过调用generate_constraints(),它使用:
on(A,C).
on(B,C).
on(C,D).
和构造约束