在gprolog中查找列表的唯一排列

时间:2017-03-03 17:34:28

标签: prolog

我正在处理家庭作业的问题。我试图获得0和1的所有唯一排列,其中0和1的数量被传递到binaryLists / 3。我有一套规则可以得到排列,但是我得到大量的重复,因为排列/ 2将每个0和1视为唯一。我觉得我需要在某个地方进行切割,但我并不理解切割,我不确定如何考虑这个问题。我的代码如下:

binaryLists(0, 0, R).
binaryLists(Z, O, R) :-
   Z >= 0, O >= 0,
   generateZero(Z, Lz),
   generateOne(O, Lo),
   append(Lz, Lo, Tmp),
   permutation(Tmp, R).

generateZero(0, R) :-
   R = [].
generateZero(Z, R) :-
    Z > 0,
    Y is Z - 1,
    generateZero(Y, Tmp),
    append(Tmp, [0], R).

generateOne(0, R) :-
   R = [].
generateOne(Z, R) :-
   Z > 0,
   Y is Z - 1,
   generateOne(Y, Tmp),
   append(Tmp, [1], R).

这样的结果将给出相同列表的许多重复(例如[1,0,0,0])。

1 个答案:

答案 0 :(得分:1)

切割对你没有帮助。这是一个普遍的Prolog初学者错误,使规则过于复杂和程序化,然后试图通过削减解决问题。

以下是一些提示。您不需要append/3permutation/2,也不需要0/1列表生成器。

你的第一条规则是在正确的轨道上,但有一个缺陷。你有单身R。你试图说一个包含0个零和0个的列表应该是一个空列表。所以只说:

binaryList(0, 0, []).

现在,您可以定义另外两个规则,这些规则给出了结果列表应该以1开头的时间以及何时应该以0开头的条件。这是您需要的唯一两个附加规则:

binaryList(Zeroes, Ones, [0|R]) :-
    Zeroes > 0,
    ...  % What goes here?
    binaryList(..., Ones, R).  % What goes in place of ...?

binaryList(Zeroes, Ones, [1|R]) :-
    Ones > 0,
    ...  % What goes here?
    binaryList(Zeroes, ..., R).  % What goes in place of ...?

一旦您在Prolog中创建了定义有效列表的正确规则,Prolog就会在探索满足规则的所有可能解决方案方面为您完成工作。这就是你获得所有排列的方式。排列是唯一的,因为规则在其解决方案中不重叠,并确保每个解决方案都不同。