Me gustaría usar la distribución integrada, pero agregarle algunas restricciones. Intenté algo como esto, pero obtengo el mismo número cuando uso la función. ¿Cómo puedo evitar esto? ¿Puedo usar la distribución como argumento de la función?

double Cauchy(double Fm){
    std::default_random_engine generator;
    std::cauchy_distribution<double> distribution(Fm, 0.1);
    double number=distribution(generator);
    while(number<0)
        number=distribution(generator);
    if (number>1)
        number = 1;
    return number;
}

Ahora cambié la función y se ve así

double Cauchy_1(double Fm, std::random_device &rd){

    std::default_random_engine generator(rd());
    std::cauchy_distribution<double> distribution(Fm, 0.1);
    double number=distribution(generator);
    while(number<0)
        number=distribution(generator);
    if (number>1)
        number =1;
    return number;
}


std::random_device rd;
    int i=15;
    double Crm=0.1, num;
    while (i>0){
        num=Cauchy_1(0.1, rd);
        cout<<num<<endl;
        i--;
    }

Me da diferentes valores, pero los valores son los mismos en una nueva ejecución.

2
Dikzamen 21 dic. 2019 a las 14:52

2 respuestas

La mejor respuesta

Las funciones de la biblioteca estándar como std::shuffle toman un generador de números aleatorios por una referencia de reenvío, no una distribución. Puedes hacer lo mismo:

template<class URBG>
double cauchy_1(double fm, URBG&& gen) {
    std::cauchy_distribution<double> distribution(fm, 0.1);
    double number;
    do 
        number = distribution(gen);
    while (number < 0);
    return std::min(number, 1.0);
}

int main() {
    std::random_device rd;
    std::default_random_engine gen(rd());

    for (int i = 0; i < 10; ++i) {
        auto num = cauchy_1(0.1, gen);
        std::cout << num << std::endl;
    }
}

Todavía tiene el mismo conjunto de números si vuelvo a ejecutar este código.

Este no es el problema de este código, sino el problema de std::random_device. Como se explicó aquí, std::random_device puede implementarse en términos de un motor de números pseudoaleatorio. Las posibles soluciones se pueden encontrar aquí.

Por ejemplo:

std::default_random_engine gen(
    std::chrono::system_clock::now().time_since_epoch().count());
3
Evg 21 dic. 2019 a las 14:37

Inicializa std::default_random_engine generator; con la misma semilla predeterminada. Necesita sembrarlo para obtener diferentes resultados si lo instancia de nuevo. Hay una clase std::random_device que puedes usar para obtener una nueva semilla aleatoria.

Además, std::default_random_engine es una clase lenta para crear instancias / crear, por lo que lo está usando mal.

4
ALX23z 21 dic. 2019 a las 11:59