我正在尝试生成一个包含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).
答案 0 :(得分:4)
无需编写递归代码!
只需使用random/3
,length/2
和maplist/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].
注意杂质!我们得到了不同的答案 - 至少在大多数情况下......
要获得可重现的结果,请记下实际的prng方法及其初始状态random-seed。
答案 1 :(得分:2)
我们将单独讨论每个问题:
geraL(0, _)
说如果你想要零随机数,那么结果就是任何东西。我确定这不是你的意思。如果元素数量为0,结果应该是什么?
在一般情况下,您应该有一个约束C > 0
,以避免在不需要时执行此规则
C is C - 1
将始终失败,因为C
的任何值,C
和C-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/1
或random_between/3
最值得注意的是,random/3
排除了上限,因此random(1, 10, U)
永远不会产生U = 10
。