VbNet · Console
Option Strict On
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Console
Imports XorShifts
'XorShift Module
'Imports System.Collections.Generic
'Imports System.Linq
Namespace XorShifts
Class XorShift
Private r As IEnumerator(Of UInteger)
Public Shared ReadOnly defaults As New Dictionary(Of String,UInteger) From {
{"x",123456789},
{"y",362436069},
{"z",521288629},
{"w",88675123}
}
Public ReadOnly seeds As Dictionary(Of String,UInteger)
Public randCount As UInteger=0
Sub New(
Optional _w As UInteger?=Nothing,
Optional _x As UInteger?=Nothing,
Optional _y As UInteger?=Nothing,
Optional _z As UInteger?=Nothing
)
Dim w=CUInt(If(_w IsNot Nothing,_w,CUInt(Environment.TickCount)))
Dim x=CUInt(If(_x IsNot Nothing,_x,w<<13))
Dim y=CUInt(If(_y IsNot Nothing,_y,w>>9 Xor x<<6))
Dim z=CUInt(If(_z IsNot Nothing,_z,y>>7))
seeds=New Dictionary(Of String,UInteger) From {
{"x",x},{"y",y},{"z",z},{"w",w}
}
r=randGen(w,x,y,z)
End Sub
Public Iterator Function randGen(w As UInteger,x As UInteger,y As UInteger,z As UInteger) As IEnumerator(Of UInteger)
Dim t As UInteger
Do
t=x Xor (x<<11)
x=y
y=z
z=w
w=(w Xor (w>>19)) Xor (t Xor (t>>8))
Yield w
Loop
End Function
Public Function rand() As UInteger
randCount+=1UI
r.MoveNext()
Return r.Current
End Function
Public Function randInt(Optional min As Integer=0,Optional max As Integer=&H7FFFFFFFI) As Integer
Return CInt(rand() mod (CUInt(max)-min+1)+min)
End Function
Public Function randFloat(Optional min As Single=0,Optional max As Single=1) As Single
Return CSng((rand() mod &HFFFFUI)/&HFFFFUI*(max-min)+min)
End Function
Public Function shuffle(Of T)(_arr As T()) As T()
Dim arr=CType(_arr.Clone(),T())
For i=0 To arr.Length-2
Dim r As Integer=randInt(i,arr.Length-1)
Dim tmp As T=arr(i)
arr(i)=arr(r)
arr(r)=tmp
Next
Return arr
End Function
Public Function shuffle(Of T)(_arr As List(Of T)) As List(Of T)
Dim arr As New List(Of T)(_arr)
For i=0 To arr.Count-2
Dim r As Integer=randInt(i,arr.Count-1)
Dim tmp As T=arr(i)
arr(i)=arr(r)
arr(r)=tmp
Next
Return arr
End Function
PubLic Class defaultSeed
Inherits XorShift
Sub New()
MyBase.New(
defaults("w"),
defaults("x"),
defaults("y"),
defaults("z")
)
End Sub
End Class
End Class
End Namespace
'XorShift End
Public Class TestXS
Shared Sub Main()
'XorShift乱数ジェネレータの初期化
' 論文デフォルトシード
Dim r_def As New XorShift.defaultSeed()
' 固定値シード
Dim r_const As New XorShift(100)
' 時間シード
Dim r As New XorShift()
'デフォルトシード値の取得
WriteLine(">> defaults")
For Each i In XorShift.defaults.Keys
WriteLine("{0}:{1}",i,XorShift.defaults(i))
Next
'適用したシード値の取得
WriteLine(">> seeds in r")
For Each i In r.seeds.Keys
WriteLine("{0}:{1}",i,XorShift.defaults(i))
Next
'乱数の生データを取得
WriteLine(">> rand 0 to UInt32Max")
For i=0 To 5-1
WriteLine(r_def.rand())
Next
'0-100の乱数(100含む)を整数で取得
WriteLine(">> randInt 0 to 100")
For i=0 To 5-1
WriteLine(r_const.randInt(0,100))
Next
'0-1の乱数を浮遊小数点で取得
WriteLine(">> randFloat 0 to 1")
For i=0 To 5-1
WriteLine(r.randFloat())
Next
'静的配列のシャッフル
'値渡しとなるので元の配列は破壊されない
WriteLine(">> shuffle Array")
Dim a As Integer()=Enumerable.Range(0,20).ToArray()
WriteLine(String.Join(", ",r.shuffle(a)))
WriteLine(String.Join(", ",a))
'List(Of T)のシャッフル
WriteLine(">> shuffle List(Of T)")
Dim b As New List(Of Integer)(Enumerable.Range(0,20))
WriteLine(String.Join(", ",r.shuffle(b)))
WriteLine(String.Join(", ",b))
'今の乱数を回した回数
WriteLine(">> randCount in r")
WriteLine(r.randCount)
End Sub
End Class