Musisz ważyć wyniki. Można zrobić coś takiego:
private int[] _distribution = new int[] { 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9 };
Random _r = new Random();
public int GetWeightedRandom()
{
return _distribution[_r.Next(0, _distribution.Length)];
}
Gdybym wiedział, moja oferta była mała i spójne, będę korzystać z tabeli - to trywialne, aby jego własna klasa.
Dla kompletności dodam również tę klasę. Klasa ta pożycza od przetwarzania obrazu i używa funkcji korekcji gamma: wartość od 0 do 1 podniesiona do gamma, która zwraca wartość z zakresu od 0 do 1, ale jest dystrybuowana więcej do niższego końca, jeśli gamma < 1.0 i więcej do wyższego rzędu, jeśli gamma> 1.0.
public class GammaRandom {
double _gamma;
Random _r;
public GammaRandom(double gamma) {
if (gamma <= 0) throw new ArgumentOutOfRangeException("gamma");
_gamma = gamma;
_r = new Random();
}
public int Next(int low, int high) {
if (high <= low) throw new ArgumentOutOfRangeException("high");
double rand = _r.NextDouble();
rand = math.Pow(rand, _gamma);
return (int)((high - low) * rand) + low;
}
}
(od komentarzy, przeniósł R z GetWeightedRandom(). Dodano także zakres kontroli do next())
OK, niech naprawdę iść do miasta tutaj. Przeznaczam na to Johna Skeeta - jest to klasa abstrakcyjna z właściwością szablonu, która zwraca funkcję przekształcenia, która odwzorowuje zakres [0..1] do [0..1] i skaluje liczbę losową do tego zakresu. Odwzorowałem również gamma pod kątem tego i zaimplementowałem grzech i cos.
public abstract class DelegatedRandom
{
private Random _r = new Random();
public int Next(int low, int high)
{
if (high >= low)
throw new ArgumentOutOfRangeException("high");
double rand = _r.NextDouble();
rand = Transform(rand);
if (rand >= 1.0 || rand < 0) throw new Exception("internal error - expected transform to be between 0 and 1");
return (int)((high - low) * rand) + low;
}
protected abstract Func<double, double> Transform { get; }
}
public class SinRandom : DelegatedRandom
{
private static double pihalf = Math.PI/2;
protected override Func<double, double> Transform
{
get { return r => Math.Sin(r * pihalf); }
}
}
public class CosRandom : DelegatedRandom
{
private static double pihalf = Math.PI/2;
protected override Func<double, double> Transform
{
get { return r => Math.Cos(r * pihalf); }
}
}
public class GammaRandom : DelegatedRandom
{
private double _gamma;
public GammaRandom(double gamma)
{
if (gamma <= 0) throw new ArgumentOutOfRangeException("gamma");
_gamma = gamma;
}
protected override Func<double, double> Transform
{
get { return r => Math.Pow(r, _gamma); }
}
}
Więc prosisz dla liczb losowych, które eee, nie są przypadkowe? – blowdart
Nie, on nie chce, on po prostu chce innej dystrybucji (więcej w stylu Gaussa około 8, nierównomiernie rozmieszczonych we wszystkich liczbach) – schnaader
Chciałbym generować ważone liczby losowe. –