C ++ üzerinde rastgele sayılar


12

Son zamanlarda, genellikle Mersenne Twister olan bir stok iyi rasgele jeneratör içeren modern dillere alıştım; Şimdi C ++ 'a döndüğümde ne kullanacağım konusunda karar vermeliyim.

Mersenne Twister uygulamalarını araştırdım ve çok fazla şey olduğunu fark ettim: daha çok kullanılan ve yaygın olan bir tane var mı yoksa hepsinin eşit derecede iyi olduğunu varsayarak birini seçmem gerekiyor mu?


1
C ++ ve modern dilleri ayırmanızı seviyorum.
jcora

2
Belki "daha yüksek seviye" demek daha uygundur.
o0 '.

Bence bu soru stackoverflow'a ait
TravisG 18:12

5
SO'da farklı bir cevap verirdim, çünkü tıbbi terapiler için Monte Carlo simülasyonlarının aksine bir oyun motoru için olduğunu bilmezdim, bu durumda 624 rastgele boyutun olmaması ölümcül olabilir.

Yanıtlar:


19

C ++ 11, yeni <random>arayüzünün bir parçası olarak varsayılan olarak Mersenne Twister jeneratörünü içerir . Örneğin, MT kullanarak [-10, 10] arasında eşit bir şekilde tamsayılar oluşturmak için:

std::mt19937 eng; // This is the Mersenne Twister
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

Bunların çoğu, TR1 sunan herhangi bir derleyicide de kullanılabilir, ancak adlar biraz farklıdır; std::tr1::mt19937ve std::tr1::uniform_int<int>.

Ben genellikle insanları Mersenne Twister kullanmamaları konusunda uyarıyorum. Bu iyi bir algoritma ama popülerliğinin çoğu sadece pazarlama. Rastgele boyutun 624 boyutu çoğu insanın ihtiyacından daha fazladır ve MT nispeten ağır durum gereksinimlerini taşır ve tam bir tablo yeniden hesaplaması yaptığında önbelleği patlatabilir. Ben şahsen küçük bir bellek ve CPU gereksinimleri ile bir oyunun ihtiyacı olan her şey için mükemmel dönemler ve makul dağılımlar veren xorshift'e kısmi davranıyorum .

Bir (çoğunlukla?) C ++ 11 uyumlu xorshift oluşturucu - xorshift.hpp , xorshift.cpp - yazdım ve kamu malı olarak yerleştirdim. Bunu yukarıdaki gibi herhangi bir C ++ 11 rastgele fonksiyonuna takabilirsiniz:

xorshift eng;
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

5
Evet, aradığım cevap budur, bu yüzden burada gamedev'de yayınladım:)
o0 '.

1
Bağladığınız dosyalardaki hiçbir şeyin, bunların kamu malı olduğunu göstermediğini not etmek istedim. Telif hakkı yasasının işleyiş şekli, varsayılan olarak "tüm haklar rezervi" ni kabul ettiğinden, bununla ilgili net bir not olmalıdır. Aslında, sadece MIT veya BSD 2 yan tümcesi lisansı gibi bir şeyi kullanmak daha güvenlidir, çünkü bazı yargı bölgeleri temelde "bu kamu malıdır" yasal olarak bağlayıcı olduğunu kabul etmez. İnsanların kodunuzu kullandığını görmek istiyorsanız, bununla ilgilenmeye değer olabilir.
Sean Middleditch

1
@seanmiddleditch: Burada tam olarak açıkım. MIT tarzı bir lisans altında olmasını istiyorsanız, SQLite'ın öncülüğünü izleyeceğim ve size sadece 1000 $ vereceğim.

Kodda bir şey (SQLite yaptığı, iirc) bildiren bir üstbilgi ana sorun olmaması. Umurumda değilse, bu harika. Sadece size samimi bir öneri veriyordu.
Sean Middleditch

1

Daha önce gamedev amaçları için kullandığım bir başka RNG, burada açıklanan Bob Jenkins'in "küçük" RNG'si .

(Ayrıca ISAAC adlı kriptografik güce sahip bir RNG var, ancak daha büyük ve daha yavaş ve oyunların bu güce ihtiyacı yok.)


1
Bu, xorshift'ten daha pahalı görünüyor (4 ekleme, 4 ekleme, 6 kaydırma, 2 ors ve bir xor), daha kötü bir süreye sahip ve belirli başlatmalarla çok kısa döngü riski taşıyor. Hızlı görünüyor ama en hızlı değil; tamam dönemi ama hiçbir yere yakın optimal; xorshift ile aynı temel dağıtım nitelikleri; Kullanmak için herhangi bir neden göremiyorum.

Yeterince adil. Dağıtım ve döngü özelliklerine girmek için RNG analizi hakkında yeterli bilgim yok.
Nathan Reed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.