[英]Fischer Yates shuffle in coffee-script
假设Math.random()
产生0到1之间均匀分布的随机数,这是否是Fischer Yates随机播放的正确实现? 我正在寻找一个非常随机的,均匀的分布,在该分布中可以指定输入数组( arr
)中混洗的元素数量(根据required
)。
shuffle = (arr, required)->
rnd = (int) ->
r = Math.random() * int
Math.round r
len = arr.length-1
for i in [len..1]
random = rnd(i)
temp = arr[random]
arr[random] = arr[i]
arr[i] = temp
break if i < len - (required - 2)
return arr
几件事:
Math.round()
,请尝试Math.floor()
; 在您的实现中, Math.round()
比其他所有元素(.5 / len与1 / len)给第一个元素(索引0)和最后一个元素更少机会。 请注意,在第一次迭代中,您为arr.length
元素输入arr.length - 1
。 required
变量,则最好将其设置为可选,因为它默认为数组的长度: shuffle = (arr, required=arr.length)
arr[arr.length - required ..]
required
不在[0,arr.length]
范围内怎么办? 将它们放在一起(并添加一些样式):
shuffle = (arr, required=arr.length) ->
randInt = (n) -> Math.floor n * Math.random()
required = arr.length if required > arr.length
return arr[randInt(arr.length)] if required <= 1
for i in [arr.length - 1 .. arr.length - required]
index = randInt(i+1)
# Exchange the last unshuffled element with the
# selected element; reduces algorithm to O(n) time
[arr[index], arr[i]] = [arr[i], arr[index]]
# returns only the slice that we shuffled
arr[arr.length - required ..]
# Let's test how evenly distributed it really is
counter = [0,0,0,0,0,0]
permutations = ["1,2,3","1,3,2","2,1,3","2,3,1","3,2,1","3,1,2"]
for i in [1..12000]
x = shuffle([1,2,3])
counter[permutations.indexOf("#{x}")] += 1
alert counter
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.