我正在处理家庭作业的问题。我试图获得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])。
答案 0 :(得分:1)
切割对你没有帮助。这是一个普遍的Prolog初学者错误,使规则过于复杂和程序化,然后试图通过削减解决问题。
以下是一些提示。您不需要append/3
,permutation/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就会在探索满足规则的所有可能解决方案方面为您完成工作。这就是你获得所有排列的方式。排列是唯一的,因为规则在其解决方案中不重叠,并确保每个解决方案都不同。