Rob*_*t K 4 random matlab shuffle probability
我在文章" 永无止境的洗牌序列 " 的评论中看到了这段代码.我理解基本前提,但我不知道它是如何工作的.我需要的最大解释是while循环的前两行.
(因为它是用MATLAB编写的,我只能猜测这段代码的功能.)
probabilities = [1 1 1 1 1 1];
unrandomness = 1;
while true
cumprob = cumsum(probabilities) ./ sum(probabilities);
roll = find(cumprob >= rand, 1)
probabilities = probabilities + unrandomness;
probabilities(roll) = probabilities(roll) - 6*unrandomness;
if min(probabilities) < 0
probabilities = probabilities - min(probabilities);
end
end
Run Code Online (Sandbox Code Playgroud)
gno*_*ice 12
该probabilities
矢量表示为数字1至6将被选择的可能性的相对权重.一开始,他们都有平等的机会被选中.我将逐步介绍while循环的每一行,解释它的作用:
while循环中的第一行从probabilities
向量创建累积概率.该CUMSUM函数用于沿矢量的长度返回一个累计总和,这由矢量(使用发现的总和除以SUM功能).在第一次通过循环时,cumprob
将具有以下值:
0.1667 0.3333 0.5000 0.6667 0.8333 1.0000
Run Code Online (Sandbox Code Playgroud)
请注意,这些创建"bins",从0到1的随机数可以落入.数字落在给定bin中的概率等于该bin的宽度,因此有一个六分之一(0.1667)的机会随机抽取的数字将落在第一个bin(从0到0.1667),或第二个bin(从0.1667到0.3333)等.
while循环中的第二行选取一个随机数(使用RAND函数),并查找其中第一个元素的索引cumprob
大于该值(使用FIND函数).roll
因此,该值是1到6的数字.
while循环中的第三行通过向上移动所有相对权重来添加"unrandomness",将概率移近一点,使所有数字相等.考虑probabilities
具有以下形式的示例:
[x x x 1 x x]
Run Code Online (Sandbox Code Playgroud)
其中x
某个值大于1.此时,选择值4的概率为1/(5*x+1)
.通过向所有元素添加1,该概率变为2/(5*x+7)
.为x = 3
,4发生的概率增加从0.0625到0.0909,而存在的任何其它数量的概率减小从0.1875到0.1818.因此,这种"非随机性"用于归一化概率.
while循环中的第四行基本上与前一行相反,通过显着降低刚刚发生的任何数字的相对权重,使其不太可能在后续循环中发生.这种降低的发生可能性将是短暂的,因为前一行的效果不断地试图使所有数字的发生概率恢复到相等.
注意,从一个元素中减去的量probabilities
等于添加到前一行中所有元素的总量,导致probabilities
向量总和的净变化为零.这使得价值保持probabilities
有限,这样它们就不会继续增长和增长.
while循环结束时的if语句就是为了确保所有数字probabilities
都是正数.如果向量的最小值(使用MIN函数找到)小于零,则从向量的每个元素中减去该值.这将确保cumprob
向量始终具有0到1之间的值.
如果替换while true
语句for i = 1:6
,在每次迭代结束时显示probabilities
向量和roll
值,并运行代码几次,您可以看到代码如何执行它的功能.这里有一组这样的6个卷,它们将每个数字1到6绘制一次:
roll probabilities
5 | 6 6 6 6 0 6
|
4 | 7 7 7 1 1 7
|
2 | 8 2 8 2 2 8
|
1 | 3 3 9 3 3 9
|
3 | 4 4 4 4 4 10
|
6 | 5 5 5 5 5 5
Run Code Online (Sandbox Code Playgroud)
注意最终值probabilities
是如何相等的,这意味着在那一点上,数字1到6都具有被再次选择的相同可能性.