创建一个概率为偶数的随机整数生成器
Creating a random int generator with an even probability
在下面的代码中,我想确保 theImageRand 等于 theImage 或 theImage2 的机会是均等的,但我意识到 1 到 100 之间的数字等于 2 mod 1 比2 mod 0. 所以图像被选择的时间不成比例。
这是我想到的最简单的想法,但也许有一个功能可以更轻松地做到这一点?我也在想我可以找到一个适合我正在寻找的数字并将其放入 randi(n)。
xRand = randi(100);
if mod(xRand,2) == 1
theImageRand = theImage;
elseif mod(xRand,2) == 0
theImageRand = theImage2;
end
如果我能解释得更清楚,请告诉我。提前致谢。
您可以生成一个介于 0 和 2 之间的数字,然后检查 xRand 是否等于 0 或 1,这有可能发生;然而,更大的数字会使一个人胜过另一个人的机会发生更大的变化。
(我说了两个,因为在声明随机值时,总是多出一个。)
tl;dr
您的代码完全符合您的要求,但可以通过使用 randi(2)
并删除 mod
的计算来简化它。但是,值得解决更多问题...
mod(xRand,2)
将 1-100 减少到 0/1
对于1到100之间的xRand
,mod(xRand,2)
的结果将平均分布在0和1上,您可以通过执行以下代码看到:
xRand = 1:100;
xMod = mod(xRand,2);
cnt1 = sum(xMod == 1) % results in 50
cnt0 = sum(xMod == 0) % results in 50 as well
基本上,您的代码按预期工作,因为 randi
选择从 1 到 100 的均匀分布的数字。随后,mod
将它们简化为二进制表示,自映射完成以来仍然均匀分布对于相等的垃圾箱。
使用 randi(2)
进行简化
生成这些均匀分布的二进制数的整个过程可以通过从头生成一个二进制集来简化。要实现这一点,您可以使用 randi(2)
直接给您 1
或 2
正如 rayryeng 在他对问题的评论中指出的那样。
这将为您提供以下代码:
xRand = randi(2);
if xRand == 1
theImageRand = theImage;
elseif xRand == 2
theImageRand = theImage2;
end
正确吗?
现在我们来看看这个问题的有趣部分:结果真的是均匀分布的吗?要检查这一点,我们可以运行代码N
次,然后分析每个图像被选择了多少次。因此,我们将 1 分配给第一张图像,将 2 分配给第二张图像,并将结果存储在 res
中。在 for 循环之后,我们取元素为 1 或 2 的总和。
N = 1000000;
theImage = 1;
theImage2 = 2;
res = zeros(N,1);
for n = 1:N
xRand = randi(2);
if xRand == 1
theImageRand = theImage;
elseif xRand == 2
theImageRand = theImage2;
end
% xRand = randi(100);
% if mod(xRand,2) == 1
% theImageRand = theImage;
% elseif mod(xRand,2) == 0
% theImageRand = theImage2;
% end
res(n) = theImageRand;
end
cnt1 = sum(res==1);
cnt2 = sum(res==2);
percentage1 = cnt1/N*100 % approximately 50
percentage2 = cnt2/N*100 % approximately 50 as well
正如我们所见,percentage1
和 percentage2
大约为 50,这意味着两张图片在大约 50% 的时间内都被选中。 计算 cnt1
和 cnt2
之间的差异可能会产生误导,因为如果 N
很大,这个数字可能会很高。 但是,如果我们观察对于许多实现的这种差异,总体平均值将近似为零。此外,我们可以观察到您使用 mod(randi(100),2)
的代码也给出了 50% 的分布。它只是不如 randi(2)
的解决方案高效和直接,后者在我使用 R2016a 的机器上的执行速度提高了大约 15%。
底线: 我建议使用上面建议的 randi(2)
,因为它更直观,也更高效。观察到的差异归因于随机过程,并通过更多实现来平衡自身。重要的是要考虑两个图像的百分比而不是绝对差异。
在下面的代码中,我想确保 theImageRand 等于 theImage 或 theImage2 的机会是均等的,但我意识到 1 到 100 之间的数字等于 2 mod 1 比2 mod 0. 所以图像被选择的时间不成比例。
这是我想到的最简单的想法,但也许有一个功能可以更轻松地做到这一点?我也在想我可以找到一个适合我正在寻找的数字并将其放入 randi(n)。
xRand = randi(100);
if mod(xRand,2) == 1
theImageRand = theImage;
elseif mod(xRand,2) == 0
theImageRand = theImage2;
end
如果我能解释得更清楚,请告诉我。提前致谢。
您可以生成一个介于 0 和 2 之间的数字,然后检查 xRand 是否等于 0 或 1,这有可能发生;然而,更大的数字会使一个人胜过另一个人的机会发生更大的变化。
(我说了两个,因为在声明随机值时,总是多出一个。)
tl;dr
您的代码完全符合您的要求,但可以通过使用 randi(2)
并删除 mod
的计算来简化它。但是,值得解决更多问题...
mod(xRand,2)
将 1-100 减少到 0/1
对于1到100之间的xRand
,mod(xRand,2)
的结果将平均分布在0和1上,您可以通过执行以下代码看到:
xRand = 1:100;
xMod = mod(xRand,2);
cnt1 = sum(xMod == 1) % results in 50
cnt0 = sum(xMod == 0) % results in 50 as well
基本上,您的代码按预期工作,因为 randi
选择从 1 到 100 的均匀分布的数字。随后,mod
将它们简化为二进制表示,自映射完成以来仍然均匀分布对于相等的垃圾箱。
使用 randi(2)
进行简化
生成这些均匀分布的二进制数的整个过程可以通过从头生成一个二进制集来简化。要实现这一点,您可以使用 randi(2)
直接给您 1
或 2
正如 rayryeng 在他对问题的评论中指出的那样。
这将为您提供以下代码:
xRand = randi(2);
if xRand == 1
theImageRand = theImage;
elseif xRand == 2
theImageRand = theImage2;
end
正确吗?
现在我们来看看这个问题的有趣部分:结果真的是均匀分布的吗?要检查这一点,我们可以运行代码N
次,然后分析每个图像被选择了多少次。因此,我们将 1 分配给第一张图像,将 2 分配给第二张图像,并将结果存储在 res
中。在 for 循环之后,我们取元素为 1 或 2 的总和。
N = 1000000;
theImage = 1;
theImage2 = 2;
res = zeros(N,1);
for n = 1:N
xRand = randi(2);
if xRand == 1
theImageRand = theImage;
elseif xRand == 2
theImageRand = theImage2;
end
% xRand = randi(100);
% if mod(xRand,2) == 1
% theImageRand = theImage;
% elseif mod(xRand,2) == 0
% theImageRand = theImage2;
% end
res(n) = theImageRand;
end
cnt1 = sum(res==1);
cnt2 = sum(res==2);
percentage1 = cnt1/N*100 % approximately 50
percentage2 = cnt2/N*100 % approximately 50 as well
正如我们所见,percentage1
和 percentage2
大约为 50,这意味着两张图片在大约 50% 的时间内都被选中。 计算 cnt1
和 cnt2
之间的差异可能会产生误导,因为如果 N
很大,这个数字可能会很高。 但是,如果我们观察对于许多实现的这种差异,总体平均值将近似为零。此外,我们可以观察到您使用 mod(randi(100),2)
的代码也给出了 50% 的分布。它只是不如 randi(2)
的解决方案高效和直接,后者在我使用 R2016a 的机器上的执行速度提高了大约 15%。
底线: 我建议使用上面建议的 randi(2)
,因为它更直观,也更高效。观察到的差异归因于随机过程,并通过更多实现来平衡自身。重要的是要考虑两个图像的百分比而不是绝对差异。