这段 MATLAB 代码是如何工作的? (概率和随机序列)
我在文章“永无休止的打乱序列"。我了解基本前提,但不知道它是如何运作的。 我需要的最大解释是 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
概率向量表示选择数字 1 到 6 的可能性的相对权重。一开始,他们都有平等的机会被选中。我将逐步介绍 while 循环的每一行,解释它的作用:
while 循环中的第一行根据
概率
向量创建累积概率。 CUMSUM 函数用于返回累积和沿着向量的长度,除以向量的总和(使用 SUM 函数)。第一次通过循环时,cumprob
将具有以下值:<前><代码>0.1667 0.3333 0.5000 0.6667 0.8333 1.0000
请注意,这些创建了“容器”,从 0 到 1 的随机数都可以落入其中。一个数字落入给定容器的概率等于该容器的宽度,因此 6 中有一个 1 (0.1667 )随机抽取的数字落入第一个 bin(从 0 到 0.1667)或第二个 bin(从 0.1667 到 0.3333)等的机会。
while 循环中的第二行选择一个随机数(使用 RAND 函数)并查找 cumprob 中第一个大于该值的元素的索引(使用 FIND 功能)。因此,
roll
值是从 1 到 6 的数字。概率
具有以下形式:<前><代码>[xxx 1 xx]
其中
x
是大于1的某个值。此时,选择值4的概率是1/(5*x+1)
。通过向所有元素添加 1,该概率变为2/(5*x+7)
。对于x = 3
,出现 4 的概率从 0.0625 增加到 0.0909,而出现任何其他数字的概率从 0.1875 减少到 0.1818 。因此,这种“非随机性”的作用是标准化概率。请注意,从
概率
的一个元素中减去的金额等于添加到上一行中所有元素的总金额,从而导致总和的净变化为零概率
向量。这使概率
中的值保持有界,这样它们就不会不断增长。while 循环末尾的 if 语句只是为了确保
概率
中的所有数字都是正数。如果向量的最小值(使用 MIN function) 小于零,则从向量的每个元素中减去该值。这将确保 cumprob 向量的值始终在 0 到 1 之间。如果将
while true
语句替换为for i = 1:6
,在每次迭代结束时显示概率向量和滚动值,并运行代码几次,您可以看到代码是如何执行其操作的。这是一组 6 次掷骰子,将数字 1 到 6 中的每一个抽出一次:请注意
概率
中的最终值是如何相等的,这意味着此时数字 1 到 6 都具有相等的概率再次被选中的可能性。The
probabilities
vector represents the relative weights for the likelihood that the numbers 1 through 6 will be selected. At the start, they all have an equal chance of being picked. I'll step through each line of the while loop explaining what it does:The first line within the while loop creates a cumulative probability from the
probabilities
vector. The CUMSUM function is used to return a cumulative sum along the length of the vector, and this is divided by the total sum of the vector (found using the SUM function). On the first pass through the loop,cumprob
will have these values:Notice that these create "bins" that a random number from 0 to 1 can fall in. The probability that a number will fall within a given bin is equal to the width of that bin, so there's a 1 in 6 (0.1667) chance that a randomly drawn number will fall in the first bin (from 0 to 0.1667), or the second bin (from 0.1667 to 0.3333), etc..
The second line within the while loop picks a random number (using the RAND function) and finds the index of the first element in
cumprob
that is larger than that value (using the FIND function). Theroll
value is thus a number from 1 to 6.The third line within the while loop adds "unrandomness" by shifting all the relative weights upward, moving the probabilities a little closer to being equal for all the numbers. Consider the example where
probabilities
has the following form:where
x
is some value greater than 1. At this point, the probability that the value 4 is chosen is1/(5*x+1)
. By adding 1 to all the elements, that probability becomes2/(5*x+7)
. Forx = 3
, the probability of 4 occurring increases from 0.0625 to 0.0909, while the probability of any other number occurring decreases from 0.1875 to 0.1818. This "unrandomness" is thus acting to normalize probabilities.The fourth line within the while loop essentially does the opposite of the previous line by significantly dropping the relative weight of whatever number just occurred, making it less likely to happen on subsequent loops. This reduced likelihood of occurrence will be short lived due to the effect of the previous line constantly trying to bring the probabilities of occurrence back to equal for all the numbers.
Note that the amount subtracted from the one element of
probabilities
is equal to the total amount added to all the elements in the previous line, resulting in a net change of zero for the total sum of theprobabilities
vector. This keeps the values inprobabilities
bounded so that they don't just keep growing and growing.The if statement at the end of the while loop is simply there to make sure all the numbers in
probabilities
are positive. If the minimum value of the vector (found using the MIN function) is less than zero, then this value is subtracted from every element of the vector. This will make sure thecumprob
vector always has values between 0 and 1.If you replace the
while true
statement withfor i = 1:6
, display theprobabilities
vector androll
value at the end of each iteration, and run the code a few times over you can see how the code does what it does. Here's one such set of 6 rolls that draws each of the numbers 1 through 6 once:Notice how the final values in
probabilities
are all equal, meaning that at that point the numbers 1 through 6 all have an equal likelihood of being chosen once again.