随机加权的选择

2023-09-10 22:41:07 作者:深渊

考虑到再$ P $下面的类psents一个经纪人:

Consider the class below that represents a Broker:

public class Broker
{
    public string Name = string.Empty;
    public int Weight = 0;

    public Broker(string n, int w)
    {
        this.Name = n;
        this.Weight = w;
    }
}

我想随机从数组中选择一个经纪人,考虑到它们的权重。

I'd like to randomly select a Broker from an array, taking into account their weights.

你觉得以下的code?

What do you think of the code below?

class Program
    {
        private static Random _rnd = new Random();

        public static Broker GetBroker(List<Broker> brokers, int totalWeight)
        {
            // totalWeight is the sum of all brokers' weight

            int randomNumber = _rnd.Next(0, totalWeight);

            Broker selectedBroker = null;
            foreach (Broker broker in brokers)
            {
                if (randomNumber <= broker.Weight)
                {
                    selectedBroker = broker;
                    break;
                }

                randomNumber = randomNumber - broker.Weight;
            }

            return selectedBroker;
        }


        static void Main(string[] args)
        {
            List<Broker> brokers = new List<Broker>();
            brokers.Add(new Broker("A", 10));
            brokers.Add(new Broker("B", 20));
            brokers.Add(new Broker("C", 20));
            brokers.Add(new Broker("D", 10));

            // total the weigth
            int totalWeight = 0;
            foreach (Broker broker in brokers)
            {
                totalWeight += broker.Weight;
            }

            while (true)
            {
                Dictionary<string, int> result = new Dictionary<string, int>();

                Broker selectedBroker = null;

                for (int i = 0; i < 1000; i++)
                {
                    selectedBroker = GetBroker(brokers, totalWeight);
                    if (selectedBroker != null)
                    {
                        if (result.ContainsKey(selectedBroker.Name))
                        {
                            result[selectedBroker.Name] = result[selectedBroker.Name] + 1;
                        }
                        else
                        {
                            result.Add(selectedBroker.Name, 1);
                        }
                    }
                }


                Console.WriteLine("A\t\t" + result["A"]);
                Console.WriteLine("B\t\t" + result["B"]);
                Console.WriteLine("C\t\t" + result["C"]);
                Console.WriteLine("D\t\t" + result["D"]);

                result.Clear();
                Console.WriteLine();
                Console.ReadLine();
            }
        }
    }

我没有那么自信。当我运行此,经纪人总是得到比经纪人d个命中,并且他们有相同的权重。

I'm not so confident. When I run this, Broker A always gets more hits than Broker D, and they have the same weight.

有没有更精确的算法?

谢谢!

推荐答案

您的算法是接近正确。然而,测试应该是&LT; 而不是&LT; =

Your algorithm is nearly correct. However, the test should be < instead of <=:

if (randomNumber < broker.Weight)

这是因为0是包容性的随机数,而 totalWeight 是排斥的。换句话说,与权重为0经纪人还是会有很小的几率被选中的 - 不是所有你想要的东西。这说明了经纪人有更多的点击率超过券商ð。

This is because 0 is inclusive in the random number while totalWeight is exclusive. In other words, a broker with weight 0 would still have a small chance of being selected – not at all what you want. This accounts for broker A having more hits than broker D.

除此之外,你的算法是细而解决这一问题的实际上的正规途径

Other than that, your algorithm is fine and in fact the canonical way of solving this problem.

相关推荐
 
精彩推荐
图片推荐