prolog - 生成具有随机值的列表

时间:2016-03-31 18:00:38

标签: list random prolog

我正在尝试生成一个包含1到10之间随机值的列表,但是当我运行代码时,我收到“false”...

geraL(0,_).
geraL(C,Y):-
  C is C-1,
  random(1,10,U),
  Y = [U|Y],
  geraL(C,Y).


?-geraL(13,X).

3 个答案:

答案 0 :(得分:4)

无需编写递归代码!

只需使用random/3length/2maplist/2即可:

?- length(Zs, 13), maplist(random(0,10), Zs).
Zs = [8, 9, 3, 5, 0, 7, 6, 7, 9, 9, 2, 4, 7].

?- length(Zs, 13), maplist(random(0,10), Zs).
Zs = [1, 7, 7, 6, 2, 5, 2, 9, 9, 2, 0, 7, 1].

?- length(Zs, 13), maplist(random(0,10), Zs).
Zs = [4, 6, 7, 0, 1, 3, 4, 9, 0, 8, 3, 8, 5].

?- length(Zs, 13), maplist(random(0,10), Zs).
Zs = [3, 1, 2, 1, 5, 3, 9, 8, 3, 7, 8, 1, 7].

注意杂质!我们得到了不同的答案 - 至少在大多数情况下......

要获得可重现的结果,请记下实际的方法及其初始状态

答案 1 :(得分:2)

我们将单独讨论每个问题:

  • geraL(0, _)说如果你想要零随机数,那么结果就是任何东西。我确定这不是你的意思。如果元素数量为0,结果应该是什么?

  • 在一般情况下,您应该有一个约束C > 0,以避免在不需要时执行此规则

  • C is C - 1将始终失败,因为C的任何值,CC-1永远不会是相同的值。一旦变量在谓词子句中具有值,就不能重新实例化,除非通过回溯。

  • 虽然允许Y = [U|Y],但它是一个循环列表定义(根据自身定义的列表,附加一个头元素),我确信这不是你想要的。

如果您修复了这些项目,您的程序将会正常运行。前两个是通过使用辅助(不同)变量来修复的。最后一个是正确定义基本案例以将空列表与0关联,而不是匿名变量。

geraL(0, []).   % Fix for item 1: zero values should be an empty list
geraL(C, Y):-
  C > 0,        % Fix for item 2
  C1 is C-1,    % Fix for item 3: use C1 for the new value
  random(1, 10, U),
  Y = [U|T],    % Fix for item 4: use T for the new value (tail)
  geraL(C1, T).

答案 2 :(得分:1)

有一个内置谓词findnsols/4,最多找到N个解决方案。

此谓词可用于等效循环。由于random/3是确定性的,我们需要在目标中添加repeat/0以使其重复。

geraL(C, Y) :- findnsols(C, U, (repeat, random(1, 10, U)), Y).

另请注意,random/3已在SWI Prolog中弃用;建议改为使用random/1random_between/3 最值得注意的是,random/3排除了上限,因此random(1, 10, U)永远不会产生U = 10