我正在研究 TSP 的变体,其中每个节点都有一个时间窗口,但我在计算成本函数时遇到了一些问题。我使用的是后继模型,所以我有一个列表,其中每个变量表示下一个目的地,Xi = j 是从节点 i 到节点 j 的链接。
我的代码如下所示:
:-lib(ic).
:-lib(branch_and_bound).
:-lib(propia).
:-[nodes].
tsp(Next, Cost):-
Cost::1..10000,
Next::1..10000,
%Constraints
alldifferent(Next),
different_from_index(Next),
circuit(Next),
create_objective(Next, Cost),
minimize(labeling(Next), Cost).
其中different_from_index是 Next 变量的索引与其值之间的约束:Next[i] != i,而create_objective是定义目标函数的谓词。首先 create_objective 谓词创建链接成本列表,因此使用简单的 sumlist 谓词很容易获得成本。但我需要为每个节点定义一个时间窗口,我想是这样的:
time_window([], _, _, 0).
time_window([HCost | TCost], Next, Start, Cost):-
element(Start, Next, Destination),
time_window(TCost, Next, Destination, Cost1),
Cost #= Cost1 + HCost,
node(Destination, Min, Max) infers most,
Cost #>= Min, Cost #=< Max.
[H成本| TCost] 是前面提到的成本列表,但已排序和反转(因此我将列表的 n 元素作为第一个链接,将 n-1 作为第二个链接,依此类推)。此外,节点谓词包含在开头加载的 prolog 文件中。不幸的是,这似乎不起作用:它既不返回 false 也不返回错误的解决方案。经过一段时间的计算,我收到此消息:
[eclipse 2]: tsp(Next, Cost).
bb_min: search did not instantiate cost variable
Aborting execution ...
Abort
我理解错误,但我不知道如何解决它。我使用更简单的模型和类似的 time_window 谓词成功地做到了,但在这种情况下似乎不合适。
谁能帮我吗?谢谢指教。