从一组数中每次抽取出一个数,并规定了每个数出现的概率
这个问题,我是这样考虑的:
假设有4个数字a、b、c,他们出现的概率分别为 10%,30%和60%。现在我随机生成一个0-99的随机数,如果随机数在0-9之间,则抽取a,随机数在10-39之间,则抽取b,随机数在40-99之间则抽取c。
实现代码如下:
using System;
using System.Collections;
using System.Diagnostics;
using System.Threading;
namespace zqf620.Demo.WeightingNumber
{
/// <summary>
/// WeightingNumber 的摘要说明。
/// </summary>
public class WeightingNumber
{
public WeightingNumber()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public WeightingNumber(params uint[] weightings) //构造函数
{
this.setWeighting(weightings);
}
private ArrayList _weightings = new ArrayList();
private int _count = 0;
public bool setWeighting(params uint[] weightings) //设置一组权重,要求所有权重之和为100
{
uint count = 0;
uint min,max;
foreach(uint i in weightings)
{
min = count*100;
max = min + i*100 -1;
zone tmp = new zone(min,max);
_weightings.Add(tmp);
count += i;
}
if (count != 100)
return false;
else
{
_count = _weightings.Count;
return true;
}
}
public int GetIndex() //返回一组数的一个下标
{
int index = -1;
if(_count == 0)
return index;
Random rdm = new Random(unchecked((int)DateTime.Now.Ticks));
int num = rdm.Next(0,9999);
// Debug.Write(num);
for(int i = 0; i < this._count; i++)
{
zone tmp = (zone)_weightings[i];
if(num >= tmp.minValue && num <= tmp.maxValue)
{
index = i;
return index;
}
}
return index;
}
struct zone //用于保存一个minValue到maxValue区域
{
public uint minValue,maxValue;
public zone(uint min,uint max)
{
minValue = min;
maxValue = max;
}
}
static void Main()
{
int[] chars = new int[]{0,1,2,3,4}; //一组数,0 1 2 3 4
//0出现的概率为10%,1出现的概率为20%,2出现的概率为40%,…… 这些概率值加起来必须为100
WeightingNumber wn = new WeightingNumber(10,20,40,15,15);
ArrayList result = new ArrayList(200);
for(int i = 0; i < 200 ;i++) //抽取200次
{
Thread.Sleep(1);
int index = wn.GetIndex(); //抽取下标
result.Add(chars[index]); //得到下标对应的数字
// Console.WriteLine(chars[index]);
}
//以下是打印抽取结果的代码
result.Sort();
for(int i = 0 ; i < result.Count ; i++)
{
if(i !=0)
{
if((int)result[i-1] != (int)result[i])
Console.WriteLine();
}
Console.Write("{0}",result[i]);
}
Console.ReadLine();
}
}
}