:- use_module(library(clpfd)). % load constraint library
% [constraint] Compute a list of distinct odd numbers (if one exists), such that their sum is equal to a given number.
odd(Num) :- Num mod 2 #= 1.
sumOfList([],N,N) :- !.
sumOfList([H|T],Counter,N) :-
NewN #= H + Counter,
sumOfList(T,NewN,N).
buildOddList(N,InputList,L) :-
%return list when sum of list is N
V in 1..N,
odd(V),
append(InputList,[V],TempL),
sumOfList(TempL,0,N)->
L = TempL;
buildOddList(N,TempL,L).
computeOddList(N) :-
buildOddList(N,[],L),
label(L).
这是我的代码,我似乎无法获得正确的输出,任何代码批评者? :)
答案 0 :(得分:3)
在这里,我通过谓词nonNegInt_oddPosSummands/2
和辅助谓词list_n_sum/3
来实现这个问题:
:- use_module(library(clpfd)).
list_n_sum([],_,0).
list_n_sum([Z|Zs],N,Sum) :-
Z #>= 1,
Z #=< N,
Z mod 2 #= 1,
Sum #= Z + Sum0,
Sum0 #>= 0,
list_n_sum(Zs,N,Sum0).
nonNegInt_oddPosSummands(N,List) :-
length(_,N),
list_n_sum(List,N,N),
chain(List,#<),
labeling([],List).
现在进行一些查询!
首先,“哪个列表可以19分解成?”:
?- nonNegInt_oddPosSummands(19,Zs).
Zs = [19] ;
Zs = [1, 3, 15] ;
Zs = [1, 5, 13] ;
Zs = [1, 7, 11] ;
Zs = [3, 5, 11] ;
Zs = [3, 7, 9] ;
false.
接下来,一个不作为解决方案集终止的更通用的查询是无限的。 “如果N
长度为2,哪些正整数Zs
可以分解为Zs
?”
?- Zs=[_,_], nonNegInt_oddPosSummands(N,Zs).
N = 4, Zs = [1,3] ;
N = 6, Zs = [1,5] ;
N = 8, Zs = [1,7] ;
N = 8, Zs = [3,5] ;
N = 10, Zs = [1,9] ...
最后,最常见的查询。与上面的一样,它不会终止,因为解决方案集是无限的。但是,它相当枚举所有分解和相应的正整数。
?- nonNegInt_oddPosSummands(N,Zs).
N = 0, Zs = [] ;
N = 1, Zs = [1] ;
N = 3, Zs = [3] ;
N = 4, Zs = [1,3] ;
N = 5, Zs = [5] ;
N = 6, Zs = [1,5] ;
N = 7, Zs = [7] ;
N = 8, Zs = [1,7] ;
N = 8, Zs = [3,5] ;
N = 9, Zs = [9] ;
N = 9, Zs = [1,3,5] ;
N = 10, Zs = [1,9] ...
答案 1 :(得分:1)
可以建议你这个解决方案:
:- use_module(library(clpfd)).
all_odd([]) :-!.
all_odd([H | T]) :-
H mod 2 #= 1,
all_odd(T).
solve(N,L) :-
N2 is floor(sqrt(N)),
Len in 1..N2,
label([Len]),
length(L, Len),
L ins 1..N,
all_different(L),
all_odd(L),
sum(L,#=,N),
label(L),
% only show sorted sets
sort(L,L).
示例:
?- solve(17,L).
L = [17] ;
L = [1, 3, 13] ;
L = [1, 5, 11] ;
L = [1, 7, 9] ;
L = [3, 5, 9] ;
false.
答案 2 :(得分:1)
我看到其他人已经发布了完整的解决方案。尽管如此,只需稍作修改即可使您的代码完成:
computeOddList
仅测试是否存在此类列表。要知道哪个列表匹配约束,只需返回它。因此:
computeOddList(N, L) :-
...
列表TempL
目前可能包含重复项。只需在all_different(TempL)
之后放置append
即可解决问题。
现在computeOddList
将返回至少一个不同奇数的列表(如果存在)。仍然,例如computeOddList(17, L)
它不会返回所有列表。我自己不知道clpFD,所以除了建议你将你的代码与Xonix' code进行比较之外,我无法真正帮助你。
答案 3 :(得分:0)
:- use_module(library(clpfd)). % load constraint library
% [constraint] Compute a list of distinct odd numbers (if one exists), such that their sum is equal to a given number.
odd(Num) :- Num mod 2 #= 1.
sumOfList([],N,N) :- !.
sumOfList([H|T],Counter,N) :-
NewN #= H + Counter,
sumOfList(T,NewN,N).
oddList([]) :- !.
oddList([H|T]) :-
odd(H),
oddList(T).
computeOddList(N,L) :-
(L = [];L=[_|_]),
length(L,V),
V in 1..N,
L ins 1..N,
all_different(L),
oddList(L),
sumOfList(L,0,N).
我设法解决了它,但是在用完之后它没有正确结束。 HMM。