概要
cscの作法、調べてみた。
乱数見つけたので、プロットしてみた。
参考にしたページ
写真
サンプルコード
using System;
using System.Windows.Forms;
using System.Drawing;
class LinearCongruential {
private uint x = 1;
public LinearCongruential() {
}
public LinearCongruential(uint s) {
if (s < 1 || s >= 2147483647)
s = 1;
x = s;
}
public uint Next() {
x = (uint)(((ulong) x * 48271) % 2147483647);
return x;
}
}
class Knuth_A {
private int[] a = new int[55];
private int p = 0;
private int q = 21;
public Knuth_A(): this(0) {
}
public Knuth_A(int s) {
if (s == -2147483648)
s = 2147483647;
else if (s < 0)
s = -s;
int j = 161803398 - s;
int k = 1;
a[54] = j;
for (int i = 0; i < 54; i++)
{
int n = k;
a[(21 * i + 20) % 55] = n;
if ((k = j - k) < 0)
k += 2147483647;
j = n;
}
for (int h = 0; h < 4; h++)
{
for (int i = 0; i < 55; i++)
{
int n = a[i] - a[(i + 31) % 55];
if (n < 0)
n += 2147483647;
a[i] = n;
}
}
}
public int Next() {
int x = a[p] - a[q];
if (x == 2147483647)
x--;
else if (x < 0)
x += 2147483647;
a[p] = x;
if (++p >= 55)
p = 0;
if (++q >= 55)
q = 0;
return x;
}
}
class Knuth_B {
private uint[] a = new uint[256];
private uint x;
private uint p;
private uint update(uint y) {
return (uint)(((ulong) 16807 * y) % 2147483647);
}
private uint position(uint y) {
return (uint)((ulong) 256 * (y - 1) / (2147483647 - 1));
}
public Knuth_B(): this(1) {
}
public Knuth_B(uint s) {
if (s < 1 || s >= 2147483647)
s = 1;
x = s;
for (int i = 0; i < a.Length; i++)
a[i] = x = update(x);
x = update(x);
p = position(x);
}
public uint Next() {
uint y = a[p];
a[p] = x = update(x);
p = position(y);
return y;
}
}
class MersenneTwister {
const uint N = 624;
const uint M = 397;
const uint MSK = 0x7FFFFFFF;
private uint[] mag = new uint[] {
0,
0x9908B0DF
};
private uint[] mt = new uint[N];
private uint mti;
public MersenneTwister(): this(5489) {
}
public MersenneTwister(uint s) {
mt[0] = s;
for (mti = 1; mti < N; mti++)
mt[mti] = 1812433253 * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti;
}
public uint Next() {
uint x;
if (mti >= N)
{
uint i,
j;
for (i = 0, j = M; i < N - M; i++, j++)
{
x = (mt[i] & ~MSK) | (mt[i + 1] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
}
for (j = 0; j < M - 1; i++, j++)
{
x = (mt[i] & ~MSK) | (mt[i + 1] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
}
x = (mt[i] & ~MSK) | (mt[0] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
mti = 0;
}
x = mt[mti++];
x ^= (x >> 11);
x ^= (x << 7) & 0x9D2C5680;
x ^= (x << 15) & 0xEFC60000;
x ^= (x >> 18);
return x;
}
}
class MersenneTwister64 {
const uint N = 312;
const uint M = 156;
const ulong MSK = 0x000000007FFFFFFFL;
private ulong[] mag = new ulong[] {
0,
0xB5026F5AA96619E9L
};
private ulong[] mt = new ulong[N];
private uint mti;
public MersenneTwister64(): this(5489) {
}
public MersenneTwister64(ulong s) {
mt[0] = s;
for (mti = 1; mti < N; mti++)
mt[mti] = 6364136223846793005L * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti;
}
public ulong Next() {
ulong x;
if (mti >= N)
{
uint i,
j;
for (i = 0, j = M; i < N - M; i++, j++)
{
x = (mt[i] & ~MSK) | (mt[i + 1] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
}
for (j = 0; j < M - 1; i++, j++)
{
x = (mt[i] & ~MSK) | (mt[i + 1] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
}
x = (mt[i] & ~MSK) | (mt[0] & MSK);
mt[i] = mt[j] ^ (x >> 1) ^ mag[x & 1];
mti = 0;
}
x = mt[mti++];
x ^= (x >> 29) & 0x5555555555555555L;
x ^= (x << 17) & 0x71D67FFFEDA60000L;
x ^= (x << 37) & 0xFFF7EEE000000000L;
x ^= (x >> 43);
return x;
}
}
public class XorShift {
private ulong x = 1;
public XorShift() {
}
public XorShift(ulong s) {
x = s;
}
public ulong Next() {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
}
class form1: Form {
int n = 0;
form1() {
Text = "LinearCongruential";
ClientSize = new Size(320, 330);
Timer timer = new Timer();
timer.Interval = 6000;
timer.Tick += new EventHandler(timerTick);
timer.Start();
}
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
Bitmap p = new Bitmap(300, 300);
int j;
double d0 = 0;
double d1 = 0;
var r = new Random();
var r0 = new LinearCongruential(12);
var r1 = new Knuth_A(12);
var r2 = new Knuth_B(12);
var r3 = new MersenneTwister();
var r4 = new MersenneTwister64();
var r5 = new XorShift(12);
for (j = 0; j < 9000; j++)
{
switch (n)
{
case 0:
d0 = (double) r0.Next() / 2147483647;
d1 = (double) r0.Next() / 2147483647;
break;
case 1:
d0 = (double) r1.Next() / 2147483647;
d1 = (double) r1.Next() / 2147483647;
break;
case 2:
d0 = (double) r2.Next() / 2147483647;
d1 = (double) r2.Next() / 2147483647;
break;
case 3:
d0 = (double) r3.Next() / 2147483647 / 2;
d1 = (double) r3.Next() / 2147483647 / 2;
break;
case 4:
d0 = (double) r4.Next() / 6364136223846793005L / 3;
d1 = (double) r4.Next() / 6364136223846793005L / 3;
break;
case 5:
d0 = (double) r5.Next() / 6364136223846793005L / 3;
d1 = (double) r5.Next() / 6364136223846793005L / 3;
break;
}
int x = (int) Math.Floor(300 * d0);
int y = (int) Math.Floor(300 * d1);
p.SetPixel(x, y, Color.Red);
}
g.DrawImageUnscaled(p, 0, 0);
base.OnPaint(e);
}
void timerTick(object sender, EventArgs e) {
n++;
if (n > 5)
n = 0;
switch (n)
{
case 0:
Text = "LinearCongruential";
break;
case 1:
Text = "Knuth_A";
break;
case 2:
Text = "Knuth_B";
break;
case 3:
Text = "MersenneTwister";
break;
case 4:
Text = "MersenneTwister64";
break;
case 5:
Text = "XorShift";
break;
}
this.Invalidate();
}
[STAThread]
public static void Main() {
Application.Run(new form1());
}
}
以上。