Генерация непрерывной случайной величины - C#

Узнай цену своей работы

Формулировка задачи:

Нужно сгенерировать методом фон Неймана(методом исключений) непрерывную случайную величину с плотностью как на прикрепленном фото. Нужно сделать на формах. Буду рад любой помощи, почитал литературу и ничего не понял... Надеюсь на вас!

Решение задачи: «Генерация непрерывной случайной величины»

textual
Листинг программы
class MainForm : Form
{
    private Chart _chart;
    
    public MainForm()
    {
        _chart = new Chart { Parent = this, Dock = DockStyle.Fill };
 
        var values = new List<float>();
        var random = new Random();
 
        for (int i = 0; i < 100000; i++)
            values.Add(NextRandom(random, Distribution, 0, 8, 0.25f));
 
        var x = Enumerable.Range(0, 1000).Select(i => 8f / 1000 * i).ToList();
        var y = x.Select(e => values.Count(v => v >= e && v <= e + 8f / 1000)).ToList();
 
        var name = "res";
        _chart.ChartAreas.Add(name);
        _chart.Series.Add(name);
        _chart.Series[name].ChartType = SeriesChartType.Spline;
        _chart.Series[name].Color = Color.Red;
        _chart.Series[name].Points.DataBindXY(x, y);
 
        AddSeries("prob", Color.Blue, Distribution, 0, 8);
    }
    
    private void AddSeries(string name, Color color, Func<float, float> f, float left, float right, float step = 1e-2f)
    {
        _chart.ChartAreas.Add(name);
        _chart.Series.Add(name);
        _chart.Series[name].ChartType = SeriesChartType.Spline;
        _chart.Series[name].Color = color;
        
        var x = new List<float>();
        var y = new List<float>();
        
        for (;left <= right; left += step)
        {
            x.Add(left);
            y.Add(f(left));
        }
        
        _chart.Series[name].Points.DataBindXY(x, y);
    }
    
    private float Distribution(float value)
    {
        value %= 2;
        return value * 0.25f / 2;
    }
    
    private float NextRandom(Random random, Func<float, float> distribution, float min, float max, float maxDistribution)
    {
        while (true)
        {
            var k1 = (float)random.NextDouble();
            var k2 = (float)random.NextDouble();
            
            var derivedK1 = min + (max - min) * k1;
            var derivedK2 = maxDistribution * k2;
            
            if (derivedK2 <= distribution(derivedK1))
                return derivedK1;
        }
    }
}
 
void Main()
{
    Application.Run(new MainForm());
}

Оцени полезность:

8   голосов , оценка 3.75 из 5
Похожие ответы