2016-06-21 77 views
0

我正在使用和重複使用rand()重新生成的大量序列。爲了獲得不同的序列,我使用srand()與不同但已知的種子。生成可重現的大量序列 - 使用僞隨機生成器?

這種方法的便攜性如何?這將工作在不同版本的libc和編譯器和CPU的不同平臺上嗎?

是否有更安全的替代方法?

只是爲了澄清:對於加密使用,這是而不是

+0

對於c和更舊的C++的,這似乎是要走的路,對於c + + 11和以上,請參閱http://stackoverflow.com/questions/25644465/fix-seed-globaly-in- c11-random – stefaanv

+0

並檢查這一個:http://stackoverflow.com/a/23032503/2703418 – bzeaman

+0

「要獲得**不同的**序列我使用srand()與**着名的種子**。」 - 恩,你確實看到了矛盾,你呢? – Olaf

回答

4

您可以保證在特定實現中獲得特定種子的相同數字序列。您不能保證在不同實現中獲得特定種子的相同序列。

如果你所關心的是該序列是可重複的,那麼你很好。如果你關心的是實現中的序列是相同的,那麼你就不是。

3

該方法存在多種缺陷。

  • 它使您的應用程序天生就是單線程的。

  • C標準沒有指定rand的算法,所以它在平臺和編譯器之間可能會有所不同。

  • 任何外部(例如,GUI)代碼都可能會意外地調用rand,導致序列無效。在C++中,它變得更糟。 Read Compatibility section

  • 標準rand函數通常被認爲不是很好。

對於C++,可以考慮使用的東西從<random>頭,尤其是一些Mersenne Twister變種。

對於C,您應該尋找一些實現MT或其他良好PRNG的庫。

如果你想自己實現它,Java Random既適合大多數情況下,也易於實現。

0

見C++ 14標準,26.8.5:C庫[c.math]

[...] [注:在本標準中的隨機數生成(26.5)設施通常比rand更好,因爲rand的底層算法是未指定的。因此使用蘭特繼續 是不可移植的,具有不可預知的和質疑和質量問題的性能。 - 尾註]

因此,標準清楚地指出,使用rand不是便攜式的。標題爲隨機數發生器提供了一系列不同的模板,每個算法都是口授的,因此是便攜式的。然後由您來選擇......所有但std::default_random_engine,這是留給實現再次選擇(26.5.5,[10]:

備註:此類型定義命名的發動機類型的選擇是實現定義[... ]