Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Generator LCG

Ostatnio zmodyfikowano 2013-06-06 15:31
Autor Wiadomość
booyaka
Temat założony przez niniejszego użytkownika
Generator LCG
» 2013-06-03 19:04:27
Witam,

Mam za zadanie napisać program - Generator liczb losowych LCG. Wydaje mi się, że udało mi się go napisać wg zaleceń, ale cały czas zwraca wynik (liczbę losową) równo 0. Nie mogę się doszukać w czym problem, choć obstawiam, że jest dosyć błahy.

C/C++
#include <iostream>
#include <time.h>

using namespace std;

void LCG();

int main()
{
    LCG();
   
   
    getchar();
    return 0;
}


void LCG()
{
    unsigned int n, X_max, m, dzielnik, c;
   
    cout << "Generator Kongruentny LCG" << endl << endl;
   
    // Pobranie zmiennych n, Xmax
    cout << "Podaj zmienna n: ";
    cin >> n;
   
    cout << "Podaj zmienna Xmax: ";
    cin >> X_max;
   
    cout << endl;
   
    // Wyznaczamy moduł m
    m = X_max + 1;
    srand( time( NULL ) );
    c = rand() % X_max;
   
    cout << "zmienna c: " << c << endl;
   
    dzielnik = 2;
    int b = 1;
    cout << "Dzielniki m:" << endl;
   
    while( m > 1 ) {
        while( m % dzielnik == 0 ) {
            cout << dzielnik << " ";
            b = b * dzielnik;
            if( c == dzielnik ) c = rand() % X_max;
           
            m = m / dzielnik;
        }
        dzielnik = dzielnik + 1;
    }
    cout << endl;
    cout << "zmienna c: " << c << endl;
    cout << "zmienna b: " << b << endl;
   
    // Wyznaczamy a
    if( m % 4 == 0 )
    while( b % 4 != 0 )
         b = b * 2;
   
    int a = b + 1;
   
    cout << "zmienna a: " << a << endl << endl;
   
    int x0 = rand() % X_max;
   
    cout << "Losowe ziarno: " << x0 << endl << endl;
   
   
    for( unsigned int i = 0; i < n; ++i )
    {
        x0 =( a * x0 + c ) % m;
        cout << x0 << endl;
    }
   
    getchar();
}
.
P-84745
pekfos
» 2013-06-03 20:48:00
C/C++
while( m > 1 ) {
Po wyjściu z takiej pętli, m będzie miało wartość 1, więc na wyjściu będą zera.
P-84771
booyaka
Temat założony przez niniejszego użytkownika
» 2013-06-03 21:56:26
Dzięki, nie mogłem się tego doszukać.
P-84778
akwes
» 2013-06-04 18:37:38
Jeszcze tylko dodam (ku przestrodze przyszłym czytaczom tematu), że linijka
srand( time( NULL ) );
 nie powinna być w funkcji (tak jak tutaj) ani w pętli. Teraz nie objawia się to problemem, ponieważ funkcja jest wywoływana tylko raz, ale przy wielokrotnym wywołaniu funkcji, będzie to działać niezgodnie z oczekiwaniami.
P-84837
booyaka
Temat założony przez niniejszego użytkownika
» 2013-06-05 21:45:14
akwes czyli wstawić ją poza funkcją?

Mam jeszcze jeden problem, podczas zwalniania pamięci otrzymuje błąd "heap corruption detected after normal block". W czym problem? Jak poprawnie zwolnić pamięć po tablicy?

C/C++
#include <iostream>
#include <time.h>

using namespace std;

unsigned int * tab;
//unsigned int tab[10] = {29, 8, 19, 83, 72, 9, 15, 62, 11, 25};
unsigned int i = 0;
unsigned int m, s, r;

void menu();
void MLCG();
void LCG( unsigned int *& tab );
void ALFG( unsigned int & m, unsigned int & s, unsigned int & r );
void ZwolnijPamiec();

int main()
{
   
    menu();
    ZwolnijPamiec();
   
    getchar();
    return 0;
};


void LCG( unsigned int *& tab )
{
    unsigned int n, X_max, m, zmienna, dzielnik, c;
   
    cout << "Generator Kongruentny LCG" << endl << endl;
   
    // Pobranie zmiennych n, Xmax
    cout << "Podaj zmienna n: ";
    cin >> n;
   
    cout << "Podaj zmienna Xmax: ";
    cin >> X_max;
   
    tab = new unsigned int[ n - 1 ];
    cout << endl;
   
    // Wyznaczamy moduł m
    zmienna = m = X_max + 1;
    srand( time( NULL ) );
   
    // Wyznaczenie zmiennej c
    c = rand() % X_max;
   
    // Podział m na czynniki i sprawdzenie czy c nie jest równe któremuś z nich
    dzielnik = 2;
    cout << "Dzielniki m:" << endl;
    while( zmienna > 1 ) {
        while( zmienna % dzielnik == 0 ) {
            cout << dzielnik << " ";
            while( c == dzielnik )
                 c = rand() % X_max;
           
            zmienna = zmienna / dzielnik;
        }
        dzielnik = dzielnik + 1;
    }
    cout << endl;
    cout << "zmienna c: " << c << endl;
   
    // Wyznaczamy a
    if( m % 4 == 0 )
    while( m % 4 != 0 )
         m = m * 2;
   
    int a = m + 1;
   
    cout << "zmienna a: " << a << endl;
    cout << "zmienna m: " << m << endl;
   
    //Losujemy losowe ziarno
    int x0 = rand() % X_max;
   
    cout << "Losowe ziarno: " << x0 << endl << endl;
   
    for( unsigned int i = 0; i < n; ++i )
    {
        x0 =( a * x0 + c ) % m;
        cout << x0 << endl;
        tab[ i ] = x0;
    }
    getchar();
}
void MLCG()
{
    unsigned int n, X_max, m;
   
    cout << "Generator Kongruentny MLCG" << endl << endl;
   
    // Pobranie zmiennych n, Xmax
    cout << "Podaj zmienna n: ";
    cin >> n;
   
    cout << "Podaj zmienna Xmax: ";
    cin >> X_max;
   
    cout << endl;
   
    // Wyznaczamy moduł m
    m = X_max + 1;
    srand( time( NULL ) );
   
    // Wyznaczamy a
    if( m % 4 == 0 )
    while( m % 4 != 0 )
         m = m * 2;
   
    int a = m + 1;
   
    cout << "zmienna a: " << a << endl;
    cout << "zmienna m: " << m << endl;
   
    //Losujemy losowe ziarno
    int x0 = rand() % X_max;
   
    cout << "Losowe ziarno: " << x0 << endl << endl;
   
    for( unsigned int i = 0; i < n; ++i )
    {
        x0 =( a * x0 ) % m;
        cout << x0 << endl;
    }
   
    getchar();
}
unsigned long long LFG( int s, int r, int m )
{
    // Instrukcje generujace losowe liczby Fibonnacciego
    unsigned long long temp =( tab[ i ] + tab[( r + i - s ) % r ] ) % m;
    tab[ i ] = temp;
    i =( i + 1 ) % r;
    return temp;
}
void ALFG( unsigned int & m, unsigned int & s, unsigned int & r )
{
    cout << "Wypelniamy tablice losowymi liczbami wykorzystujac LCG" << endl;
    LCG( tab );
    unsigned int n;
   
    cout << "Ile liczb wygenerowac: ";
    cin >> n;
    cout << endl;
    cout << "Podaj wartosc wspolczynnika m: ";
    cin >> m;
    cout << endl;
    cout << "Podaj wartosc wspolczynnika s: ";
    cin >> s;
    cout << endl;
    cout << "Podaj wartosc wspolczynnika r: ";
    cin >> r;
    cout << endl;
   
    // Wypisujemy n liczb
    for( int i = 0; i < n; i++ )
    {
        unsigned long long temp = LFG( s, r, m );
        cout << temp << "  ";
    };
    getchar();
}
void ZwolnijPamiec()
{
    delete[] tab;
}
void menu()
{
    int x = 5;
    while( x != 0 )
    {
        cout << "*******************MENU********************" << endl;
        cout << "1.Generator LCG" << endl;
        cout << "2.Generator MLCG" << endl;
        cout << "3.Generator Fibonnacci'ego" << endl;
        cout << "0. Wyjscie" << endl;
        cout << "Wybieram : ";
        cin >> x;
        system( "cls" );
       
       
        switch( x )
        {
        case 1:
            LCG( tab );
            getchar();
            system( "cls" );
            break;
        case 2:
            MLCG();
            getchar();
            system( "cls" );
            break;
        case 3:
            ALFG( m, s, r );
            getchar();
            system( "cls" );
            break;
        }
    }
}


P-85003
usmiech
» 2013-06-06 00:23:21
Dlaczego wg Ciebie akwes srand(time(NULL)) nie moze byc w funkcji ?
Moge napisac program , ktory bedzie mial to srand w funkcji i bedzie oki.. moge zmienic program booyaka tak, ze srand nadal bedzie w funkcji i wszystko bedzie oki.. ale wtedy znowu dostane za , albo pisanie nie na temat, albo dawanie gotowcow ;-)
P-85027
killjoy
» 2013-06-06 00:26:54
Bo jak będziesz szybko wywoływał rand() (pare razy w ciągu sec) to będziesz miał te same wyniki.
P-85028
usmiech
» 2013-06-06 00:28:36
Moze tak, a moze nie... zalezy jak to napiszesz :-)
Nie tak dawno temu pisalem jakis program i wlasnie umiescilem srand w funkcji.. no eksperyment ..i bylo wszystko oki :-)
Jednak nie zmienilo to mojego przyzwyczajenia, wole umieszczac srand w main... :)

ps.

Jesli znacie angielski to polecam ksiazke .. C++ Programming: Program Design Including Data Structures D.S. Malik
P-85029
« 1 » 2
  Strona 1 z 2 Następna strona