格式化最小路径
Format minimal path
所以我一直在做一些事情来帮助我更好地理解 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.
我很想得到这方面的帮助,因为我正在尝试的一切都是逻辑混乱。
谢谢 guys/girls <3
如果你有一个实际的解法路径(我相信你的代码在某些initial/end状态下不会产生正确的结果),你可以编写如下程序:
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.
查看模式以检查两个相邻元素
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.
所以我一直在做一些事情来帮助我更好地理解 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.
我很想得到这方面的帮助,因为我正在尝试的一切都是逻辑混乱。
谢谢 guys/girls <3
如果你有一个实际的解法路径(我相信你的代码在某些initial/end状态下不会产生正确的结果),你可以编写如下程序:
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.
查看模式以检查两个相邻元素
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.