在列表中查找max元素及其索引 - Prolog

时间:2015-10-03 02:08:30

标签: list prolog

我在Prolog很新鲜。我正在尝试编写一个谓词,找到Max值及其整数列表的索引。即MAX=4将产生INDEX=2var markerdata = { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-84.537291, 33.767675, 0] }, "properties": { "geometry": "Point", "name": "Test Marker 1", "url": "http://www.someurl.com/file_1.html" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-84.556685, 33.748580, 0] }, "properties": { "geometry": "Point", "name": "Test Marker 2", "url": "http://www.someotherurl.com/file_2.html" } }] };

谢谢你的回复〜我道歉!这是我第一次在stackoverflow中提问。我可以编写一个谓词来查找列表的最大值或最小值,但我不知道如何获得列表中值的确切位置。我只是想了解答案。

4 个答案:

答案 0 :(得分:4)

使用 ...

:- use_module(library(clpfd)).
我们定义

..., maplist/2nth0/3

zs_maximum_at(Zs,Max,Pos) :-
   maplist(#>=(Max),Zs),
   nth0(Pos,Zs,Max).

这是OP给出的查询:

?- zs_maximum_at([2,3,4],M,I).
I = 2, M = 4.

OK! ... 最常见的查询怎么样?

?- zs_maximum_at(Zs,M,I).
  Zs = [M], I = 0, M in inf..sup
; Zs = [ M,_B], I = 0, M #>= _B
; Zs = [_A, M], I = 1, M #>= _A
; Zs = [ M,_B,_C], I = 0, M #>= _B, M #>= _C
; Zs = [_A, M,_C], I = 1, M #>= _A, M #>= _C
; Zs = [_A,_B, M], I = 2, M #>= _A, M #>= _B
; Zs = [ M,_B,_C,_D], I = 0, M #>= _B, M #>= _C, M #>= _D
; Zs = [_A, M,_C,_D], I = 1, M #>= _A, M #>= _C, M #>= _D
...

编辑:算术表达式怎么样?

  1. 我们可以通过添加额外目标(#=)/2允许使用算术表达式:

    zs_maximum_at(Zs,Expr,Pos) :-
       maplist(#>=(Max),Zs),
       nth0(Pos,Zs,Expr),
       Expr #= Max.
    

    现在我们可以运行类似下面的查询 - 但却失去了单调性(参见this clpfd manual)!

    ?- zs_maximum_at([0+1,1+1,2-0,3-1,1+0],M,I).
      I = 1, M = 1+1
    ; I = 2, M = 2-0
    ; I = 3, M = 3-1
    ; false.
    
  2. 禁用算术表达式,我们可以将length/2ins/2结合使用:

    zs_maximum_at(Zs,Max,Pos) :-
       length(Zs,_),
       Zs ins inf..sup,
       maplist(#>=(Max),Zs),
       nth0(Pos,Zs,Max).
    

    再次运行上面的查询,我们现在得到:

    ?- zs_maximum_at([0+1,1+1,2-0,3-1,1+0],M,I).
    ERROR: Type error: `integer' expected, found `0+1' (a compound)
    
  3. 请注意,(允许使用算术表达式)的问题不仅限于
    当使用普通的Prolog算术谓词(如is/2和朋友)时,它也会出现。

答案 1 :(得分:2)

我自己不是Prolog专家所以这可能不是最美丽的解决方案,但这个谓词应该做你想要的:

max_list([X|Xs],Max,Index):-
    max_list(Xs,X,0,0,Max,Index).

max_list([],OldMax,OldIndex,_, OldMax, OldIndex).
max_list([X|Xs],OldMax,_,CurrentIndex, Max, Index):-
    X > OldMax,
    NewCurrentIndex is CurrentIndex + 1,
    NewIndex is NewCurrentIndex,
    max_list(Xs, X, NewIndex, NewCurrentIndex, Max, Index).
max_list([X|Xs],OldMax,OldIndex,CurrentIndex, Max, Index):-
    X =< OldMax,
    NewCurrentIndex is CurrentIndex + 1,
    max_list(Xs, OldMax, OldIndex, NewCurrentIndex, Max, Index).

答案 2 :(得分:2)

joel76的一个变种回答:

max_list(L, M, I) :- nth0(I, L, M), \+ (member(E, L), E > M).

答案 3 :(得分:1)

另一种方法,效率不高但更多&#34; prologish&#34;是说: 列表的最大值是多少?它是列表的成员,此列表中没有其他成员大于最大值! 所以:

max_list(Lst, Max, Ind) :-
   member(Max, Lst),
   \+((member(N, Lst), N > Max)),
   % Now, with SWI-Prolog, (may be with other Prolog)
   % nth0/3 gives you the index of an element in a list
   nth0(Ind, Lst, Max).