Cara terbaik untuk seed N generator nomor acak independen dari 1 nilai

10

Dalam program saya, saya perlu menjalankan N utas terpisah masing-masing dengan RNG mereka sendiri yang digunakan untuk sampel dataset besar. Saya harus dapat menyemai seluruh proses ini dengan nilai tunggal sehingga saya dapat mereproduksi hasil.

Apakah cukup untuk meningkatkan benih secara berurutan untuk setiap indeks?

Saat ini saya menggunakan numpy's RandomStateyang menggunakan Mersenne Twister pseudo-random number generator.

Cuplikan kode di bawah ini:

# If a random number generator seed exists
if self.random_generator_seed:
    # Create a new random number generator for this instance based on its
    # own index
    self.random_generator_seed += instance_index
    self.random_number_generator = RandomState(self.random_generator_seed)

Pada dasarnya saya memulai dengan seed yang dimasukkan pengguna (jika ada) dan untuk setiap instance / utas saya secara berurutan menambahkan indeks (0 hingga N-1) dari instance yang berjalan. Saya tidak tahu apakah ini praktik yang baik atau apakah ada cara yang lebih baik untuk melakukan ini.

EricR
sumber
1
Apakah Anda tahu sebelumnya berapa banyak nilai acak semu yang akan digunakan masing-masing utas - atau setidaknya Anda bisa mendapatkan taksiran batas atas yang baik?
whuber
Tidak, saya tidak bisa. Ini sampel daerah yang dijumlahkan sampai ambang batas itu. Ukuran wilayah dapat sangat bervariasi.
EricR

Jawaban:

9

Ini bukan latihan yang bagus, tentu saja. Sebagai contoh, perhatikan apa yang terjadi ketika Anda melakukan dua run dengan seed root 12345 dan 12346. Setiap run akan memiliki N-1aliran yang sama.

Implementasi Mersenne Twister (termasuk numpy.randomdan random) biasanya menggunakan PRNG yang berbeda untuk memperluas seed integer ke dalam vektor state besar (624 integer 32-bit) yang digunakan MT; ini adalah array dari RandomState.get_state(). Cara yang baik untuk melakukan apa yang Anda inginkan adalah menjalankan PRNG itu, diunggulkan dengan integer input Anda sekali, dan dapatkan N*624integer 32-bit darinya. Pisahkan aliran itu menjadi Nvektor-vektor status dan gunakan RandomState.set_state()untuk menginisialisasi setiap RandomStateinstance secara eksplisit . Anda mungkin harus berkonsultasi dengan sumber C numpy.randomatau _randomdari perpustakaan standar untuk mendapatkan PRNG itu (semuanya sama). Saya tidak yakin apakah ada yang menerapkan versi mandiri dari PRNG untuk Python.

Robert Kern
sumber
Saya pikir ini mungkin solusi terbaik yang pernah saya dengar sejauh ini. Saya tidak berpikir itu penting pada bagaimana saya membagi aliran meskipun benar? Tampaknya jauh lebih tidak mungkin untuk memiliki urutan duplikat pada 624 bilangan bulat 32-bit antara instance tidak peduli bagaimana mereka diambil dari PRNG dan seed awal.
EricR
1
Sebenarnya, saya akan kembali sedikit. Tidak jelas bagi saya bahwa initializer PRNG dirancang untuk memiliki banyak nilai yang diambil darinya. Pertimbangkan menggunakan PRNG kualitas lain (lebih disukai tidak terkait dengan MT) untuk menghasilkan aliran negara. Seseorang dapat mengimplementasikan HMAC-DRBG (PRNG menggunakan HMAC sebagai primitif kriptografi) hanya menggunakan perpustakaan standar yang relatif mudah. Keamanan kriptografi bukan masalah; hanya kemudahan implementasi dan kualitas bitstream. Anda perlu memastikan bahwa tidak ada vektor nol dibuat, pada kesempatan yang sangat langka.
Robert Kern
Atau cukup gunakan salah satu RandomStateimplementasi baru dalam pengembangan yang menggunakan algoritma yang memiliki aliran yang dapat diatur. Artinya, Anda menginisialisasi setiap RandomStateinstance dengan seed yang sama dan ID aliran yang berbeda (hanya bertambah baik-baik saja), dan Anda dijamin aliran independen. pypi.python.org/pypi/randomstate
Robert Kern
4

Φ(u)uN

  1. menghasilkanΦ(u),ΦN(u),Φ2N(u),...
  2. menghasilkanΦ2(u),Φ1+N(u),Φ1+2N(u),...
  3. ...
  4. menghasilkanΦN1(u),ΦN1+N(u),ΦN1+2N(u),...

Φn(u)=Φ(Φn1(u))

Xi'an
sumber
2

Sekarang ada paket Python yang disebut RandomGen yang memiliki metode untuk mencapai ini.

Ini mendukung stream independen yang dibuat dari satu seed, serta protokol lompat untuk generator nomor acak yang lebih lama seperti MT19937.

Praveen
sumber
0

Beberapa orang mengklaim bahwa ada korelasi dalam angka acak yang dihasilkan oleh biji berurutan. /programming/10900852/near-seeds-in-random-number-generation-may-give-similar-random-number Saya tidak yakin seberapa benar itu.

Jika Anda khawatir tentang hal itu, mengapa tidak menggunakan generator nomor acak tunggal untuk memilih benih untuk semua generator lainnya?

Harun
sumber
Hanya karena saya tidak ingin memiliki kesempatan untuk menghasilkan benih yang sama secara acak untuk lebih dari 1 generator. Tentu saja saya bisa melakukan beberapa pekerjaan pemrograman untuk mencegah hal ini terjadi tetapi kemudian saya tidak tahu bagaimana itu akan lebih baik daripada memetik benih secara berurutan di tempat pertama.
EricR
1
Rupanya , korelasi dimungkinkan dengan benih berurutan ... Namun, seperti yang ditunjukkan oleh artikel yang terhubung dalam jawaban dari blog John D Cook, menggunakan satu RNG untuk menghasilkan benih untuk generator lain jauh lebih buruk, karena Anda mengalami masalah ulang tahun! Dikatakan bahwa menghasilkan 1000 biji unsigned 16-bit secara acak memiliki kemungkinan 99,95% tumpang tindih!
Praveen