2010-06-17 40 views
9

Jak utworzyć funkcję, która przy każdym wywołaniu generuje losową liczbę całkowitą? Ta liczba musi być jak najbardziej losowa (zgodnie z uniform distribution). Dopuszczalne jest użycie tylko jednej zmiennej statycznej i co najwyżej 3 podstawowe etapy, przy czym każdy etap obejmuje tylko jeden podstawowych operacji arytmetycznych arity 1 lub 2.Specjalny prosty generator liczb losowych

Przykład:

int myrandom(void){ 
    static int x; 
    x = some_step1; 
    x = some_step2; 
    x = some_step3; 
    return x; 
} 

Podstawowe operacje arytmetyczne + , -,% i, nie, xor lub, lewe przesunięcie, prawe przesunięcie, mnożenie i dzielenie. Oczywiście żadna z rand(), random() lub podobnych rzeczy nie jest dozwolona.

+0

No 'time()' lub wyzwalania funkcji? – FrustratedWithFormsDesigner

+0

nie, nie ma żadnej funkcji zewnętrznej – psihodelia

+18

To jest bezwartościowe pytanie-wywiad. Prosi o coś, co znasz (lub może wiesz, lub po prostu przeczytałeś w czasopiśmie), a nie o czymś, co możesz (lub możesz odliczyć lub wyjaśnić). – Patrick

Odpowiedz

34

liniowy przystający Generator rzecz jest jednym z najstarszych i najprostszych metod:

int seed = 123456789; 

int rand() 
{ 
    seed = (a * seed + c) % m; 
    return seed; 
} 

Ony nieliczne wskazówki z podstawowych operacji arytmetycznych, to co potrzebne.

pamiętać, że ten algorytm działa dobrze tylko jeśli a, c i m wybierane są w sposób szczególny!

Aby zapewnić możliwie najdłuższy okres sekwencji C i m powinna być względnie pierwsze, A-1 powinna być podzielna przez czynniki-m a także do 4 jeżeli m jest podzielna przez 4.

niektórych przykładach wartości przedstawiono w Wikipedia: np ANSI C dla niektórych kompilatorów proponuje m = 2^32, a = 1103515245 i c = 12345

+0

Warto zauważyć, że 'm = 2^32' nie działa w powyższym kodzie ... dla takiej wartości operacja'% m' może być usunięta (i to jest właśnie powód jej wyboru). –

+0

Nie podano nasion. – psihodelia

+2

@psihodelia - co to jest "int seed = 123456789;" następnie? – KevinDTimm

3

Możesz rzucić okiem na this. To daleki od bycia "idealnym" generatorem liczb losowych, ale spełnia moje wymagania, o ile widzę.

Here można znaleźć dodatkowe informacje na temat generowania liczb losowych.

0

Funkcja Boost ma bardzo ładną bibliotekę liczb losowych, a kod źródłowy jest dostępny, więc możesz spróbować sprawdzić i zastosować to, czego potrzebujesz (np. Wyciąć i wkleić).

-3

Oto funkcja o rozkładzie równomiernym w całym zakresie int:

int rand() 
{ 
    static int random = 0; 
    return random++; 
} 
+0

Jednak nie do końca losowy. = P Chociaż przypuszczam, że jest dokładnie tak samo losowy jak jakikolwiek inny generator psuedorandom. –

+4

nie losowe: łatwo można rozpoznać, w jaki sposób jest produkowany (zasada produkcji), więc to kwalifikuje go jako nie losowy (i bardzo zły pseudolos). – ShinTakezou

+0

produkuje wszystkie wyjścia z równym prawdopodobieństwem = losowe –

0

Jeśli piszę man rand, mogę czytać możliwy przykład, podany w POSIX.1-2001, za wdrożenie rand() i srand(). Zobacz np. here. Jeśli potrzebujesz czegoś bardziej wyrafinowanego, spójrz na GNU Scientific Library; możesz oczywiście pobrać kod i zobaczyć implementacje.

-3

Używam tego

SUBROUTINE GNA(iiseed) 
    USE Variaveis 
    parameter (ia=843314861,ib=453816693,m=1073741824, r231=1./2147483648.) 
    INTEGER :: iiseed 

    iiseed = ib + ia*iiseed 
    if (iiseed.lt.0) iiseed = (iiseed+m) + m 
    RndNum = iiseed*r231 

END SUBROUTINE GNA 

Duży zysk losowości można osiągnąć bez spędzać więcej czasu obliczeniowego stworzenie generatora liczb losowych dla każdego połączenia generatora liczb losowych wykonany w programie.

To jest bardzo dobra sztuczka!

7
public long randomLong() { 
    x ^= (x << 21); 
    x ^= (x >>> 35); 
    x ^= (x << 4); 
    return x; 
} 

ziarno nie może być 0. Źródło: http://www.javamex.com/tutorials/random_numbers/xorshift.shtml#.VlcaYzKwEV8

Dodatkowe informacje w wiki: https://en.wikipedia.org/wiki/Xorshift

+0

gdzie jest "losowość" w tym rozwiązaniu? –

+0

"Losowość" jest w operacji XOR przerzucanie przesuniętych bitów "losowo" :). W tym celu potrzebujemy co najmniej jednego zestawu bitów, dlatego nasiona nie mogą być zerowe. – misioptysio

+0

... a tego typu rozwiązanie wydaje się tańsze pod względem cykli procesora: bez mnożenia, bez dzielenia - może być przydatne do intensywnego generowania. – misioptysio

Powiązane problemy