随机数生成与重量

时间:2013-11-28 19:38:47

标签: c# random

我正在寻找生成4个随机数,介于1和10之间,并为每个数字分配权重。 例如:

number   weight
  1        3
  2        2
  3        6
 ...      ...
 10        3

我看到了一些关于此的文章(本网站上有一篇文章:https://softwareengineering.stackexchange.com/questions/150616/return-random-list-item-by-its-weight),但它并没有完全满足需要。 我需要在1到10之间生成4个数字,无需替换;不能有2,3,8,2。

4 个答案:

答案 0 :(得分:0)

生成数字而不重复。我建议将数字添加到列表中并删除已显示的数字。喜欢这个

List<int> nos = new List<int>(10);
nos.Add(1); nos.Add(2); nos.Add(3); nos.Add(4); nos.Add(5); 
nos.Add(6); nos.Add(7); nos.Add(8); nos.Add(9); nos.Add(10);
Random rnd = new Random();
int n1 = rnd.Next(nos.Count);
Console.WriteLine(nos[n1].ToString());
nos.RemoveAt(n1);
int n2 = rnd.Next(nos.Count - 1);
Console.WriteLine(nos[n2].ToString());
nos.RemoveAt(n2);
int n3 = rnd.Next(nos.Count - 2);
Console.WriteLine(nos[n3].ToString());
nos.RemoveAt(n3);
int n4 = rnd.Next(nos.Count - 3);
Console.WriteLine(nos[n4].ToString());
nos.RemoveAt(n4);

答案 1 :(得分:0)

这是我的想法,而不是统计/数学的程序员方式。有重量的数字列表:

number   weight
  1        3
  2        2
  3        6
...      ...
  9        3
 10        3

程序将选择List的随机索引,并在列表中选择所选索引处的数字。通过将该数字添加到列表中而模拟的数量的权重与权重一样多。这是主要的方法(感谢@Tijesunimi,因为我在他的答案中使用了部分代码而没有进行任何修正):

List<int> nos = new List<int>(10);
nos.AddWeightedNo(1, 3);
nos.AddWeightedNo(2, 2);
nos.AddWeightedNo(3, 6);
//...
nos.AddWeightedNo(9, 3);
nos.AddWeightedNo(10, 3);
Random rnd = new Random();
int n1 = rnd.Next(nos.Count);
Console.WriteLine(nos[n1].ToString());
nos.RemoveWeightedNo(nos[n1]);
int n2 = rnd.Next(nos.Count);
Console.WriteLine(nos[n2].ToString());
nos.RemoveWeightedNo(nos[n2]);
int n3 = rnd.Next(nos.Count);
Console.WriteLine(nos[n3].ToString());
nos.RemoveWeightedNo(nos[n3]);
int n4 = rnd.Next(nos.Count);
Console.WriteLine(nos[n4].ToString());
nos.RemoveWeightedNo(nos[n4]);

扩展方法AddWeightedNo和RemoveWeightedNo:

public static class Extension
{
    public static void AddWeightedNo(this List<int> nos, int no, int weight)
    {
        for (int i = 0; i < weight; i++)
        {
            nos.Add(no);
        }
    }

    public static void RemoveWeightedNo(this List<int> nos, int no)
    {
        nos.RemoveAll(o => o == no);
    }
}

答案 2 :(得分:0)

&#34; I&#34;通过实现按位搜索算法解决了其他语言问题。网络上有一些例子,即使是堆栈溢出 - 但我想只有其他语言。

我自己也需要一个,所以当我准备好之后,我有机会在这里发布代码。

按位搜索可能不是最快的,但它对于大多数情况来说足够快,并且它会比#34;扩展整个列表更快#34;这是解决这个问题的最长时间。

以下是解释:https://stackoverflow.com/a/1761646/129202

我引用一般的方法分三步:

  1. 计算所有权重的总和

  2. 选择0或更大且小于的随机数 权重之和

  3. 一次检查一项,减去它们的重量 你的随机数,直到你得到随机数的项目 小于该项目的重量

答案 3 :(得分:0)

这是一个简单的方法:

private static string GenerateStatus()
    {
        var validStatuses = new Dictionary<char, string> 
        {
            {'1', "InProcess"}, {'2',"Partial"}, {'3', "Failed"}, {'4', "Delivered"}, {'5',  "NTD"}, {'6',  "Filtered"}, {'7',  "Rejected"}, {'8',  "Waiting"}, {'9',  "Retrying"}, {'A', 
            "Suspended"}, {'B',  "Complete"}
        };
        const string statusDistribution = "4441444444344444A414444444434444447444B41444414444444444444544444441444444444344444A4444484144444446444449444441444444";

        return validStatuses[statusDistribution[_rand.Next(0, statusDistribution.Length)]];
    }

这个想法很简单。使用尽可能多的指数(如'3')。例如,40表示'4',只有1表示'2'。