Подтвердить что ты не робот

С# Обычный случайный номер

Я хотел бы создать функцию, которая принимает Double mean, Double deviation и возвращает случайное число с нормальным распределением.

Пример: если я пройду через 5.00 в качестве среднего и 2.00 в качестве отклонения, 68% времени я получу число между 3.00 и 7.00

Моя статистика немного слаба.... У кого-нибудь есть идея, как я должен подходить к этому? Моя реализация будет С# 2.0, но не стесняйтесь отвечать на вашем языке выбора, если математические функции являются стандартными.

Думаю, этот может быть тем, что я ищу. Любая помощь, конвертирующая это в код?

Заранее благодарим за помощь.

4b9b3361

Ответ 1

Смотрите эту статью CodeProject: Простая генерация случайных чисел. Код очень короткий, и он генерирует выборки из однородных, нормальных и экспоненциальных распределений.

Ответ 2

Вам может быть интересно Math.NET, в частности пакет Numerics.

Предостережение. Пакет численных значений предназначен для .NET 3.5. Возможно, вам придется использовать пакет Iridium, если вы ориентируетесь на более раннюю версию...

Ответ 3

Вот несколько C, которые возвращают два значения (rand1 и rand2), только потому, что алгоритм эффективно делает это. Это полярная форма преобразования Box-Muller.

void RandVal (double mean1, double sigma1, double *rand1, double mean2, double sigma2, double *rand2)
{
double u1, u2, v1, v2, s, z1, z2;

do {
    u1 = Random (0., 1.);  // a uniform random number from 0 to 1
    u2 = Random (0., 1.);
    v1 = 2.*u1 - 1.;
    v2 = 2.*u2 - 1.;
    s = v1*v1 + v2*v2;
} while (s > 1. || s==0.); 

z1 = sqrt (-2.*log(s)/s)*v1;
z2 = sqrt (-2.*log(s)/s)*v2;
*rand1 = (z1*sigma1 + mean1);
*rand2 = (z2*sigma2 + mean2);
return;

}

Ответ 5

Извините, у меня нет кода для вас, но я могу указать вам на некоторые алгоритмы в Википедии. Выбираемый алгоритм зависит от того, насколько вы точны и насколько быстро он должен быть.

Ответ 6

Для тех, кто ссылается на этот вопрос, простым решением может быть:

Random rand = new Random();
double normRand  = alglib.invnormaldistribution(rand.NextDouble())

по массе и сигме по мере необходимости.
Библиотека alglib доступна по адресу www.alglib.net

Ответ 7

Библиотека MetaNumerics, также .NET, рассчитает нормальное распределение (и почти все остальное из статистики), супер быстро. Посмотрите на страницу Feature для более подробной информации. Страница Codeplex находится здесь: http://metanumerics.codeplex.com/.

Ответ 8

Mathnet

из второго верхнего ответа

    public static double GenerateRandomVariant(double mean,double deviation,System.Random rand=null, int factor=1)
    {

        rand = rand ?? new Random();
        double randNormal=(MathNet.Numerics.Distributions.Normal.Sample(rand, mean , deviation));
        return factor * randNormal;

    }

Преобразование Box-Mueller

от верхнего ответа по ссылке (в два раза быстрее?)

by u/yoyoyoyosef Случайные гауссовские переменные

    public static double GenerateRandomVariant(double mean, double deviation, System.Random rand=null, int factor = 1)
    {
        rand = rand ?? new Random();
        double u1 = 1.0 - rand.NextDouble(); //uniform(0,1] random doubles
        double u2 = 1.0 - rand.NextDouble();
        double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
                     Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
        double randNormal=(
                     mean +  deviation * randStdNormal); //random normal(mean,stdDev^2)
        return randNormal * factor;
    }

Ответ 9

Я знаю, что этот пост немного стар, но я хотел бы поделиться небольшим проектом, который я создал вчера. Я думаю, что проще использовать С++ 11 и создать .dll в Managed С++. Там ссылка на источник и почтовый индекс, содержащий уже скомпилированную dll.

И код, который я сделал:

// NormalDistributionRandom.h
#include <random>

#pragma once

using namespace System;

namespace NormalDistribution 
{

    class _NormalDistributionRandom
    {
        std::default_random_engine engine;
        std::normal_distribution<double> distribution;

    public:
        _NormalDistributionRandom(double mean, double deviation) : distribution(mean, deviation)
        {
        }

        double Next()
        {
            return distribution(engine);
        }
    };

    public ref class NormalDistributionRandom
    {
    private:

        void* Distribution;

    public:

        NormalDistributionRandom( double mean, double deviation)
        {
            Distribution = new _NormalDistributionRandom(mean, deviation);
        }

        double Next()
        {
            return ((_NormalDistributionRandom*)Distribution)->Next();
        }
        ~NormalDistributionRandom()
        {
            this->!NormalDistributionRandom();
        }
    protected:
        !NormalDistributionRandom()
        {
            if (Distribution != nullptr)
            {
                delete (_NormalDistributionRandom*)Distribution;
                Distribution = nullptr;
            }
        }
    };

}