节点 ID 列表之间的 Prolog 总和距离

Prolog sum distance between list of nodes ids

node(1,22,44).
node(2,43,53).
node(3,23,12).

distance(Id1,Id2,D) :-
    node(Id1,X1,Y1),
    node(Id2,X2,Y2),
    D is sqrt((X2-X1)^2 + (Y2-Y1)^2).

distancePath([X,Y],D) :-
    distance(X,Y,D).
distancePath([H,X|T],Distance) :-
    distancePath([X|T],Rest),
    distance(H,X,D),
    Aux is Rest + D,
    Distance is Distance + Aux.

我在 distancePath 上遇到了一些问题,因为当我 运行 distancePath([1,2,3],Distance). 它给我“(is)/2 的参数 2 中的实例化错误”有人可以帮助我吗?

Distance is Distance + Aux.没有多大意义。变量是不可变的,这意味着一旦设置变量将在 Prolog 评估的那个分支中保持相同的值。此外 Distance 是无限的,因此错误。

您实际上已经有了 Distance 的值:它是 Aux,因为它是列表 Rest 的距离加上距离 D

distancePath([X,Y], D) :-
    distance(X,Y,D).

distancePath([H,X|T], Aug) :-
    distancePath([X|T],Rest),
    distance(H,X,D),
    Aux is Rest + D.

然后我们得到:

?- distancePath([1,2,3], D).
D = 68.4652982294199 ;
false.

但是上面的代码不是很有效:它没有使用尾递归,而且你多次执行 cons 构造函数的解包。您可以使用辅助谓词来提高效率:

distancePath([X|T], Result) :-
    distancePath(T, X, 0, Result).

distancePath([], _, D, D).
distancePath([J|T], I, Di, Do) :-
    distance(I, J, Dd),
    D2 is Di + Dd,
    distancePath(T, J, D2, Do).