Spiegazione su seed_seq

di il
12 risposte

Spiegazione su seed_seq

Salve a tutti

std::random_device r;
    std::mt19937 gen(r());
    std::uniform_int_distribution<int> dist(1, 90);
   std::cout << dist(gen) << " "; // qui estraggo un numero pseudo casuale
    std::string str;
    std::cout << "inserisci seme: ";
    std::cin >> str;
    std::seed_seq seed1(str.begin(), str.end()); // qui fisso il seme ad un valore specifico accettato da console.
   std::cout << dist(gen) << " "; // qui estraggo un numero pseudo casuale 
   

adesso mi chiedevo 

  1. se volessi mettere in una variabile il risultato di dist(gen) che ti variabile devo usare?
  2. volendo resettare il seme con il valore di dist(gen) per un estrazione successiva il valore restituito lo devo mettere in str o in str.begin?
  3. mi potreste spiegare come aggisce la dist(gen) e la seed_seq 

grazie per le risposte che mi darete

12 Risposte

  • Re: Spiegazione su seed_seq

    Hai visto il template

    uniform_int_distribution<int>

    ?

    Quindi restituisce un int e la variabile sarà una int.

    La seconda domanda non si capisce, per la terza esiste molta documentazione online.

  • Re: Spiegazione su seed_seq

    https://cplusplus.com/reference/random/ 

    Basta leggere la documentazione!

    Poi non si capisce perche' dovresti usare una stringa! Che centra la stringa?

    Conosci la differenza tra

    auto x = "123";

    e

    auto x = 123;

    ?

  • Re: Spiegazione su seed_seq

    In effetti cosa c'entra la stringa?

    E poi pensi che ci sia una relazione tra seed_seq e il resto del tuo codice?

  • Re: Spiegazione su seed_seq

    09/04/2024 - oregon ha scritto:


    In effetti cosa c'entra la stringa?

    E poi pensi che ci sia una relazione tra seed_seq e il resto del tuo codice?

    la stringa stava nell esempio che ho preso è modificato 

    https://cplusplus.com/reference/random/mersenne_twister_engine/seed/ 

    09/04/2024 - migliorabile ha scritto:


    https://cplusplus.com/reference/random/ 

    Basta leggere la documentazione!

    Poi non si capisce perche' dovresti usare una stringa! Che centra la stringa?

    Conosci la differenza tra

    auto x = "123";

    e

    auto x = 123;

    ?

  • Re: Spiegazione su seed_seq

    La stringa allora come sequenza di caratteri, quindi di bit.

    Ma il seed generato va usato DOPO in 

    std::mt19937 gen(seed1);
  • Re: Spiegazione su seed_seq

    Grazie 

      //* quindi diventa 
        int a;
        std::mt19937 gen(seed1);
        a=dist(gen); // qui estraggo un numero pseudo casuale
       std::cout << a << " ";  

    a questo punto dove devo andare andare a mettere il valore estratto al fine di richiamare la seed_seq  per cambiarlo?

  • Re: Spiegazione su seed_seq

    Non capisco che intendi

  • Re: Spiegazione su seed_seq

    Allora la mia idea era questa:

    fare un ciclo dove ad ogni estrazione cambiavo il seme di generazione.

    il primo seme era quello standard della funzione

    adesso siccome la seed_seq ha bisogno di una stringa “std::seed_seq seed1(str.begin(), str.end())”

    mi chiedevo il numero che ho estratto, una volta convertito in stringa, per farlo diventare seme dove lo devo copiare?

    poi ho notato che “std::mt19937 gen(seed1);” all'interno di un ciclo mi da problemi di duplicazione come posso risolvere?

  • Re: Spiegazione su seed_seq

    10/04/2024 - smalldragon ha scritto:


    fare un ciclo dove ad ogni estrazione cambiavo il seme di generazione.

    Perche'? A che ti serve?

    10/04/2024 - smalldragon ha scritto:


    il primo seme era quello standard della funzione

    il primo seme dovrebbe essere 0 (zero) se ricordo bene

    10/04/2024 - smalldragon ha scritto:


    adesso siccome la seed_seq ha bisogno di una stringa “std::seed_seq seed1(str.begin(), str.end())”

    Dove c'e' scritto che ha bisogno di una “”stringa""?   STUDIA BENE la documentazione, se no rischi di fare pasticci.

    Che ci vuoi fare con la seed_seq????

    10/04/2024 - smalldragon ha scritto:


    mi chiedevo il numero che ho estratto, una volta convertito in stringa, per farlo diventare seme dove lo devo copiare?

    Ma che cosa stai cercando di fare? PERCHE" converti il numero in stringa? Perche' vuoi convertire una stringa in seme quando hai gia il numero che puoi usare come seme?

    10/04/2024 - smalldragon ha scritto:


    poi ho notato che “std::mt19937 gen(seed1);” all'interno di un ciclo mi da problemi di duplicazione come posso risolvere?

    Che stai a di'?

    Che cosa intendi per “duplicazione”?


    Stai usando la libreria per la generazione di numeri casuali in un modo che ha senso SOLO per te, 
    MA che NON HA SENSO per come dovrebbe essere usate “normalmente”.

  • Re: Spiegazione su seed_seq

    "perchè a che serve" da quanto so io ogni seme fa generare una sequenza di numeri pseudocasuali alla molto lunga prevedibile quindi cambiando ogni volta il seme penso che sia imprevedibile anche alla molto lunga.

    // prova con mersenne_twister del calcolo delle convergenze casuali
    #include <iostream>
    #include <random>
    //using namespace std;
    int main()
    {
        std::random_device r;
        std::mt19937 gen(r());
        std::uniform_int_distribution<int> dist(1, 90);
        std::cout << "distribuzione intera uniforme con seme standard\n";
        for (int indy=0; indy<6;indy++)
        {
            std::cout << dist(gen) << " ";
        }
        int a = 0;
        std::cout << "---------------------------------------------------\n";
        std::string str;
        std::cout << "inserisci seme: ";
        std::cin >> str;
        std::seed_seq seed1(str.begin(), str.end());
        std::mt19937 gen(seed1); // qui mi da errore di definizione multipla
        std::cout << "distribuzione con seme impostato dall'utente\n";
        for (int indy = 0; indy < 6; indy++)
        {
            a = dist(gen);
            std::cout << a << "\n";
        }
        std::cout << "---------------------------------------------------\n";
        std::cout << "distribuzione con seme mutevole partenza con l'ultimo numero estratto\n";
        for (int indy = 0; indy < 6; indy++)
        {
        std::seed_seq seed2(a,0);
        std::mt19937 pen(seed1);
        a = dist(pen);
        std::cout << a << "\n";
        }
    }

    quando lo vado a compilare dopo aver risolto l'errore di definizione multipla lo risolvo mettendo un altro nome alla 2 riga std::mt19937

    mi da errore di riferimento indiretto C2100 presumo che stia nella seed_seq

    se come parametro metto solo la variabile intera alla seed_seq del ciclo

    mi da come errore E0289 "nessuna istanza del costruttore “std::seed_seq::seed_seq” corrisponde all'elenco di Argomenti

    e

    C2665 “std::seed_seq::seed_seq” nessuno dei 2 overload potrebbe convertire tutti i tipi di argomenti

    ecco perchè pensavo che la funzione seed_seq accettasse come parametri un tipo string

    come posso risolvere?

  • Re: Spiegazione su seed_seq

    Alla molto lunga è più lunga di quanto pensi. In ogni caso, se vuoi un generatore personalizzato che conosci solo tu, anche in combinazione con uno di quelli noti, teoricamente si può fare ma solo se hai la certezza di non aver alterato l'uniformità   della distribuzione. Se non ne hai la certezza, usa uno dei generatori già studiati e disponibili con il time() per il primo seed e buonanotte

  • Re: Spiegazione su seed_seq

    @smalldragon, e' vero che il seed permette di generare una sequenza di numeri pseudocasuali PREVEDIBILE, MA bisogna conoscere il seed! 

    Inoltre la lunghezza della sequenza NON E' 10 o 20 elementi, ma, in base al l'algoritmo, si va da 2^32-1 (QUATTRO MILIARDI di valori e spiccioli) a 2^19937-1 (alias 10^6001 - SEIMILA E UNO - e spiccioli) direi che ti basta per qualche MILIARDO d'anni.  

    E' la stessa logica della crittografia: puoi decifrare facilmente un testo SE conosci la chiave, altrimenti col piffero che lo decodifichi. 

    Quindi, tutto quello che serve e' usare un seed che non sia facilmente prevedibile. E di metodi c'e'ne sono n-mila ed INFINITAMENTE piu' semplici del tuo approccio. Il piu' banale e' usare l'orologio di sistema.

    Un'altro e usare il generatore di numeri CASUALI hardware della CPU (proprio CASUALI, NON pseudocasuali) , come fatto nel codice che hai postato. 

    STUDIA MEGLIO l'argomento perche' stai cercando di risolvere un problema che NON ESISTE. 

Devi accedere o registrarti per scrivere nel forum
12 risposte