【问题标题】:Solving set partition in Prolog在 Prolog 中解决集合分区
【发布时间】:2015-09-10 00:06:46
【问题描述】:

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

L U R = S && L^R = empty

我想实现一个谓词 partition/3 使得 ?- partition(S,L,R) 成功,如果 L 和 R 是 S 的有效分区。例如,partition([1,2,3],L,R) 应该通过答案替换 L = [1,2], R = [3] 成功。我不想考虑这个问题的重复条目。

【问题讨论】:

  • 您的问题陈述中是否缺少此约束?总和(L)=总和(R)
  • 另外,这个问题的重复条目是什么?在您的示例 S=[1,2,3] 中,这些有效的解决方案是: L=[1,2], R=[3] ; L=[3],R=[1,2]; L=[1],R=[2,3],等等?
  • 请解释“我不想为这个问题考虑重复条目”的含义。这是否意味着partition/3需要强制所有涉及的列表都这样做不包含任何重复项?或者这是否意味着partition/3 可以(默认)假设所有列表(它会看到)不包含重复项?

标签: prolog


【解决方案1】:

如果您的问题不需要 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).

【讨论】:

  • 感谢您的展示!我被非空要求绊倒了,但是引入从属谓词确实很容易。
【解决方案2】:

这是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]

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

【讨论】:

  • L=[1,3], R=[2] 呢?
  • 是否应该考虑订购?
  • 他不想在结果集中看到L=[1,2], R=[3] L=[2,1], R=[3],因为这些列表代表相同的集合,因此它们是重复的解决方案。但是L=[1,3], R=[2] 是您的解决方案不会生成的有效不同分区。
  • 我以为 OP 想解决 sum(L) = sum(R) 和 L U R = S 和 L^R = empty 的分区问题
  • 不,但谷歌“分区问题”。否则解决方案是微不足道的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多