I want to generate a number based on a distributed probability. For example, just say there are the following occurences of each numbers:
Number| Count
I know this is an old post, but I also searched for such a generator and was not satisfied with the solutions I found. So I wrote my own and want to share it to the world.
Just call "Add(...)" some times before you call "NextItem(...)"
/// A class that will return one of the given items with a specified possibility.
/// The type to return.
/// If the generator has only one item, it will always return that item.
/// If there are two items with possibilities of 0.4 and 0.6 (you could also use 4 and 6 or 2 and 3)
/// it will return the first item 4 times out of ten, the second item 6 times out of ten.
public class RandomNumberGenerator
{
private List> _items = new List>();
private Random _random = new Random();
///
/// All items possibilities sum.
///
private double _totalPossibility = 0;
///
/// Adds a new item to return.
///
/// The possibility to return this item. Is relative to the other possibilites passed in.
/// The item to return.
public void Add(double possibility, T item)
{
_items.Add(new Tuple(possibility, item));
_totalPossibility += possibility;
}
///
/// Returns a random item from the list with the specified relative possibility.
///
/// If there are no items to return from.
public T NextItem()
{
var rand = _random.NextDouble() * _totalPossibility;
double value = 0;
foreach (var item in _items)
{
value += item.Item1;
if (rand <= value)
return item.Item2;
}
return _items.Last().Item2; // Should never happen
}
}