sobota, 14 maja 2011

Algorytm losujący #1

Podstawowe biblioteki C++ nie oferują zbyt wiele w zakresie generowania losowości – zwłaszcza w kwestii generowania liczb losowych z określonego przez nas przedziału. Mamy co prawda funkcję rand() zdefiniowaną w pliku cstdlib (stdlib.h), jednakże jest ona dość niewygodna do stosowania w niektórych sytuacjach, nie biorąc już nawet pod uwagę zmniejszenia przejrzystości kodu.

Bardzo dobrą praktyką jest napisanie własnej implementacji funkcji losującej dostosowanej do naszych potrzeb. Poniżej przedstawię i opiszę jeden z wielu algorytmów, które bazują na funkcji rand() z biblioteki standardowej.

Schemat blokowy algorytmu


Kod funkcji losującej:

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

using namespace std;

int main()
{
    int min, max, result;
    cout << "Podaj dolna granice przedzialu: ";
    cin >> min;
    cout << "Podaj gorna granice przedzialu: ";
    cin >> max;

    if (max >= min) {
        max -= min;
    } else {
        int tmp = min - max;
        min = max;
        max = tmp;
    }

    srand(time(NULL));

    if (max < 0) {
        result = min;
    } else {
        result = (rand()%max) + min;
    }

    cout << "Wynik: " << result;

    return 0;
}


Jak widać algorytm ten nie jest zbyt skomplikowany. Przyjmuje dwa argumenty: min (minimalna liczba jaką chcemy wylosować) i max (maksymalna liczba jaką chcemy wylosować). Następnie sprawdzane jest, czy maksymalna liczba jest większa lub równa minimalnej. Jest to takie małe zabezpieczenie, w przypadku gdyby ktoś korzystający z tego algorytmu pomylił się podczas kodzenia. Jeśli minimalna liczba jest większa od maksymalnej, ich wartości zostają zamienione miejscami. Dodatkowo w zarówno jednym, jak i drugim wyniku warunku od wartości maksymalnej odejmowana jest minimalna, co daje nam ilość możliwych wylosowanych liczb. Później sprawdzane jest czy owa ilość jest większa od zera, a jeśli nie to ostatecznie funkcja zwraca wartość minimalną (min). W przypadku gdy max jest większe od 0 za pomocą wbudowanej w biblioteki standardowe funkcji rand() losujemy liczbę. Wylosowana liczba podzielona przez ilość możliwych liczb do wylosowania daje resztę, do której dodajemy wartość minimalną. W efekcie otrzymujemy (pseudo)losową wartość z przedziału wprowadzonego na początku działania algorytmu.