В ответ мы используем clpfd и немного lambda:
:- use_module([library(clpfd),
library(lambda)]).
На основе meta-predicatemaplist/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
с опцией max/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.
Является ли 'L' всегда восходящим? – false
Решение должно быть под-списком исходного списка?(вы использовали как «набор элементов из», так и «подписок» в своем вопросе) –
ну, это не важно, скажем, что я должен поместить результат в другой список и сохранить исходный код ps: список всегда восходящий да –