using System; using System.Collections.Generic; using System.Linq; namespace MLEM.Extensions { /// /// A set of extensions for dealing with /// public static class RandomExtensions { /// /// Gets a random entry from the given list with uniform chance. /// /// The random /// The entries to choose from /// The entries' type /// A random entry public static T GetRandomEntry(this Random random, IList entries) { return entries[random.Next(entries.Count)]; } /// /// Returns a random entry from the given list based on the specified weight function. /// A higher weight for an entry increases its likeliness of being picked. /// /// The random /// The entries to choose from /// A function that applies weight to each entry /// The entries' type /// A random entry, based on the entries' weight /// If the weight function returns different weights for the same entry public static T GetRandomWeightedEntry(this Random random, IList entries, Func weightFunc) { var totalWeight = entries.Sum(weightFunc); var goalWeight = random.Next(totalWeight); var currWeight = 0; foreach (var entry in entries) { currWeight += weightFunc(entry); if (currWeight >= goalWeight) return entry; } throw new IndexOutOfRangeException(); } /// public static T GetRandomWeightedEntry(this Random random, IList entries, Func weightFunc) { var totalWeight = entries.Sum(weightFunc); var goalWeight = random.NextDouble() * totalWeight; var currWeight = 0F; foreach (var entry in entries) { currWeight += weightFunc(entry); if (currWeight >= goalWeight) return entry; } throw new IndexOutOfRangeException(); } } }