好吧,我测试了以下方式。
在x
之间生成0~x
次随机数,然后检查未生成的随机数。
我认为它会非常接近100%。我的意思是生成0~x
之间的所有数字。
但结果令人震惊。 36%的数字缺失。
我的随机功能不是真的随机吗?
下面是我的随机课程:
private static Random seedGenerator = new Random();
private static ThreadLocal<Random> random =
new ThreadLocal<Random>(SeededRandomFactory);
private static Random SeededRandomFactory()
{
lock (seedGenerator)
return new Random(seedGenerator.Next());
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
return random.Value.Next(irMinValue, irMinValue + irRandValRange);
}
以下结果如下:
Between 0-10, missing numbers count: 4, percent: 40% Between 0-100, missing numbers count: 36, percent: 36% Between 0-1000, missing numbers count: 369, percent: 36,9% Between 0-10000, missing numbers count: 3674, percent: 36,74% Between 0-100000, missing numbers count: 36583, percent: 36,58% Between 0-1000000, missing numbers count: 367900, percent: 36,79% Between 0-10000000, missing numbers count: 3678122, percent: 36,78% Between 0-100000000, missing numbers count: 36797477, percent: 36,8%
这里是我检查的代码:
File.WriteAllText("results.txt", "");
int irFirst = 10;
for (int i = 0; i < 8; i++)
{
HashSet<int> hsGenerated = new HashSet<int>();
for (int k = 0; k < irFirst; k++)
{
hsGenerated.Add(GenerateRandomValue.GenerateRandomValueMin(irFirst, 0));
}
int irNotFound = 0;
for (int k = 0; k < irFirst; k++)
{
if (hsGenerated.Contains(k) == false)
irNotFound++;
}
string srSonuc =
string.Format(
"Between 0-{0}, missing numbers count: {1}, percent: {2}%",
irFirst, irNotFound,
Math.Round((Convert.ToDouble(irNotFound)/Convert.ToDouble(irFirst))*100.0, 2).ToString()
);
using (StreamWriter w = File.AppendText("sonuclar.txt"))
{
w.WriteLine(srSonuc);
}
irFirst = irFirst * 10;
}
答案 0 :(得分:13)
如评论中所述,您的测试方法已关闭。
您在x和x之间绘制x倍数。特定数字不绘制的概率为:
当x接近无穷大时,p将朝向1 / e(或大约36.7879441%)这是您在结果中看到的数字。 此外,当x接近无穷大时,您将观察到这个概率作为样本的结果(大数定律)
这与概率有关。当你有一个红色和白色大理石碗。而你拿一个,把它拿回另一个你不能保证你看到两者。你可以把红色的两次。你正在用更多的对象做同样的事情。
详细说明真正的随机性:
我预计接近99%而不是64%。或至少90%+百分比。所以你说现在的技术是不可能的
这很简单。由于现代数学,技术和我的超能力,我可以告诉你如何做到这一点:你需要更多的抽奖而不是数字可供选择。公式变为:
其中n是所需的缺失数百分比。例如,如果您愿意接受5%的数字丢失,则必须绘制三倍于随机数的数字。对于1%的几率,您需要迭代最大数量的4.6倍。
此数学假设生成完全均匀的随机数。
答案 1 :(得分:5)
您的结果正是您在更换样品时的均匀分布所期望的结果。
考虑最简单的例子。你有一枚硬币扔两次。因此,我们假设我们从均匀的离散分布中采样。
以0.25的概率发生的可能结果是:
TT
TH
HT
HH
正如您所看到的,四种结果中只有两种具有头部和尾部。
这称为替换采样。所以,一旦我们对尾巴进行采样,然后我们“将它放回袋子里”,它就可以在下一个样品上再次出现。
现在假设我们在没有替换的情况下进行采样在这种情况下,有两种可能的结果:
TH
HT
如您所见,每个可能的值只出现一次。
基本上你对结果的期望是不正确的。作为另一个例子,假设你扔了一枚硬币然后它掉下了尾巴。你期望在下一次投球时会发生什么?你在争论硬币现在必须降下来。但这显然是无稽之谈。
如果您确实想要在没有替换的情况下进行采样,并且不清楚这是否真的是您想要的,那么您可以使用Fisher-Yates shuffle进行采样。
答案 2 :(得分:-1)
如果你想要1亿个独特的随机数,你可以这样做:
现在使用Fisher-Yates的算法:
List<int> numbers = new List<int>(100000000);
for (int i = 0; i < numbers.Capacity; i++)
{
int rnd = random.Next(numbers.Count + 1);
if (rnd == numbers.Count)
numbers.Add(i);
else
{
numbers.Add(numbers[rnd]);
numbers[rnd] = i;
}
}
顺便说一句,你可以更快地计算irNotFound:
int irNotFound = irFirst - hsGenerated.Count;
祝你好运。