我的游戏是关于从给定列表中选择其总和为N
的最大元素集示例:L=[1,1,2,2,3,2,4,5,6]
,N = 6
,子列表等于[1,1,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)]).
基于meta-predicate maplist/4
以及我们定义的约束(ins)/2
和sum/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.