我正在尝试在多个存储桶中分配一组项目。我正在寻找以下属性:
桶分配必须确定。在不同的运行中相同 输入应最终位于同一存储桶中。
存储分区之间的数据分配应该是均匀的。
首先尝试从输入数据生成md5,并从md5的第一个字节形成存储桶。我对统一性不太满意。当输入较大时,它可以很好地工作,但对于较小的输入,则不能很好地工作。例如。在64个存储桶中分配100个项目:
List<string> l = new List<string>();
for (int i = 0; i < 100; i++)
{
l.Add(string.Format("data{0}.txt", i));
}
int[] buckets = new int[64];
var md5 = MD5.Create();
foreach (string str in l)
{
{
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(str));
uint bucket = BitConverter.ToUInt32(hash, 0) % 64;
buckets[bucket % 64]++;
}
}
任何建议我该怎么做才能获得更高的均匀性?谢谢。
答案 0 :(得分:1)
不考虑将MD5用于此目的的效率(请参见讨论here和该问题的带标记的重复内容),基本上答案是您所拥有的就是均匀分布的真正外观。 / p>
这似乎是违反直觉的,但是很容易通过数学或实验证明。
作为一种激励示例,请考虑在0-63范围内准确选择64个数字的任务。每个存储桶中获得一个的几率非常接近0。共有64 64 个可能的序列,其中64个!包含所有64个数字。获得这些序列之一的几率约为3.1×10 26 之一。实际上,获得一个没有元素出现三遍的序列的几率小于千分之一(约.000658)。因此,几乎可以肯定的是,在0-63范围内的64个数字的随机统一样本将具有一些三胞胎,并且很可能会有一些四胞胎。如果样本是100个数字,那么这些概率将变得更大。
但是一般而言,数学并不是那么容易计算,因此我在这里选择使用random.org通过实验进行演示:-),这是一个非常可靠的随机数源。我要求它提供0-63范围内的100个数字,并对其进行计数(使用bash,因此我的“图形”不如您的漂亮)。这是两次运行:
Random numbers:
44 17 50 11 16 4 24 29 12 36
27 32 12 63 4 30 19 60 28 39
22 40 19 16 23 2 46 31 52 41
13 2 42 17 29 39 43 9 20 50
45 40 38 33 17 45 28 6 48 12
56 26 34 33 35 40 28 44 22 10
50 55 49 43 63 62 22 50 15 52
48 54 53 26 4 53 13 56 42 60
49 30 14 55 29 62 15 13 35 40
22 38 37 36 10 36 5 41 43 53
Counts:
X X X
X XX X X XX X X X X X
X X X XX XXX X X X XXX X XX XXXXXXXX XXX XX XX X XX
X XXX XXXXXXXXX XX XXX XXXXXXXXXXXXXXXXXXXXX XXX XXXXX X XX
----------------------------------------------------------------
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6
0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2
Random numbers:
41 31 16 40 1 51 17 41 27 46
24 14 21 33 25 43 4 36 1 14
40 22 11 22 30 19 23 63 39 61
8 55 40 6 21 13 55 13 3 52
17 52 53 53 7 21 47 13 45 57
25 27 30 48 38 55 55 22 61 11
11 28 45 63 43 0 41 51 15 2
33 2 46 14 35 41 5 2 11 37
28 56 15 7 18 12 57 36 59 51
42 5 46 32 10 8 0 46 12 9
Counts:
X X X X
X X XX XX XX X X X
XXX X XX XXXXX X XX X XX X X X XX X XX XXX X X X X
XXXXXXXXXXXXXXXXXXXX XXXXX XX XXXX XXXXXXXXX XXXX XXX XXX X X X
----------------------------------------------------------------
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6
0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2
您可以使用自己喜欢的随机数生成器尝试此操作,并根据分布的大小进行调整。您将获得相同的形状。