Prolog,在列表中找到最小值 [英] Prolog, find minimum in a list

查看:19
本文介绍了Prolog,在列表中找到最小值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

长篇大论:

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

我的代码目前如下所示:

<上一页>弧(1,2).弧(2,3).弧(3,4).弧(3,5).弧(3,6).弧(2,5).弧(5,6).弧(2,6).路径(X,Z,A):-(arc(X,Y),path(Y,Z,A1),A 为 A1+1;arc(X,Z),A 为 1).

因此,'键控 findall(Z,path(2,6,Z),L).'in listener 允许我获得一个列表 [3,2,2,1].我需要从这里检索最小值并将其乘以一个数量.有人可以建议如何检索最小值吗?谢谢!

解决方案

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

list_min([L|Ls], Min) :-list_min(Ls,L,Min).list_min([], 最小值, 最小值).list_min([L|Ls], Min0, Min) :-Min1 是 min(L, Min0),list_min(Ls,Min1,Min).

这种模式称为 fold(从左至右),而在最近的 SWI 版本中提供的 foldl/4 允许您将其写为:

list_min([L|Ls], Min) :- foldl(num_num_min, Ls, L, Min).num_num_min(X, Y, Min) :- 最小值是 min(X, Y).

<小时><小时>

请注意,这不能用于所有方向,例如:

?- list_min([A,B], 5).is/2:参数没有充分实例化

如果您正在推理 整数,就像您的示例中的情况一样,因此我建议您使用 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 在 5..sup.

in short: How to find min value in a list? (thanks for the advise kaarel)

long story:

I have created a weighted graph in amzi prolog and given 2 nodes, I am able to retrieve a list of paths. However, I need to find the minimum value in this path but am unable to traverse the list to do this. May I please seek your advise on how to determine the minimum value in the list?

my code currently looks like this:

arc(1,2).
arc(2,3).
arc(3,4).
arc(3,5).
arc(3,6).
arc(2,5).
arc(5,6).
arc(2,6).

path(X,Z,A) :- 
 (arc(X,Y),path(Y,Z,A1),A is A1+1;arc(X,Z), A is 1).

thus, ' keying findall(Z,path(2,6,Z),L).' in listener allows me to attain a list [3,2,2,1]. I need to retrieve the minimum value from here and multiply it with an amount. Can someone please advise on how to retrieve the minimum value? thanks!

解决方案

It is common to use a so-called "lagged argument" to benefit from first-argument indexing:

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).

This pattern is called a fold (from the left), and foldl/4, which is available in recent SWI versions, lets you write this as:

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

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



Notice though that this cannot be used in all directions, for example:

?- list_min([A,B], 5).
is/2: Arguments are not sufficiently instantiated

If you are reasoning about integers, as seems to be the case in your example, I therefore recommend you use CLP(FD) constraints to naturally generalize the predicate. Instead of (is)/2, simply use (#=)/2 and benefit from a more declarative solution:

:- 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).

This can be used as a true relation which works in all directions, for example:

?- list_min([A,B], 5).

yielding:

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

这篇关于Prolog,在列表中找到最小值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆