using System.Collections;
using System.Collections.Generic;
public static void Main()
const int Iterations = 100000;
var uqBag = new WeightedRandomBag<string>()
var resultDictionary = uqBag.ToDictionary(item => item.Item, item => 0);
for (var i = 0 ; i < Iterations ; i++)
var randomItem = uqBag.GetRandomItem();
resultDictionary[randomItem]++;
Console.WriteLine(string.Join("\n", resultDictionary.Select(p => $"{p.Key}, {p.Value}")));
public class WeightedRandomBag<T> :IEnumerable<(T Item, double AccumulatedWeight)>
private Random random = new Random();
private List<(T Item, double AccumulatedWeight)> _items = new List<(T, double)>();
private double accumulatedWeight;
public void Add((T Item, double Weight) weightedItem)
accumulatedWeight += weightedItem.Weight;
_items.Add((weightedItem.Item, accumulatedWeight));
public void Add(IEnumerable<(T Item, double Weight)> itemWeights)
_items.AddRange(itemWeights);
var randomWeight = random.NextDouble() * accumulatedWeight;
return _items.First(item => item.AccumulatedWeight >= randomWeight).Item;
public IEnumerator<(T Item, double AccumulatedWeight)> GetEnumerator()
return _items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
return _items.GetEnumerator();