在Prolog中解决集合分区

时间:2015-09-09 12:15:50

标签: prolog

我正在尝试解决prolog中的set partition问题。假设,设置S = {1,3,4,2,5}。现在要对它进行分区

partition/3

我想实现一个谓词?- partition(S,L,R),使得partition([1,2,3],L,R)成功,如果L和R是S的有效分区。例如,L = [1,2], R = [3]应该成功回答子结构{{1}}。我不想考虑此问题的重复条目。

2 个答案:

答案 0 :(得分:3)

如果您的问题不需要{em> sum(L)= sum(R),如Partition Problem所述,那么

partition(S, [ItemL|L], [ItemR|R]):-
  partition1(S, [ItemL|L], [ItemR|R]).

partition1([], [], []).
partition1([Item|S], [Item|L], R):-
  partition1(S, L, R).
partition1([Item|S], L, [Item|R]):-
  partition1(S, L, R).

如果约束 sum(L)= sum(R)成立,则对partition / 3的更改将起作用(尽管效率很低):

partition(S, [ItemL|L], [ItemR|R]):-
  partition1(S, [ItemL|L], [ItemR|R]),
  sumlist([ItemL|L], Sum),
  sumlist([ItemR|R], Sum).

答案 1 :(得分:0)

这是append/3谓词的一种情况,我们只需要移动参数。

?- append(R, L, [1,2,3]).
L = [1, 2, 3],
R = [];
L = [2, 3],
R = [1];
L = [3],
R = [1, 2];
L = [],
R = [1, 2, 3];
false

这将找到列表中所有可能的有序分区,现在您需要验证其成员的总和。

现在你的谓词partition/3应该是这样的:

sumList([], 0).
sumList([Head|Tail], S):- number(Head), sumList(Tail, S1), S is S1 + Head.

partition(L1, L, R):- append(L, R, L1), sumList(L, S), sumList(R, S).

测试:

?- partition([1,2,3], L, R).
L = [1, 2],
R = [3]

这个答案的问题是只找到有序分区