/// <summary> /// Samples an index from <paramref name="distribution"/>. /// </summary> /// <param name="distribution">A collection of values which sum to 1</param> /// <returns>The sampled index</returns> public static int Sample(this IEnumerable <float> distribution) { float sample = ThreadsafeRandom.NextFloat() * distribution.Sum(); Queue <float> values = new Queue <float>(distribution); int index = 0; while (sample > 0 && values.Count > 0) { sample -= values.Dequeue(); index++; } return(index - 1); }
/// <summary> /// Samples an index from <paramref name="list"/> using <paramref name="selector"/> to transform <typeparamref name="T"/> to a float. /// </summary> /// <typeparam name="T">Type of the list</typeparam> /// <param name="list">The list to sample</param> /// <param name="selector">Function used to create a normalized list</param> /// <returns>The sampled index</returns> public static int Sample <T>(this IEnumerable <T> list, Func <T, float> selector) { float sample = ThreadsafeRandom.NextFloat() * list.Sum(selector); Queue <float> values = new Queue <float>(from item in list select selector(item)); int index = 0; while (sample > 0 && values.Count > 0) { sample -= values.Dequeue(); index++; } return(index - 1); }