Prolog计算排列

时间:2012-10-10 17:04:46

标签: prolog

我正在写一个排列函数[a,b] - > [[[a],[b]],[[a,b]]

到目前为止,我有这个,但它不起作用。

perm([],[]).
perm(L,[H|T]) :- append(V,[H|U],L), append(V,U,W), perm(W,T).

3 个答案:

答案 0 :(得分:5)

根据您的示例,您可能实际上想要给定列表的powerset,而不是排列

例如,[a,b]的powerset是集{[a,b][a][b][]}。

要计算Prolog中项目列表的powerset,请查看@gusbro的this answer。如果这对您有所帮助,请同意请回答。

如果您想同时获得列表L的所有解决方案,您可以在powerset/2这样的findall/3调用中将呼叫包裹到?- findall(S, powerset(L, S), Ss).

partition(L, PL) :-
    partition(L, [], PL).

partition([], [], []).
partition([X|Xs], As, R) :-
    % add X into the new partition... 
    append(As, [X], NewAs),  
    partition(Xs, NewAs, R).
partition(L, [A|As], [[A|As]|R]) :-
    % ...or, collect the current non-empty partition
    partition(L, [], R).

另一方面,如果您在分区之后(正如您之前编辑中提到的那样),请考虑以下事项:

partition/2

谓词?- partition([a,b,c],L). L = [[a, b, c]] ; L = [[a, b], [c]] ; L = [[a], [b, c]] ; L = [[a], [b], [c]] ; false. 获取一个列表并返回所有分区,如您所述。例如:

{{1}}

答案 1 :(得分:3)

真的?它似乎适用于SWI-Prolog:

?- [user].
|: perm([],[]).
|: perm(L,[H|T]) :- append(V,[H|U],L), append(V,U,W), perm(W,T).
|: % user://1 compiled 0.00 sec, 3 clauses
true.

?- perm([a,b,c], X).
X = [a, b, c] ;
X = [a, c, b] ;
X = [b, a, c] ;
X = [b, c, a] ;
X = [c, a, b] ;
X = [c, b, a] ;
false.

?- perm([a,b,c,d], X).
X = [a, b, c, d] ;
/* trimming 22 solutions */
X = [d, c, b, a] ;
false.

这也会产生你期望的答案数量:3! = 6,4! = 24.什么不适合你?

答案 2 :(得分:2)

快速说明:Prolog不提供功能,但关系

在这种情况下,当参数是另一个的排列时,perm / 2将保持为真。

我觉得这个定义比你的定义更具可读性。

perm([], []).
perm([E|Es], P) :-
    perm(Es, Q),
    select(E, P, Q).

它几乎与permutation / 2 SWI-Prolog相同,但隐藏了一个错误......