Prolog: devices of k elements with the sum of elements S

I am trying to calculate the arrangement of elements Kin Prolog, where the sum of their elements is equal to the given S. So, I know that mechanisms can be computed by finding combinations and then rearranging. I know how to calculate combinations of elements K, for example:

comb([E|_], 1, [E]).
comb([_|T], K, R) :-
   comb(T, K, R).
comb([H|T], K, [H|R]) :-
   K > 1,
   K1 is K-1,
   comb(T, K1, R).

Permutations of the list with the property that the sum of their elements is equal to the given S, I know, to calculate this:

insert(E, L, [E|L]).
insert(E, [H|T], [H|R]) :-
   insert(E, T, R).

perm([], []).
perm([H|T], P) :-
   perm(T, R),
   insert(H, R, P).

sumList([], 0).
sumList([H], H) :-
   number(H).
sumList([H|Tail], R1) :-
   sumList(Tail, R),
   R1 is R+H.

perms(L, S, R) :-
   perm(L, R),
   sumList(R, S1),
   S = S1.

allPerms(L, LP) :-
   findall(R, perms(L,R), LP).

The problem is that I don’t know how to combine them to get elements Kthat have a sum of elements equal to the given S. Any help would be appreciated.

+4
source share
4

SWI-Prolog. ,

:- use_module(library(lambda)).

arrangement(K, S, L) :-
    % we have a list of K numbers
    length(L, K),
    % these numbers are between 1 (or 0) and S
    maplist(between(1, S), L),
    % the sum of these numbers is S
    foldl(\X^Y^Z^(Z is X+Y), L, 0, S).

 ?- arrangement(5, 10, L).
L = [1, 1, 1, 1, 6] ;
L = [1, 1, 1, 2, 5] ;
L = [1, 1, 1, 3, 4] ;
L = [1, 1, 1, 4, 3] .

CLP (FD).

@repeat.

+3

!

< > : use_module ( (clpfd)).

SWI-Prolog 7.3.16, :

< > ? - (Zs, 4), Zs ins 1..4, sum (Zs, # =, 7), labeling ([], Zs).  Zs = [1,1,1,4] ; Zs = [1,1,2,3] ; Zs = [1,1,3,2] ; Zs = [1,1,4,1] ; Zs = [1,2,1,3] ; Zs = [1,2,2,2] ; Zs = [1,2,3,1] ; Zs = [1,3,1,2] ; Zs = [1,3,2,1] ; Zs = [1,4,1,1] ; Zs = [2,1,1,3] ; Zs = [2,1,2,2] ; Zs = [2,1,3,1] ; Zs = [2,2,1,2] ; Zs = [2,2,2,1] ; Zs = [2,3,1,1] ; Zs = [3,1,1,2] ; Zs = [3,1,2,1] ; Zs = [3,2,1,1] ; Zs = [4,1,1,1].

" ", chain/2:

< > ? - (Zs, 4), Zs ins 1..4, (Zs, # = <), sum (Zs, # =, 7), ([], Zs).  Zs = [1,1,1,4] ; Zs = [1,1,2,3] ; Zs = [1,2,2,2] ; .
+3

@repeat

, SICStus 4.3.2

gen_list(+,+,?)

gen_list(Length,Sum,List) :-    length(List,Length), 
                                domain(List,0,Sum), 
                                sum(List,#=,Sum), 
                                labeling([],List),

                                % to avoid duplicate results
                                ordered(List).

Test

| ?- gen_list(4,7,L).
L = [0,0,0,7] ? ;
L = [0,0,1,6] ? ;
L = [0,0,2,5] ? ;
L = [0,0,3,4] ? ;
L = [0,1,1,5] ? ;
L = [0,1,2,4] ? ;
L = [0,1,3,3] ? ;
L = [0,2,2,3] ? ;
L = [1,1,1,4] ? ;
L = [1,1,2,3] ? ;
L = [1,2,2,2] ? ;
no
+1

, . , . ,

sumList([], 0).
%sumList([H], H) :-
%   number(H).
sumList([H|Tail], R1) :-
   sumList(Tail, R),
   R1 is R+H.

'arrangements of K elements'(Elements, K, Sum, Arrangement) :-
    comb(Elements, K, Arrangement),
    sumList(Arrangement, Sum).

:

'arrangements of K elements'([1,2,3,4,5,6],3,11,A).
A = [2, 4, 5] ;
A = [2, 3, 6] ;
A = [1, 4, 6] ;
false.

, findall/3 , .

0

Source: https://habr.com/ru/post/1628455/


All Articles