在Prolog中

时间:2018-04-16 16:37:49

标签: arrays graph prolog

我需要使用需要进行排序的数组来实现队列。每个项目都是图形的节点,我正在使用A *算法进行探索,即:

nodo(S, ListaAzioniPerS, C, S)

其中S是节点的标识符,ListaAzioniPerS是到达该节点的路径,C是此处的费用,S是其启发式。我需要按C+S我称之为F

的总和来订购它们

为此,我试图通过此代码进行有序插入:

orderedInsert(X, [], [X]).
orderedInsert(nodo(S, ListaAzioniPerS, C, S),
              [nodo(S1, ListaAzioniPerS1, C1, S1)|Rest],
              [nodo(S, ListaAzioniPerS, C, S), nodo(S1, ListaAzioniPerS1, C1, S1)|Rest]) :-
  F is C + S,
  F1 is C1 + S1,
  F < F1,
  !.
%orderedInsert(nodo(S, ListaAzioniPerS, C, S),
%              [nodo(S1, ListaAzioniPerS1, C1, S1)|Rest],
%       [nodo(S, ListaAzioniPerS, C, S), nodo(S1, ListaAzioniPerS1, C1, S1)|Rest]) :-
%  F is C + S,
%  F1 is C1 + S1,
%  F == F1,
%  C < C1,
%  !.
orderedInsert(X, [Y|Rest0], [Y|Rest]) :-
  orderedInsert(X, Rest0, Rest).

(有一个注释部分会考虑F==F1的情况,因此它会按C排序,但因为我已经搞砸了,所以我只是评论了它)

现在,出于某种原因,即使我使用第二个参数非空列表调用orderedInsert/3,它也只与第一个仿函数匹配! 但这不是全部,结果总是在列表的末尾添加... 这是此行orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [nodo(nodo2, listaAzioniPerS1, 2, 1)], X).

中的一个简单示例
[trace] 7 ?- orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [nodo(nodo2, listaAzioniPerS1, 2, 1)], X).
 * Call: (8) orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [nodo(nodo2, listaAzioniPerS1, 2, 1)], _2026) ? creep
   Call: (9) length([nodo(nodo2, listaAzioniPerS1, 2, 1)], 0) ? creep
   Fail: (9) length([nodo(nodo2, listaAzioniPerS1, 2, 1)], 0) ? creep
 * Redo: (8) orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [nodo(nodo2, listaAzioniPerS1, 2, 1)], _2026) ? creep
 * Call: (9) orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [], _2278) ? creep
   Call: (10) length([], 0) ? creep
   Exit: (10) length([], 0) ? creep
 * Exit: (9) orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [], [nodo(nodo1, listaAzioniPerS, 1, 1)]) ? creep
 * Exit: (8) orderedInsert(nodo(nodo1, listaAzioniPerS, 1, 1), [nodo(nodo2, listaAzioniPerS1, 2, 1)], [nodo(nodo2, listaAzioniPerS1, 2, 1), nodo(nodo1, listaAzioniPerS, 1, 1)]) ? creep
X = [nodo(nodo2, listaAzioniPerS1, 2, 1), nodo(nodo1, listaAzioniPerS, 1, 1)] .

追踪虽然执行并没有帮助我(实际上它让我想知道我是否完全理解了序言)。 知道我哪里错了吗?

使用SWI Prolog。

1 个答案:

答案 0 :(得分:1)

您的问题是变量S和S1的重复使用。 您可以将它们 - 例如 - 更改为

orderedInsert(nodo(N, ListaAzioniPerS, C, S),
              [nodo(N1, ListaAzioniPerS1, C1, S1)|Rest],
              [nodo(N, ListaAzioniPerS, C, S), nodo(N1, ListaAzioniPerS1, C1, S1)|Rest]) :-
  F is C + S,
  F1 is C1 + S1,
  F < F1,
  !.

您的代码将有效。顺便说一句,你可以减少一点杂乱:

orderedInsert(nodo(N, ListaAzioniPerS, C, S),
              [nodo(N1, ListaAzioniPerS1, C1, S1)|Rest],
              [nodo(N, ListaAzioniPerS, C, S), nodo(N1, ListaAzioniPerS1, C1, S1)|Rest]) :-
  C + S < C1 + S1,
  !.