从加权列表中选择一个随机项

时间:2011-09-09 20:01:26

标签: c# random distribution weighted

我正在尝试编写一个程序来从US Census last name list中选择一个随机名称。列表格式为

Name           Weight Cumulative line
-----          -----  -----      -
SMITH          1.006  1.006      1
JOHNSON        0.810  1.816      2
WILLIAMS       0.699  2.515      3
JONES          0.621  3.136      4
BROWN          0.621  3.757      5
DAVIS          0.480  4.237      6

假设我将数据加载到类似

的结构中
Class Name
{
    public string Name {get; set;}
    public decimal Weight {get; set;}
    public decimal Cumulative {get; set;}
}

哪种数据结构最适合保存名称列表,以及从列表中选择随机名称但名称分布与现实世界相同的最佳方式。

如果它在数据结构上有所不同,我将只使用前10,000行。

我已经尝试过关于加权随机性的其他一些问题但我在将理论转化为代码时遇到了一些麻烦。我对数学理论知之甚少,所以我不知道这是一个“有或没有替代”的随机选择,我想要同一个名字能够不止一次出现,这就是那个意思。

4 个答案:

答案 0 :(得分:6)

处理此问题的“最简单”方法是将其保存在列表中。

然后你可以使用:

Name GetRandomName(Random random, List<Name> names)
{
    double value = random.NextDouble() * names[names.Count-1].Culmitive;
    return names.Last(name => name.Culmitive <= value);
}

如果速度是一个问题,您可以存储一个仅包含Culmitive值的单独数组。有了这个,您可以使用Array.BinarySearch快速找到合适的索引:

Name GetRandomName(Random random, List<Name> names, double[] culmitiveValues)
{
    double value = random.NextDouble() * names[names.Count-1].Culmitive;
    int index = Array.BinarySearch(culmitiveValues, value);
    if (index >= 0)
        index = ~index;

    return names[index];
}

可能最有效的另一种选择是使用C5 Generic Collection Librarytree classes之一。然后,您可以使用RangeFrom查找相应的名称。这具有不需要单独收集的优点

答案 1 :(得分:3)

我创建了a C# library for randomly selected weighted items

  • 它实现了树选择和walker别名方法算法,以便为所有用例提供最佳性能。
  • 经过单元测试和优化。
  • 它有LINQ支持。
  • 它是免费的开放源代码,根据MIT许可证授权。

一些示例代码:

add

答案 2 :(得分:0)

我会说一个数组(如果你愿意,可以使用矢量)最好保留它们。对于加权平均值,找到总和,在零和总和之间选择一个随机数,然后选择累积值较小的姓氏。 (例如,这里,&lt; 1.006 =史密斯,1.006-1.816 =约翰逊等。

P.S。这是累积的。

答案 3 :(得分:0)

只是为了好玩,而且绝不是最佳的

List<Name> Names = //Load your structure into this

List<String> NameBank = new List<String>();
foreach(Name name in Names)
   for(int i = 0; i <= (int)(name.Weight*1000); i++)
     NameBank.Add(name.Name)

然后:

String output = NameBank[rand(NameBank.Count)];
相关问题