Próba wylosowanie wielu liczb z zakresu bez powtórzeń
Ostatnio zmodyfikowano 2016-02-20 18:43
executor1909 Temat założony przez niniejszego użytkownika |
Próba wylosowanie wielu liczb z zakresu bez powtórzeń » 2016-02-20 17:52:21 Mam problem, chciałbym wylosować sporo liczb z przedziału np. <0, 3>. Aby były one nie tylko liczbami całkowitymi zrobiłem coś takiego: void losowanie( double * tablica, double poczatek, double koniec, int ile ) { double zmienna; bool powtorzenie; tablica[ 0 ] = poczatek; tablica[ ile - 1 ] = koniec; for( int i = 1; i < ile - 1; ++i ) { powtorzenie = false; zmienna = static_cast < double >( rand() % static_cast < int >( 10000 *( koniec - poczatek ) ) + static_cast < int >( 10000 * poczatek ) ); zmienna /= 10000.0; for( int j = 0; j < ile; ++j ) { if( zmienna == tablica[ j ] ) powtorzenie = true; } if( powtorzenie == false ) tablica[ i ] = zmienna; else { cout << "Powtorzenie!" << endl; --i; } } }
Na początku myślałem, że z dalszą częścią programu coś jest nie tak, bo raz rozwiązywanie problemu trwało kilka setnych sekundy, a czasem nawet do kilku minut. Jednak potem dodałem "cout << "Powtorzenie!" << endl" ... Kod działa poprawnie, ale niestety przy losowaniu 100 liczb w małych przedziałach trwa to bardzo długo, a linia "Powtórzenie!" wyświetla się non stop. Jest jakiś sposób, żeby szybciej wylosować te liczby? |
|
Monika90 |
» 2016-02-20 18:09:21 Nie wiem po co Ci takie liczby, więc nie wiem jaka metoda będzie najlepsza, ale można np. tak #include <iostream> #include <vector> #include <random> #include <algorithm> #include <ctime>
int main() { const int min = 0; const int max = 3; const int precision = 10000; std::mt19937 rng( std::time( nullptr ) ); std::vector < int > pool(( max - min ) * precision + 1 ); std::iota( pool.begin(), pool.end(), 0 ); std::shuffle( pool.begin(), pool.end(), rng ); for( auto i: pool ) std::cout <<( i + min * precision ) / static_cast < double >( precision ) << ' '; }
W miarę możliwości należy użyć czegoś lepszego niż std::time(nullptr) do inicjalizacji generatora. |
|
executor1909 Temat założony przez niniejszego użytkownika |
» 2016-02-20 18:34:55 Mam bardzo oryginalne zadanie - stworzyć coś w rodzaju wykresu funkcji dla dowolnej funkcji znając jej wzór i przedział, ale bez używania pochodnych, granic, itp. , tylko podstawowe działania ;) Aby był on w miarę dokładny, zamierzam znaleźć jak najwięcej argumentów dla danego przedziału i obliczyć ich wartości, stąd takie liczby.
Dziękuję za odpowiedź! Z chęcią sprawdzę ten sposób. |
|
Monika90 |
» 2016-02-20 18:43:49 Drobna poprawka, tak będzie lepiej #include <iostream> #include <vector> #include <random> #include <algorithm> #include <ctime>
int main() { const int min = 0; const int max = 3; const int precision = 10000; std::mt19937 rng( std::time( nullptr ) ); std::vector < int > pool(( max - min ) * precision + 1 ); std::iota( pool.begin(), pool.end(), min * precision ); std::shuffle( pool.begin(), pool.end(), rng ); for( auto i: pool ) std::cout << i / static_cast < double >( precision ) << ' '; }
|
|
« 1 » |