2012-10-19 14 views
5

Chcę generować 2^30 liczb losowych z zakresu od 0 do 2^10. Słyszałem, że funkcja rand() nie jest odpowiednia dla tych wielu liczb. Czy istnieje inny sposób jej wygenerowania z niemal równą dystrybucją?Generowanie losowej liczby 2^30

+4

Sprawdź w nagłówku '' C++ 11. – chris

+1

I w C++ 03, Boost.Random (skąd pochodzi ""). – GManNickG

+1

Czy nie ma problemu z generowaniem dużych liczb losowych o jednolitym rozkładzie? – andre

Odpowiedz

1

g_random_int() zwraca losowy guint32 równomiernie rozmieszczona w całym zakresie [0..2^32-1].

#include <glib.h> 

int 
main(void) 
{ 
    g_print("%d\n", g_random_int()); 
    return 0; 
} 

z gcc:

gcc -o rand rand.c `pkg-config --cflags --libs glib-2.0` 

Edycja:

odczytu bezpośrednio z/dev/losowy (mniej przenośny), kompilacji jak zwykle:

#include <stdio.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <unistd.h> 

int 
main(void) 
{ 
    int    fd; 
    unsigned int number; 

    fd = open("/dev/random", O_RDONLY); 

    read(fd, &number, sizeof(number)); 

    printf("%u\n", number); 
    close(fd); 
    return 0; 
} 

PS sprawdź błędy.

+0

rand.c to mój plik, w którym zapisałem ten kod? (Przepraszam, mam bardzo mniejszą wiedzę na temat kompilatora) – john

+0

@jhon jeśli chcesz tylko liczb losowych z przedziału od 0 do 2^32, to po prostu odczytaj z/dev/random da ci losowość: P wypróbuj to w swojej powłoce: 'od -An -N4 -tu/dev/random | tr -d '' ' przekierowanie do pliku ' od -An -N4 -tu/dev/random | tr -d ''> file.txt' ale tak; jeśli skopiujesz i wkleisz powyższy kod do pliku o nazwie rand.c, możesz go skompilować po prostu wpisując powyższe polecenie. pamiętaj, że kod jest wymagany, musisz zainstalować glib w swoim systemie. Oczywiście nic z tego nie zadziała, jeśli nie korzystasz z Linuksa. – yeyo

+0

ok dzięki poleceniu powłoki, które mogę wykonać. Ale kiedy zrobiłem to dla pliku rand.c z powyższym poleceniem utknął on z symbolem >>. – john

0

Mark A. Overton miał ładny artykuł o dość proste, ale wysokiej jakości RNGs na Dr. Dobbs w dniu 24 maja 2011

2

W Javie można użyć Losowo który ma powtórzyć po 2^48 wartości.

Random rand = new Random(); 

for(int i = 0; i < (1<<30); i++) { 
    int n = rand.nextInt(1 << 10); 

} 
3

Biblioteka C++ <random> jest doskonałym rozwiązaniem, z wielu wyborów silnika i dystrybucji PRNG.

#include <random> 
#include <cstdint> 
#include <iostream> 

int main() { 
    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937_64 eng(seed); 
    std::uniform_int_distribution<> dist(0, 1<<10); 

    for (std::uint32_t i = 0; i< (1<<30); ++i) { 
     int value = dist(eng); 
     std::cout << value << ' '; 
    } 
} 

Również random_device jest sam silnik, który może, w zależności od implementacji, zapewnić dostęp do niedeterministycznym lub kryptograficznej RNG:

std::random_device eng; 
std::cout << dist(eng) << '\n'; 

Na przykład w libC++ używa/dev/urandom domyślnie, który na OS X używa kryptograficznego algorytmu RNG Yarrow.

+0

jego błąd wyświetlania jako: 'mt19937_64' nie jest członkiem 'std' – john

+0

Jakiego kompilatora/biblioteki i wersji używasz? Być może jeszcze tego nie zaimplementował. Możesz także wypróbować 'std :: mt19937' lub jeden z [predefined generatorów liczb losowych] (http://en.cppreference.com/w/cpp/numeric/random). – bames53

+0

pokazuje wersję gcc 4.6.3 – john

0

w prosty sposób zwiększyć przypadkowość oraz okres:

public class Random2 { 

    private static int LEN = 64; 
    private final int[] buf = new int[LEN]; 
    private Random r; 
    private final int maxInt = 1 << 10; 

    public Random2() { 
     r = new Random(); 
     for (int i = 0; i < LEN; i++) 
      buf[i] = r.nextInt(maxInt); 
    } 

    public int nextInt() { 
     int i = r.nextInt(LEN); 
     int x = buf[i]; 
     buf[i] = r.nextInt(maxInt); 
     return x; 
    } 

} 
1

Oto stary post Usenetu z wieloma interesującymi RNG - wszystko bardzo łatwo zaimplementowane.

http://www.cse.yorku.ca/~oz/marsaglia-rng.html

Oni mogą nie całkiem pasuje Mersenne Twister, ale zrobiłem dobry użytek z kilku z nich, a oni są z pewnością lepsze niż niektóre z domyślnym rand() implementacje. Przekazują one losowe testy DIEHARD, a największy z nich zawiera okres> 2^7700 i zajmuje nie więcej niż kilka linii do zaimplementowania.

Ken

Powiązane problemy