XorShift On VB

VbNet · Console

/Program.vb

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
;