gprolog最长的子集

时间:2011-11-21 20:42:08

标签: prolog

我有整数列表,我需要从列表中找到升序整数的最长子集。 例如:[1,2,5,3,6,7,4] - 最长的子集应为SS = [1,2,3,6,7]

任何人都可以向我展示至少实现它的主要指南。

3 个答案:

答案 0 :(得分:2)

longestSubseq( List, Ans ) :-
    longestSubseq( List, [], [], Ans ).

longestSubseq( [], Buffer, [], Buffer ) :- !.

longestSubseq( [], _, AnsRevert, Ans ) :-
    reverse( AnsRevert, Ans ).

longestSubseq( [H | Tail], [], Longest, Ans ) :-
    longestSubseq( Tail, [H], Longest, Ans ).

longestSubseq( [H | Tail], [BufHead | BufTail], Longest, Ans ) :-
    BufHead =< H,
    longestSubseq( Tail, [H, BufHead | BufTail], Longest, Ans ).

longestSubseq( [H | Tail], Buffer, Longest, Ans ) :-
    [BufHead | _ ] = Buffer,
    BufHead > H,
    length( Longest, LongestLength ),
    length( Buffer, BufferLength ),
    ( 
        ( BufferLength > LongestLength, NewLongest = Buffer )
    ;
        ( BufferLength =< LongestLength, NewLongest = Longest ) 
    ),
    longestSubseq( Tail, [H], NewLongest, Ans ).

我对gprolog不太熟悉,所以这是一个swi-prolog代码。

我们得到的是2个谓词:longestSubseq/2longestSubseq/4

longestSubseq/4有一个缓冲区(当前单调子序列),最长(当前时间最长的子序列)和累加器Ans。

我们需要在累加器中处理一些行为:

  1. 缓冲区为空。我们在其中添加了新元素。
  2. 新元素小于最后一个缓冲区元素。我们把那个元素放在缓冲区里。
  3. 新元素大于最后一个缓冲区元素。我们清除缓冲区并将该元素放入其中。如果缓冲区大于最长的子序列,我们将其替换。
  4. 所以,这似乎是可行的。

    ?- longestSubseq( [2], X ).
    X = [2] ;
    false.
    
    ?- longestSubseq( [2,1,2,3,2], X ).
    X = [1, 2, 3] ;
    false.
    

答案 1 :(得分:0)

递送传递最后看到的元素,以检查排序。传递的元素&gt; =当前头部时失败。

答案 2 :(得分:0)

最好的搜索方法:

% not very tested!

longest(L, S) :-
        length(L, Len),
        advance(L, Len, [], [], S).

cmp_start([], _).
cmp_start([H|_], E) :- H =< E. 

add_to_bag([], P, [P]).
add_to_bag([H|T], P, Bag) :-
        P = LenP-_,
        H = LenH-_,
        (   LenH > LenP
        ->  Bag = [H|Bag1],
            add_to_bag(T, P, Bag1)
        ;   Bag = [P, H| T] ).

advance([Len-Start/Tail|Bag], Solution) :-
        advance(Tail, Len, Start, Bag, Solution).

advance([], _, Start, _, Solution) :-
        reverse(Start, Solution).

advance([H|Tail], Len, Start, Bag, Solution) :-
        Len1 is Len - 1,
        add_to_bag(Bag, Len1-Start/Tail, Bag1),
        (   cmp_start(Start, H)
        ->  advance(Tail, Len, [H|Start], Bag1, Solution)
        ;   advance(Bag1, Solution) ).

部分解决方案表示为MaximunLength-StartList/ListOfItemsToBeConsidered