selection based on percentage weighting

后端 未结 13 2058
忘掉有多难
忘掉有多难 2020-12-04 13:40

I have a set of values, and an associated percentage for each:

a: 70% chance
b: 20% chance
c: 10% chance

I want to select a value (a, b, c) based

相关标签:
13条回答
  • 2020-12-04 14:19

    Here is my version that can apply to any IList and normalize the weight. It is based on Timwi's solution : selection based on percentage weighting

    /// <summary>
    /// return a random element of the list or default if list is empty
    /// </summary>
    /// <param name="e"></param>
    /// <param name="weightSelector">
    /// return chances to be picked for the element. A weigh of 0 or less means 0 chance to be picked.
    /// If all elements have weight of 0 or less they all have equal chances to be picked.
    /// </param>
    /// <returns></returns>
    public static T AnyOrDefault<T>(this IList<T> e, Func<T, double> weightSelector)
    {
        if (e.Count < 1)
            return default(T);
        if (e.Count == 1)
            return e[0];
        var weights = e.Select(o => Math.Max(weightSelector(o), 0)).ToArray();
        var sum = weights.Sum(d => d);
    
        var rnd = new Random().NextDouble();
        for (int i = 0; i < weights.Length; i++)
        {
            //Normalize weight
            var w = sum == 0
                ? 1 / (double)e.Count
                : weights[i] / sum;
            if (rnd < w)
                return e[i];
            rnd -= w;
        }
        throw new Exception("Should not happen");
    }
    
    0 讨论(0)
提交回复
热议问题