CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using XorShifts;
//XorShift Module
//using System;
//using System.Collections.Generic;
namespace XorShifts{
class XorShift{
private IEnumerator<uint> r;
public static readonly Dictionary<string,uint> defaults=new Dictionary<string,uint>(){
{"x",123456789},
{"y",362436069},
{"z",521288629},
{"w",88675123}
};
public readonly Dictionary<string,uint> seeds;
public uint randCount=0;
public XorShift(uint? _w=null,uint? _x=null,uint? _y=null,uint? _z=null){
uint w=_w ?? (uint)Environment.TickCount;
uint x=_x ?? w<<13;
uint y=_y ?? (w>>9)^(x<<6);
uint z=_z ?? y>>7;
seeds=new Dictionary<string,uint>(){
{"x",x},{"y",y},{"z",z},{"w",w}
};
r=randGen(w,x,y,z);
}
public IEnumerator<uint> randGen(uint w,uint x,uint y,uint z){
uint t;
for(;;){
t=x^(x<<11);
x=y;
y=z;
z=w;
yield return w=(w^(w>>19))^(t^(t>>8));
}
}
public uint rand(){
randCount++;
r.MoveNext();
return r.Current;
}
public int randInt(int min=0,int max=0x7FFFFFFF){
return (int)(rand()%(max-min+1))+min;
}
public float randFloat(float min=0,float max=1){
return (float)(rand()%0xFFFF)/0xFFFF*(max-min)+min;
}
public T[] shuffle<T>(T[] _arr){
var arr=(T[])_arr.Clone();
for(int i=0;i<=arr.Length-2;i++){
int r=randInt(i,arr.Length-1);
T tmp=arr[i];
arr[i]=arr[r];
arr[r]=tmp;
}
return arr;
}
public List<T> shuffle<T>(List<T> _arr){
var arr=new List<T>(_arr);
for(int i=0;i<=arr.Count-2;i++){
int r=randInt(i,arr.Count-1);
T tmp=arr[i];
arr[i]=arr[r];
arr[r]=tmp;
}
return arr;
}
public class defaultSeed:XorShift{
public defaultSeed():base(
defaults["w"],
defaults["x"],
defaults["y"],
defaults["z"]
){}
}
}
}
//XorShift End
namespace TestXS{
public class TestXS{
public static void Main(){
//XorShift乱数ジェネレータの初期化
// 論文デフォルトシード
var r_def=new XorShift.defaultSeed();
// 固定値シード
var r_const=new XorShift(100);
// 時間シード
var r=new XorShift();
//デフォルトシード値の取得
Console.WriteLine(">> defaults");
foreach(var i in XorShift.defaults.Keys){
Console.WriteLine("{0}:{1}",i,XorShift.defaults[i]);
}
//適用したシード値の取得
Console.WriteLine(">> seeds in r");
foreach(var i in r.seeds.Keys){
Console.WriteLine("{0}:{1}",i,XorShift.defaults[i]);
}
//乱数の生データを取得
Console.WriteLine(">> rand 0 to UInt32Max");
for(int i=0;i<5;i++){
Console.WriteLine(r_def.rand());
}
//0-100の乱数(100含む)を整数で取得
Console.WriteLine(">> randInt 0 to 100");
for(int i=0;i<5;i++){
Console.WriteLine(r_const.randInt(0,100));
}
//0-1の乱数を浮遊小数点で取得
Console.WriteLine(">> randFloat 0 to 1");
for(int i=0;i<5;i++){
Console.WriteLine(r.randFloat());
}
//静的配列のシャッフル
//値渡しとなるので元の配列は破壊されない
Console.WriteLine(">> shuffle Array");
int[] a=Enumerable.Range(0,20).ToArray();
Console.WriteLine(String.Join(", ",r.shuffle(a)));
Console.WriteLine(String.Join(", ",a));
//List<T>のシャッフル
Console.WriteLine(">> shuffle List<T>");
var b=new List<int>(Enumerable.Range(0,20));
Console.WriteLine(String.Join(", ",r.shuffle(b)));
Console.WriteLine(String.Join(", ",b));
//今の乱数を回した回数
Console.WriteLine(">> randCount in r");
Console.WriteLine(r.randCount);
}
}
}