W małej aplikacji napisanej w C / C ++ mam problem z rand
funkcją i być może zalążkiem:
Chcę utworzyć sekwencję liczb losowych, które mają różne rzędy, tj. Mają różne wartości logarytmu (podstawa 2). Wydaje się jednak, że wszystkie uzyskane liczby są tego samego rzędu, wahając się między 2 ^ 25 a 2 ^ 30.
Czy to dlatego, że rand()
jest zasiane czasem uniksowym, który jest obecnie stosunkowo dużą liczbą? O czym ja zapominam? Rozsiewam rand()
tylko raz na początku main()
.
rand()
się zwrócić równomiernie rozłożone liczby (dokumentacja z wysokim rankingiem Google wyraźnie tak mówi), nie sądzę, aby to pytanie było przydatne dla przyszłych czytelników. Dlatego głosuj negatywnie, ale nie zniechęcaj się do używania SO.Odpowiedzi:
Jest tylko 3% liczb od 1 do 2 30, które NIE są między 2 25 a 2 30 . Więc to brzmi całkiem normalnie :)
Ponieważ 2 25 /2 30 = 2 -5 = 1/32 = 0,03125 = 3,125%
źródło
>>
przesunięcie bitów - to da ci mniejsze liczby. (Lub biorąc moduł z%
.)0
- i jeśli każdy bit jest przypadkowy ...Jaśniejszy zielony to region między 0 a 2 25 ; ciemniejsza zieleń to obszar między 2 25 a 2 30 . Tiki mają moc 2.
źródło
Musisz być bardziej precyzyjny: chcesz różnych wartości logarytmu o podstawie 2, ale jaki rozkład chcesz dla tego? Standardowe funkcje rand () generują równomierną dystrybucję, będziesz musiał przekształcić te dane wyjściowe za pomocą funkcji kwantyli związanej z żądaną dystrybucją.
Jeśli podasz nam dystrybucję, możemy Ci powiedzieć, jakiej
quantile
funkcji potrzebujesz.źródło
Jeśli chcesz różnych rzędów wielkości, dlaczego po prostu nie spróbować
pow(2, rand())
? A może wybierz kolejność bezpośrednio jako rand (), jak zasugerował Harold?źródło
rand()
może wzrosnąć doRAND_MAX
, naprawdę musisz przeskalować liczbę losową, aby wynik się nie przepełnił ...@ C4stor zrobił świetną uwagę. Ale dla bardziej ogólnego przypadku i łatwiejszego do zrozumienia dla człowieka (podstawa 10): dla zakresu od 1 do 10 ^ n ~ 90% liczb mieści się w przedziale od 10 ^ (n-1) do 10 ^ n, zatem ~ 99% liczb waha się od 10 ^ (n-2) do 10 ^ n. Dodawaj tyle miejsc po przecinku, ile chcesz.
Zabawna matematyka, jeśli będziesz to robić dla n, zobaczysz, że od 1 do 10 ^ n, 99,9999 ...% = 100% liczb to od 10 ^ 0 do 10 ^ n tą metodą.
Teraz o kodzie, jeśli chcesz losową liczbę o losowych rzędach wielkości, od 0 do 10 ^ n, możesz zrobić:
Wygeneruj małą liczbę losową od 0 do n
Jeśli znasz zakres, który ma n, wygeneruj dużą liczbę losową rzędu 10 ^ k, gdzie k> max {n}.
Wytnij dłuższą liczbę losową, aby uzyskać n cyfr tej dużej liczby losowej.
źródło
Podstawowa (i poprawna) odpowiedź została już podana i zaakceptowana powyżej: jest 10 liczb od 0 do 9, 90 liczb od 10 do 99, 900 od 100 do 999 itd.
Aby uzyskać wydajny obliczeniowo sposób uzyskania rozkładu o rozkładzie w przybliżeniu logarytmicznym, należy przesunąć w prawo liczbę losową o liczbę losową:
Nie jest doskonały, ale jest znacznie szybszy niż komputer
pow(2, rand()*scalefactor)
. Będzie „grudkowaty” w tym sensie, że rozkład będzie jednorodny dla liczb w ramach współczynnika 2 (jednolity dla 128 do 255, połowa gęstości dla 256 do 1023 itd.).Oto histogram częstotliwości liczb od 0 do 31 (w próbkach 1M):
źródło
rand()>>(rand()&31);
intuicyjnie można by oczekiwać, że 1/32 liczby będzie miała 32 bity, a 1/32 liczby miała 31 bitów, a 1/32 liczby miała 30 bitów itd. nie wyniki, które otrzymujesz, tylko około 1/64 liczby daje 32 bity, podczas gdy prawie połowa powinna wynosić 0. Ponieważ moja psychiczna matematyka nie zgadza się z twoimi pomiarami, będę musiał wykonać własne pomiary, aby obliczyć to na zewnątrz.Jest dokładnie taka sama liczba liczb od 0 do 2 ^ 29 i 2 ^ 29 i 2 ^ 30.
Inny sposób spojrzenia na problem: rozważ binarną reprezentację generowanej liczby losowej, prawdopodobieństwo, że najwyższy bit to 1, równa się 1/2, a zatem otrzymujesz rząd 29 w połowie przypadków. Chcesz zobaczyć liczbę, która byłaby poniżej 2 ^ 25, ale to oznacza, że 5 najwyższych bitów to zero, co zdarza się z niskim prawdopodobieństwem 1/32. Są szanse, że nawet jeśli uruchomisz go przez długi czas, w ogóle nie zobaczysz zamówienia poniżej 15 (prawdopodobieństwo jest takie, jak wyrzucenie 6 6 razy z rzędu).
A teraz część twojego pytania o ziarno. Nie, ziarno prawdopodobnie nie może określić zakresu, z którego generowane są liczby, po prostu określa pierwszy, początkowy element. Pomyśl o rand () jako sekwencji wszystkich możliwych liczb w zakresie (z góry określona permutacja). Ziarno określa, gdzie zaczniesz rysować liczby z sekwencji. Dlatego jeśli chcesz (pseudo) losowości, do inicjalizacji sekwencji używasz bieżącego czasu: nie obchodzi cię, że pozycja, od której zaczynasz, nie jest równomiernie rozłożona, liczy się tylko to, że nigdy nie zaczynasz z tej samej pozycji.
źródło
jego użycie
pow(2,rand())
da odpowiedzi w kolejności pożądanej wielkości !!źródło
Jeśli chcesz użyć liczb losowych z usługi online, możesz użyć do tego wget, możesz również zobaczyć, że możesz również użyć usług takich jak random.org do generowania liczb losowych, możesz je złapać za pomocą wget, a następnie odczytać liczby z pobrany plik
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html
źródło