problem z funkcją srand - powtarzające się wyniki rand()

0

Witam,

Na wstępie chciałbym zaznaczyć, że jestem początkującym w świecie C++. Tak naprawdę to uczę się programowania od kilku tygodni. Dlatego proszę o wyrozumiałość.I jestem otwarty na konstruktywną krytykę i wszelkie porady.

Do rzeczy. W ramach nauki postanowiłem napisać kod zawierający kilka podstawowych poleceń.
W skrócie, kod ma zasymulować kilka (ilość podana przez użytkownika) losowych rzutów monetą i zwrócić wynik w postaci informacji "Orzel" albo" Reszka".
Sam mechanizm losujący postanowiłem zawrzeć w funkcji o nazwie ** monety**. Następnie, już w funkcji main, funkcja ta miała zostać powtórzona n razy.
I tu natknąłem się na problem. Gdy funkcję losowości srand wciągnąłem w obszar funkcji ** monety**, to niestety nie uzyskałem losowości. Za każdym powtórzeniem program zwraca mi n identycznych wyników. Poniżej niedziałający kod:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

string monety(int n)
{
    int wynik;
    srand(time(NULL));
    rand();
    wynik=rand()%2;
            if(wynik==0)
            {
                return "Orzel";
            }
            else
            {
                return "Reszka";
            }

}

int main()
{
    int n; // iosc powtorzen
    cout << "Podaj ilość losowan: ";
    cin >> n;
    for(int i=0; i<n; i++)
    {
    cout << monety(n) << endl;
    }
    return 0;
}

Program zaczyna funkcjonować prawidłowo, gdy funkcja srand zostanie wyciągnięta z funkcji monety do funkcji main i wywołana przed wywołaniem funkcji monety. Poniżej działający program:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

string monety(int n)
{
    int wynik;
    wynik=rand()%2;
            if(wynik==0)
            {
                return "Orzel";
            }
            else
            {
                return "Reszka";
            }
}

int main()
{
    srand(time(NULL));
    rand();
    int n; // iosc powtorzen
    cout << "Podaj ilość losowan: ";
    cin >> n;
    for(int i=0; i<n; i++)
    {
    cout << monety(n) << endl;
    }
    return 0;
}

Czy jest mi ktoś z Was w stanie w kilku zdaniach wyjaśnić dlaczego funkcja losowości traci swoja (pseudo :P) losowość w pierwszym kodzie?
Czy zapętlenie funkcji, która zawiera w sobie funkcje losowości powoduje, że z każdym liczba rand() przyjmuje identyczną wartość? Alb wczytywana jest tyllko raz i powielana w każdej iteracji pętli for?

Wybaczcie, jeśli przedstawiłem to chaotycznie. Ale tak jak wspomniałem, jestem praktycznie całkowitym newbie w tym temacie ;)

Pozdrawiam.

PK

0

Seed jest zawsze taki sam chyba, że ustawisz przez srand jak w drugim przypadku. W C++ używa się innych funkcji losowych.

Pzdr.

0

Funkcja rand() działa jakoś tak że losuje liczby na podstawie czasu jaki upłynął od (data której nie pamiętam, coś koło lat 70 chyba), chyba że ustawisz inaczej za pomocą funkcji srand, problem w tym że jak umieścisz srand w funkcji to ta wartość będzie taka sama dla każdej losowanej liczby stąd i wylosowana liczba będzie taka sama.

6

Generalnie nie powinieneś używać pary srand i rand - C++ ma lepsze alternatywy w nagłówku <random>. Przykład użycia tu i tu

Jeśli zaś chodzi o pytanie: mechanizm generowania liczb pseudolosowych, jak nazwa wskazuje, generuje liczby pseudolosowe. Każde wywołanie rand() bierze pod uwagę obecny/ostatni stan1 i na jego podstawie generuje kolejną liczbę. Jak możesz wywnioskować nie jest ona faktycznie losowa (stąd pseudo w nazwie). Za pomocą srand() ustawiasz ten stan początkowy. Dlatego też, jeśli ustawiasz go na tę samą wartość przed każdym losowaniem - otrzymujesz identyczne wyniki.

Na uproszczonym przykładzie, załóżmy, że rand() dokonuje inkrementacji, mnożenia przez 103 a następnie reszty z dzielenia przez 100. T.j.

int stan;
int my_rand()
{
    stan = (stan + 1) * 103 % 100;
    return stan;
}

void my_srand(int wartosc)
{
    stan = wartosc;
}

Dla wartości początkowej 0, kolejne wartości zwrócone przez my_rand() to: 3, 12, 39, 20, 63, 92, 79, 40, 23, 72...

Jeśli za każdym wywołaniem ustawiałbyś wartość początkową na 0, uzyskałbyś 3, 3, 3, 3, 3, 3....

1traktuj to jako zmienną globalną

0
czaffik napisał(a):

Funkcja rand() działa jakoś tak że losuje liczby na podstawie czasu jaki upłynął od (data której nie pamiętam, coś koło lat 70 chyba), chyba że ustawisz inaczej za pomocą funkcji srand, problem w tym że jak umieścisz srand w funkcji to ta wartość będzie taka sama dla każdej losowanej liczby stąd i wylosowana liczba będzie taka sama.

Tak, wszystko to rozumiem :). Tylko zależy mi na zrozumieniu dlaczego umieszczenie funkcji srand wewnątrz mojej funkcji monety powoduje, ze rand() ciagle przyjmuje jednakowa wartosc?!

0

Jeśli liczba pseudolosowa jest ustalana na podstawie czasu jaki upłynął od określonej daty, którą ustawiasz w funkcji srand(), to umieszczenie jej w tej samej funkcji co losowanie liczby poskutkuje tym że dla każdej losowanej liczby czas jaki upłynął będzie taki sam stąd i wartość losowana będzie taka sama, jak umieścisz srand w mainie to czas dla kolejnych wywołań rand() będzie ulegał wydłużeniu i uzyskasz inne wartości.
Swoją drogą zainteresuj się tym: http://www.cplusplus.com/reference/random/ - w c++ masz multum innych silników randomowych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1