【问题标题】:Prolog not finding all solutionsProlog没有找到所有解决方案
【发布时间】:2018-11-11 06:44:34
【问题描述】:

像这样模拟地下管线的停靠点:

stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).

其中stop(L, N, S) 表示SN'第L 线上的站点,我正在尝试定义path(S1, S2, P) 来计算S1S2 之间的可能路径。

这里的路径是“段”的列表,段是沿同一条线的旅程,即segment(L,S1,S2) 表示沿线LS1S2 的连续旅程。所以path(a,d,P) 的一个可能解决方案是P=[segment(line1, a, b), segment(line2, b, d)],即在line1 上从ab,然后在line2 上从bd

另外一个限制是路径不能多次包含同一行。

我有以下内容:

segment(L, S1, S2) :- stop(L, N1, S1), stop(L, N2, S2), N2>N1.
line_present_in_path(_, []) :- false.
line_present_in_path(L, [H|_]) :- segment(L, _, _) = H.
line_present_in_path(L, [_|T]) :- line_present_in_path(L, T).
path(S1, S2, [H]) :- segment(_, S1, S2) = H, H.
path(S1, S2, [H|T]) :- segment(L, S1, X) = H, H, \+line_present_in_path(L, T), path(X, S2, T).

但是发生了一些奇怪的事情。如果我自己明确指定所有参数,它会识别为正确的路径:

?- path(station1, station4, [segment(line1, station1, station2),segment(line2, station2, station4)]).
true ;
false.

但是,如果我要求它计算所有路径,它只会找到一条路径,与它刚刚验证为正确的路径不同:

?- path(station1, station4, P).
P = [segment(line1, station1, station4)] ;
false.

我必须承认我是 Prolog 的新手,所以我可能会遗漏一些基本的东西。但是,我真的不明白为什么它可以验证给定路径是否正确,但在尝试查找所有路径时却找不到该路径。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    错误出现在path/3 谓词的第二个子句中。为了清楚起见重写它:

    path(S1, S2, [segment(L, S1, X)|T]) :-
        \+ line_present_in_path(L, T),
        path(X, S2, T).
    

    对于path(station1, station4, P) 之类的目标,您可以调用line_present_in_path/2 谓词,并在第二个参数中添加一个变量。该调用总是成功,因此它的否定总是失败。一般来说,您应该谨慎使用 \+/1 和充分实例化的参数。

    提示:要解决此错误,请使用路径谓词的附加参数来保存到目前为止找到的站点。例如

    path(S1, S2, Path) :-
        path(S1, S2, Path, []).
    
    path(S1, S2, Path, Visited) :-
        ...
    

    您可以使用事实上的标准member/2 谓词来检查站点是否已经在路径中,否则将其添加到访问列表中。寻路是一个常见问题,您可以在 StackOverflow 中找到几个相关的答案。但请先尝试自己解决。

    【讨论】:

    • 感谢您的回答。我明白为什么我的现在失败了,但很遗憾我已经盯着和思考了几个小时,仍然无法听取你的建议。你能扩大一点吗?我应该完全取消 line_present_in_path 还是您的解决方案可以补充?
    • 按照您的要求扩展了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多