Prolog - 如何找到它们的和等于N的最大元素集

时间:2015-01-06 16:50:59

标签: prolog clpfd constraint-programming

我的游戏是关于从给定列表中选择其总和为N

的最大元素集

示例:L=[1,1,2,2,3,2,4,5,6]N = 6,子列表等于[1,1,2,2]

我需要使用约束逻辑编程提示。

2 个答案:

答案 0 :(得分:3)

SWI-Prolog中有一个用于约束逻辑编程的库。它被称为clpfd

:-use_module(library(clpfd)).

假设你有一个变量用于子序列的长度。它的域从零(对应于空子序列)到列表的长度。为了获得最长的序列,应该从最高的序列开始尝试值。

...
    length(List, M),
    L in 0..M,
    labeling([max(L)],[L]),
...

接下来,L可用于构建L变量列表,这些变量对应于List中元素的索引。由于这些索引必须按升序排列,chain/2可用于在任意两个连续索引之间创建#</2约束。

...
    length(Indices, L),
    Indices ins 1..M,
    chain(Indices, #<),
...

使用这些索引,可以构建包含List元素的列表。 nth1/3在这里很有用,但有一个小技巧。

...
nth1a(List, N, E):-
    nth1(N, List, E).
...
    maplist(nth1a(List), Indices, SubSequence),
...

该列表的总和必须为N

...
    sum(SubSequence, #=, N)
...

由于只需要最长的序列,once/1可用于在找到第一个解决方案后停止。

一些示例查询:

?- longest_subsequence([1,1,4,4,6], 9, S).
S = [1, 4, 4].

?- longest_subsequence([1,1,4,4,6], 11, S).
S = [1, 4, 6].

?- longest_subsequence([1,1,4,4,6], 21, S).
false.

由于我不确定这是否是家庭作业,我不会在这里发布完整的代码。

答案 1 :(得分:1)

在这个答案中,我们使用和一点

:- use_module([library(clpfd),
               library(lambda)]).

基于 maplist/4以及我们定义的约束(ins)/2sum/3

zs_selection_len_sum(Zs, Bs, L, S) :-
   same_length(Zs, Bs),
   Bs ins 0..1,
   maplist(\Z^B^X^(X #= Z*B), Zs, Bs, Xs),
   sum(Bs, #=, L),
   sum(Xs, #=, S).

使用带有选项labeling/2的{​​{1}}的示例查询:

?- zs_selection_len_sum([1,1,4,4,6],Bs,L,8), labeling([max(L)],Bs).
  Bs = [1,1,0,0,1], L = 3
; Bs = [0,0,1,1,0], L = 2
; false.

?- zs_selection_len_sum([1,1,3,4,5],Bs,L,7), labeling([max(L)],Bs).
  Bs = [1,1,0,0,1], L = 3 
; Bs = [0,0,1,1,0], L = 2
; false.

?- zs_selection_len_sum([1,1,2,2,3,2,4,5,6],Bs,L,6), labeling([max(L)],Bs).
  Bs = [1,1,0,1,0,1,0,0,0], L = 4
; Bs = [1,1,1,0,0,1,0,0,0], L = 4
; Bs = [1,1,1,1,0,0,0,0,0], L = 4
; Bs = [0,0,1,1,0,1,0,0,0], L = 3
; Bs = [0,1,0,0,1,1,0,0,0], L = 3
; Bs = [0,1,0,1,1,0,0,0,0], L = 3
; Bs = [0,1,1,0,1,0,0,0,0], L = 3
; Bs = [1,0,0,0,1,1,0,0,0], L = 3
; Bs = [1,0,0,1,1,0,0,0,0], L = 3
; Bs = [1,0,1,0,1,0,0,0,0], L = 3
; Bs = [1,1,0,0,0,0,1,0,0], L = 3
; Bs = [0,0,0,0,0,1,1,0,0], L = 2
; Bs = [0,0,0,1,0,0,1,0,0], L = 2
; Bs = [0,0,1,0,0,0,1,0,0], L = 2
; Bs = [0,1,0,0,0,0,0,1,0], L = 2
; Bs = [1,0,0,0,0,0,0,1,0], L = 2
; Bs = [0,0,0,0,0,0,0,0,1], L = 1
; false.