簡體   English   中英

我的PRNG實現與我要復制的實現有何不同?

[英]How does my PRNG implementation differ from the one I'm trying to copy?

我需要一個PRNG來進行仿真項目,並且找到了一個資源 ,鑒於我對PRNG的了解有限但並非根本不存在,因此該資源似乎是合理且明智的。 我試圖將本報告中給出的算法封裝在一個類中,但是由於某種原因,我得到了很多重復的值。 PRNG可能不如報告中說明的那樣好,但是我懷疑這是我的實現失敗的原因。

背景:報告中的PRNG代碼

第3頁上給出以下代碼示例:

/* Public domain code for JKISS RNG */
// seed variables
static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217;

unsigned int JKISS()
{
    unsigned long long t;
    x = 314527869 * x + 1234567;
    y ^= y << 5; y ^= y >> 7; y ^= y << 22;
    t = 4294584393ULL * z + c; c = t >> 32; z = t;
    return x + y + z;
}

關於這一點,報告聲稱

JKISS的周期為≈2127 = 1.7x10 38(2 32 x(2 32 -1)x(1/2 * 4294584393 x 2 32-1)),並且通過了所有Dieharder測試和完整的BigCrunch測試集在TestU01中。

所以這對我來說絕對足夠好。 在報告的后面(第6頁)中對此進行了說明

以下C代碼生成[sic]隨機(雙精度)浮點數0 <= x <1:

 double x; x = JKISS() / 4294967296.0; 

我對此的封裝

我在頭文件中有以下內容:

class JKISS : public IPRNG {
private:
    // Seed variables
    static unsigned int x;
    static unsigned int y;
    static unsigned int z;
    static unsigned int c;


public:
    static unsigned int randui32();
    static double randdouble();
};

與以下實現文件

#include "prng.hpp"

unsigned int JKISS::x = 123456789;
unsigned int JKISS::y = 987654321;
unsigned int JKISS::z = 43219876;
unsigned int JKISS::c = 6543217;

unsigned int JKISS::randui32() {
    unsigned long long t;
    x = 314527869 * x + 1234567;
    y ^= y << 5; y ^= y >> 7; y ^= y << 22;
    t = 4294584393ULL * z + c; c = t >> 32; z = t;
    return x + y + z;
}

double JKISS::randdouble() {
    return randui32() / 4294967296.0;
}

和下面的主程序

#include <iostream>
#include "prng.hpp"

int main() {
    for (int i = 0; i < 10000; ++i) {
        std::cout << JKISS::randdouble() << std::endl;
    }
}

如您所見,我已經復制粘貼了大部分代碼。

但是,當我運行此代碼時,即使我僅獲取10000個值,我也會得到68個重復值。 這向我表明我的封裝有問題,但我無法弄清楚問題出在哪里。

萬一有問題,我將在Ubuntu 13.10上以以下規格運行GCC 4.8.1:

Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU           E5410  @ 2.33GHz
  WORD_SIZE: 64

任何可能導致這種情況的想法都將受到歡迎。

您將返回一個float ,而原始代碼將生成一個double

做什么的? 是什么讓您認為,與C ++標准庫中內置的網頁相比,Web上的某些隨機頁面會為您提供更好的RNG,C ++標准庫提供了打包后可以使用的各種精美功能? 您是否真的可以評估發現的內容是否更適合您的目的?

我得到的結果與您相同,但沒有重復; p

我的意思是,如果我按照指示運行程序,則會得到68個重復項,但是如果我切換randdouble() => randui32() ,就不再有重復項,因此我敢打賭,由於打印例程。

您可以嘗試將雙打收集到一個數組中,然后進行比較以確保100%確定。

看起來打印輸出只有六個有效數字,這意味着您擁有大約1000000個唯一的顯示值(這被過度簡化了-可能性更大,但分布卻偏斜)。 實際上,您從1000000個池中打印10000個值。在這種情況下,我認為 68個重復是合理的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM