所以我有这些事实:
border(germany, france).
border(france, spain).
border(spain, portugal).
还有一些其他的边界可以让我从葡萄牙到俄罗斯(这里有太多的事实要发布,但实际上有可能从葡萄牙到俄罗斯)。 我做了这个谓词,告诉你当你从P1到P2时你越过的国家数量:
crossedCountries(P1,P2,0):- (border(P1,P2);border(P2,P1)).
crossedCountries(P1,P2,Num):-
(border(P1,Z);border(Z,P1)),
(crossedCountries(Z,P2,Num1);crossedCountries(P2,Z,Num1)),!,
Num is Num1 + 1.
当我必须跨越3个,4个或5个或5个国家时一切顺利,但如果它太远,它只会给我错误
ERROR: Out of local stack
有人可以指点我吗?
答案 0 :(得分:1)
我注意到的第一行是代码片段#2的第四行:
(crossedCountries(Z,P2,Num1);crossedCountries(P2,Z,Num1)),!,
之前已经处理了对称性,我发现它只是至少循环的原因,但很可能是堆栈溢出错误。
border(germany, france).
border(france, spain).
border(spain, portugal).
crossedCountries(P1,P2,0):-
border(P1,P2);
border(P2,P1).
crossedCountries(P1,P2,Num):-
(
border(P1,Z);
border(Z,P1)
),
crossedCountries(Z,P2,Num1),
Num is Num1 + 1.
答案 1 :(得分:1)
这个问题是一个经典的图遍历问题,你想知道从一个特定节点到另一个特定节点的不同唯一路径(或者在这种情况下,只是两者之间的国家数)。
出现循环问题是因为您在确定路线时可能会多次访问同一个国家/地区(“节点”)。因此,如果有从A到B到C到D的路线,您最终可能会做A到B到A到B到C到B到C到B到A ......并且永远不会到达D.
不考虑此问题的解决方案可能如下所示:
border(germany, france).
border(france, spain).
border(spain, portugal).
border(germany, austria).
border(austria, slovakia).
border(slovakia, poland).
border(poland, germany).
bordering(Country1, Country2) :-
border(Country1, Country2).
bordering(Country1, Country2) :-
border(Country2, Country1).
crossedCountries(C1, C2, 0):-
bordering(C1, C2).
crossedCountries(C1, C2, Num):-
bordering(C1, Z),
crossedCountries(Z, C2, Num1),
Num is Num1 + 1.
你得到这样的结果:
| ?- crossedCountries(germany, spain, N).
N = 1 ? ;
N = 3 ? ;
N = 5 ? ;
...
这是因为有效途径是德国 - 法国 - 西班牙,德国 - 法国 - 德国 - 法国 - 西班牙等。
常见的补救措施是跟踪访问过的国家(“节点”)。这可以通过添加参数来跟踪它们来完成。另外,为了使结果更清晰,我添加了一个Path
参数来查看通过国家/地区的实际解决方案路径(如果需要,可以省略此参数):
crossedCountries(P1, P2, [P1|Path], Num) :-
crossedCountries(P1, P2, [P1], Path, Num).
crossedCountries(P1, P2, Visited, [P2], 0) :-
neighbors(P1, P2),
\+ member(P2, Visited).
crossedCountries(P1, P2, Visited, [Z|Path], Num) :-
neighbors(P1, Z),
\+ member(Z, Visited),
crossedCountries(Z, P2, [Z|Visited], Path, Num1),
Num is Num1 + 1.
现在查询结果如下:
| ?- crossedCountries(germany, spain, Path, N).
N = 1
Path = [germany,france,spain] ? ;
no
| ?- crossedCountries(germany, poland, Path, N).
N = 0
Path = [germany,poland] ? a
N = 2
Path = [germany,austria,slovakia,poland]
no
| ?-
等