list - Prolog,在列表中找到最小值

标签 list prolog minimum traversal

简而言之:如何在列表中找到最小值? (感谢 kaarel 的建议)

很长的故事:

我在 amzi prolog 中创建了一个加权图,并给出了 2 个节点,我能够检索路径列表。但是,我需要在此路径中找到最小值,但无法遍历列表来执行此操作。我可以就如何确定列表中的最小值征求您的意见吗?

我的代码目前看起来像这样:

弧(1,2)。
弧(2,3)。
弧(3,4)。
弧(3,5)。
弧(3,6)。
弧(2,5)。
弧(5,6)。
弧(2,6)。

路径(X,Z,A): -
(弧(X,Y),路径(Y,Z,A1),A是A1+1;弧(X,Z),A是1)。

因此,'键入 findall(Z,path(2,6,Z),L).'在听众中,我可以得到一个列表 [3,2,2,1]。
我需要从这里检索最小值并将其乘以一个数量。有人可以就如何检索最小值提出建议吗?谢谢!

最佳答案

通常使用所谓的“滞后参数”来从第一参数索引中受益:

list_min([L|Ls], Min) :-
    list_min(Ls, L, Min).

list_min([], Min, Min).
list_min([L|Ls], Min0, Min) :-
    Min1 is min(L, Min0),
    list_min(Ls, Min1, Min).

这种模式称为折叠(从左侧开始),而 foldl/4 ,在最近的 SWI 版本中可用,让您将其写为:
list_min([L|Ls], Min) :- foldl(num_num_min, Ls, L, Min).

num_num_min(X, Y, Min) :- Min is min(X, Y).



请注意,这不能用于所有方向,例如:
?- list_min([A,B], 5).
is/2: Arguments are not sufficiently instantiated

如果您正在推理整数,就像您的示例中的情况一样,因此我建议您使用 CLP(FD) 约束来自然地概括谓词。而不是 (is)/2 ,只需使用 (#=)/2并从更具声明性的解决方案中受益:
:- use_module(library(clpfd)).

list_min([L|Ls], Min) :- foldl(num_num_min, Ls, L, Min).

num_num_min(X, Y, Min) :- Min #= min(X, Y).

这可以用作在所有方向都起作用的真实关系,例如:
?- list_min([A,B], 5).

产生:
A in 5..sup,
5#=min(B, A),
B in 5..sup.

关于list - Prolog,在列表中找到最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3965054/

相关文章:

list - Groovy 获取某个索引下列表中的所有元素

list - 从 Prolog 中的列表中删除头部

vba - VBA/Excel 中的最早日期为 00 :00:00

python - 获取长向量中最小值索引的有效方法,python

python - 优化数组中的计数

java - 如何在 Java 中更改列表中项目的顺序并保持线程安全?

java - 从 Java 7 中的 ArrayList 中删除备用元素

php - 如何获取相似项目的列表

prolog - 在 prolog 中使用自行创建的列表

prolog - 在序言中排除 tuples_in 列表