普通随机抽取分别进行1000次和10000次测试显示:
1000次
10000次
控制随机几率随机抽取分别进行1000次和10000次代码修改:
1. 将rc.RandomExtract(rand)改为rc.ControllerRandomExtract(rand)
2. 注释掉上面输出部分代码,加上以下代码:
Dictionary
<
char
,
ushort
>
items
=
new
Dictionary
<
char
,
ushort
>
();
for ( int i = 0 ,j = rc.datas.Count; i < j; i ++ )
{
items.Add(rc.datas[i],rc.weights[i]);
}
Console.WriteLine( " \t\t出现次数\t占总共出现次数百分比\t权值 " );
foreach (KeyValuePair < char , int > item in result)
{
Console.WriteLine(item.Key + " \t\t " + item.Value.ToString() + " \t\t " + (( double )item.Value / ( double )(FOR_COUNT * COUNT)).ToString( " 0.00% " ) + " \t\t\t " + items[item.Key]);
}
for ( int i = 0 ,j = rc.datas.Count; i < j; i ++ )
{
items.Add(rc.datas[i],rc.weights[i]);
}
Console.WriteLine( " \t\t出现次数\t占总共出现次数百分比\t权值 " );
foreach (KeyValuePair < char , int > item in result)
{
Console.WriteLine(item.Key + " \t\t " + item.Value.ToString() + " \t\t " + (( double )item.Value / ( double )(FOR_COUNT * COUNT)).ToString( " 0.00% " ) + " \t\t\t " + items[item.Key]);
}
测试结果:
1000次
10000次
小结
从上面统计结果可以看出,普通随机数分布比较均匀,随机抽中的几率相对持平;但是经过控制随机抽中几率,权值高的明显抽中几率要高,另外需要注意的是这里只输出了25个字母,也就是还有一个字母没有被抽中过,因为按算法他是始终不会出现的,除非一次抽26个!!
需要注意的是:
1. 合理的调配权值和随机数生成的大小也很有关系,大家可以看到权值5的和权值1的出现几率相差不是5倍,而是30-50倍。
2. 如果数据源随机的数据大,比如上千上万条,按现在的程序是不可行的,可以先随机抽取比所需抽取个数多2-5倍的数据,然后直接按权值排序然后抽取前N位来达到目的。
3. 最重要的一点就是注意随机性,这个算法如果不是建立在随机的机制上是毫无价值的!!
本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586455,如需转载请自行联系原作者