2009-07-22 27 views
7

到目前爲止,我已經用在這裏找到了C#Mersenne Twister生成隨機數:C#梅森倍捻機隨機整數發電機執行(SFMT)蒙特卡羅模擬

http://www.centerspace.net/resources.php

我剛剛發現SFMT這是應該是快兩倍,在這裏:

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/

任何人都可以指向我在一個C#實現SFMT

我的要求是生成(和包括)0和2^20(1048576)之間的整數。

我需要這樣做每天數萬億次模擬24小時運行時間,所以我準備花上幾天時間來調整這個完美。

public uint Next20() 
{    
    return (uint)(genrand_int32() >> 12); 
} 

使用方法genrand_int32()我想我製作自己的版本,genrand_int20(),即產生:

目前我已經加入了新的方法,以適應我的要求調整了中心空間梅森倍捻機整數在(和包括)0和2^20之間以保存在上面,並且移位但我不瞭解數學。我到底該如何做到這一點?

也使用uint會更快,int,或者只是一個可尋址數字的問題?因爲我只需要1048576,我只關心速度。

同樣在此將一個的Windows Server 2003 R2 SP2(32位)盒.NET 2.處理器上運行是AMD Opteron 275(4芯)

+0

後的20位數字將代表範圍從0到2^20-1包容性,2^20需要21位來表示(1後跟20個零) – 2009-07-22 16:16:39

+1

Nifle:不要將發生器的*週期*(它是序列的長度)與*間隔*混淆在哪個隨機數中。 – Joey 2009-07-22 16:23:54

+0

@帕特里克感謝你是正確的2^20-1是我需要的,我需要隨機索引到一個長度爲2^20的數組。 – m3ntat 2009-07-22 16:30:25

回答

5

你可以做的是下載你在代碼項目中發現的source from the link。解壓縮,在Visual Studio中加載解決方案並編譯它。這會給你一個源代碼,一個非託管的c dll和一個.lib文件。

您可以在此dll中調用函數(僅導出5個簡單函數,其中只需要兩個函數),或者您可以使用此dll,lib和SFMT頭文件來創建託管包裝器你可以在C#中使用沒有P/Invoke的DLL。我只是嘗試了這種方法,做起來非常簡單。沒有涉及明確的編組。

以下是操作方法。一旦你下載並編譯了源文件(你需要除了dll之外創建的頭文件和lib文件)創建一個新的C++ CLR類庫項目。稱它爲WrapSFMT或其他東西。去項目屬性。在C++ /預編譯頭文件下,更改爲「不使用預編譯頭文件」。在鏈接器/常規/附加庫目錄下,輸入SFMT.lib的路徑。在鏈接器/輸入/附加依賴項下,添加SFMT.lib。關閉屬性頁面。將SFMT.h複製到您的項目文件夾並將其包含在項目中。

編輯WrapSFMT.h,內容如下:

#pragma once 
#include "SFMT.H" 

using namespace System; 

namespace WrapSFMT { 

public ref class SRandom 
{ 
public:SRandom(UInt32); 
public:UInt32 Rand32(void); 
}; 
} 

這些聲明將在你的類中的方法。現在編輯WrapSFMT.cpp來讀取:

#include "WrapSFMT.h" 

namespace WrapSFMT { 

SRandom::SRandom(UInt32 seed) 
{ 
    init_gen_rand(seed); 
} 

UInt32 SRandom::Rand32() 
{ 
    return gen_rand32(); 
} 
} 

這些實現您在頭文件中聲明的方法。您所做的只是從SFMT.dll調用函數,而C++/CLI會自動處理從非託管轉換爲託管的功能。現在,您應該能夠構建WrapSFMT.dll並在您的C#項目中引用它。確保SFMT.dll在路徑中,並且應該沒有問題。

0

我真的沒有看到你的速度問題在這裏。在使用MT19937或MT19937-64生成隨機整數的我的機器上(Core 2 Duo T7200 @ 2 GHz)大約需要20 ns(繪製50000個數字時的平均值)。所以這一天大概是4,32×10 (因此大約有4 兆億個數字)。這是一個核心。用Java。所以我認爲你可以期望性能足以滿足你的需求。

要真正回答你的問題:我不知道SFMT的C#實現,但將C代碼轉換爲C#應該相當簡單。然而,由於SFMT針對SIMD進行了優化,而C#目前不直接支持,因此您的收益並不高。

0

也許this是你在找什麼? 有幾個實現的列表。

具體而言,this one(Cory Nelson)可能會有用。