格式化最小路径

时间:2019-04-24 23:22:06

标签: prolog water-jug-problem

因此,我一直在努力以帮助我更好地理解Prolog。我回答了传统的水壶问题,但增加了一些困难。因此,我的代码运行得很好。剩下要做的唯一事情就是为输出做一些漂亮的格式化。目前,它仅显示在我的水罐填充代码中找到的最小路径。 (请参见下面的示例)

到目前为止,我已经想出了一种方法,但是在Prolog中我毫无头绪

我的最佳路径的最终列表的格式如下:[ [x(a,b),y(c,d),z(e,f)], [], [], ...]

我想采用这种格式(有关详细输出,请参见下文):

a -> b
c -> d
etc
  • 首先,我将打印的初始字母打印为液体(在我们的示例中为1。否则,列表中的第一个元素是初始模式)。然后,我遵循第一个子列表,并与之前的一个列表进行比较,以查看哪个水罐确实转移到另一个水罐并进行打印。然后,继续直到列表为空。

当前,它显示以下内容:

?- problem.
[[jug(3,0),jug(5,0),jug(8,8)],[jug(3,0),jug(5,5),jug(8,3)],
 [jug(3,3),jug(5,2),jug(8,3)],[jug(3,0),jug(5,2),jug(8,6)],
 [jug(3,2),jug(5,0),jug(8,6)],[jug(3,2),jug(5,5),jug(8,1)],
 [jug(3,3),jug(5,4),jug(8,1)],[jug(3,0),jug(5,4),jug(8,4)]]
true .

这是当前水罐配置的正确路径。 (稍后我将添加一种与n个水罐相关的方法)

这就是我想要的显示方式(在我的代码中,您可以看到我想要的每个索引):

?- problem.
1 -> 2
2 -> 3
3 -> 1
2 -> 3
1 -> 2
2 -> 3
3 -> 1
true.

我很想获得这一方面的帮助,因为我尝试的一切都是逻辑混乱。

感谢男生/女生<3

2 个答案:

答案 0 :(得分:0)

假设您具有实际的解决方案路径(我相信您的代码对于某些初始/结束状态将无法产生正确的结果),则可以编写以下过程:

show([_]).
show([S1, S2|Tail]):-
  show1(S1, S2, 3, Gain, Loss),  # 3 here is the number of jugs
  write(Loss), write(' -> '), write(Gain),nl,
  show([S2|Tail]).

show1([], [], _, _, _).
show1([jug(Max1,Cur1)|S1], [jug(Max2,Cur2)|S2], Idx, Gain, Loss):-
  succ(NIdx, Idx),
  (Max1-Cur1=Max2-Cur2 -> true;
   (Cur2 > Cur1 -> Gain=Idx ;
    Loss=Idx
  )),
  show1(S1, S2, NIdx, Gain, Loss).

但是,我建议您在构建解决方案路径时改进原始代码以计算这些值。

样品运行:

show([[jug(3,0),jug(5,0),jug(8,8)],[jug(3,0),jug(5,5),jug(8,3)], 
     [jug(3,3),jug(5,2),jug(8,3)],[jug(3,0),jug(5,2),jug(8,6)], 
     [jug(3,2),jug(5,0),jug(8,6)],[jug(3,2),jug(5,5),jug(8,1)], 
     [jug(3,3),jug(5,4),jug(8,1)],[jug(3,0),jug(5,4),jug(8,4)]]).
1 -> 2
2 -> 3
3 -> 1
2 -> 3
1 -> 2
2 -> 3
3 -> 1
true.

答案 1 :(得分:0)

查看模式以检查两个相邻元素

show(L) :-
    findall(T, (append(_,[A,B|_],L), transition(A,B,T)), Ts),
    maplist(writeln, Ts).

transition(
    [jug(3,A),jug(5,B),jug(8,C)],
    [jug(3,U),jug(5,V),jug(8,Z)],
    S->T
) :-
    P=[A^U,B^V,C^Z],
    nth0(L,P,X^M), X>M,
    nth0(R,P,Y^N), Y<N,
    S is 3-L, T is 3-R.