【问题标题】:How To Make Selection Random Based On Percentage如何根据百分比随机选择
【发布时间】:2016-02-26 14:18:49
【问题描述】:

我有一堆物品,尺寸1-10开始。

我想让项目的大小由百分比或对象是该大小的机会来确定..

例如:

物品出现尺寸的几率1 = 50% 几率

物品出现尺寸的几率5 = 20% 几率

物品出现尺寸的几率10 = 5% 几率

我知道我当然需要为此使用Random 生成器。

但只是想知道你们中的一些人会如何处理 C# 中的逻辑?

【问题讨论】:

  • 用 50 个 1、20 个 5 和 5 个 10 填写一个列表(以及其他,直到列表中有 100 个项目)。然后获取 0 到 99 之间的随机数,并将其用作列表中的索引以获取相应的值。
  • 不,OP 正在询问如何获取给定分布的随机数。投票回购。
  • 不,OP 是在询问如何进行比例/轮盘赌选择,就像 Corak 的答案(这应该是一个答案!)。
  • 现在这个问题,当然也有人问过了。 Distributed probability random number generator 的可能重复项
  • 50% + 20% + 5% = 75% 不等于100%,完整的可能性是什么?

标签: c# math random


【解决方案1】:

首先:提供的概率加起来不是 100%

50% + 20% + 5% = 75%

所以你必须检查这些值。您可能想要生成这些百分比:

// Simplest, but not thread safe
private static Random s_Random = new Random();

...
int perCent = s_Random.Next(0, 100);

if (perCent < 50)               //  0 .. 49
{
    // return Item of size 1
}
else if (perCent < 50 + 20)     // 50 .. 69
{
    // return Item of size 5
}
else if (perCent < 50 + 20 + 5) // 70 .. 74 
{
    // return Item of size 10
} 
...

【讨论】:

  • 太棒了。非常感谢。另一件事是提供的项目数量可以从 5 到 50 不等。那么有没有办法在 1-50 之间的任何数字之间分配重量。例如 - 项目 #1 最大尺寸为 50。那么我怎样才能让每个尺寸都有重量?因为 50 里面有 10 号、2 号、20 号等。我希望这是有道理的。
【解决方案2】:

使用我的方法。它简单易懂。 我不计算 0...1 范围内的部分,我只使用“Probabilityp Pool”(听起来很酷,是吗?) 我列出了我想要选择的所有元素。每个元素都有自己的机会。将最常见的元素几率设置为 100 很有用,因此最稀有的元素将是 60 或 50。

At circle diagram you can see weight of every element in pool

Here you can see an implementing of accumulative probability for roulette

`

// Some c`lass or struct for represent items you want to roulette
public class Item
{
    public string name; // not only string, any type of data
    public int chance;  // chance of getting this Item
}

public class ProportionalWheelSelection
{
    public static Random rnd = new Random();

    // Static method for using from anywhere. You can make its overload for accepting not only List, but arrays also: 
    // public static Item SelectItem (Item[] items)...
    public static Item SelectItem(List<Item> items)
    {
        // Calculate the summa of all portions.
        int poolSize = 0;
        for (int i = 0; i < items.Count; i++)
        {
            poolSize += items[i].chance;
        }

        // Get a random integer from 0 to PoolSize.
        int randomNumber = rnd.Next(0, poolSize) + 1;

        // Detect the item, which corresponds to current random number.
        int accumulatedProbability = 0;
        for (int i = 0; i < items.Count; i++)
        {
            accumulatedProbability += items[i].chance;
            if (randomNumber <= accumulatedProbability)
                return items[i];
        }
        return null;    // this code will never come while you use this programm right :)
    }
}

// Example of using somewhere in your program:
        static void Main(string[] args)
        {
            List<Item> items = new List<Item>();
            items.Add(new Item() { name = "Anna", chance = 100});
            items.Add(new Item() { name = "Alex", chance = 125});
            items.Add(new Item() { name = "Dog", chance = 50});
            items.Add(new Item() { name = "Cat", chance = 35});

            Item newItem = ProportionalWheelSelection.SelectItem(items);
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多