publicvoid
asked on
Picking a random number between x and y using the KISS generator by George Marsaglia
Ok this is c++ code, but I am going to port it over. In the mean time, if i have this code that generates pretty good random numbers, how do i restrict its output to a certain range (ie 0-500000) without weighting the results either way. Should i just keep picking random number until i get one in the range that i want and then return it? Or is there a better way? Here is the c++ code: (Again i am moving this to c#, so any help in that direction would be great also)
#include <stdio.h>
#define znew (z=36969*(z&65535)+(z>>16) )
#define wnew (w=18000*(w&65535)+(w>>16) )
#define MWC ((znew<<16)+wnew )
#define SHR3 (jsr^=(jsr<<17), jsr^=(jsr>>13), jsr^=(jsr<<5))
#define CONG (jcong=69069*jcong+1234567 )
#define FIB ((b=a+b),(a=b-a))
#define KISS ((MWC^CONG)+SHR3)
#define LFIB4 (c++,t[c]=t[c]+t[UC(c+58)] +t[UC(c+11 9)]+t[UC(c +178)])
#define SWB (c++,bro=(x<y),t[c]=(x=t[U C(c+34)])- (y=t[UC(c+ 19)]+bro))
#define UNI (KISS*2.328306e-10)
#define VNI ((long) KISS)*4.656613e-10
#define UC (unsigned char) /*a cast operation*/
typedef unsigned long UL;
/* Global static variables: */
static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160;
static UL a=224466889, b=7584631, t[256];
/* Use random seeds to reset z,w,jsr,jcong,a,b, and the table
t[256]*/
static UL x=0,y=0,bro; static unsigned char c=0;
/* Example procedure to set the table, using KISS: */
void settable(UL i1,UL i2,UL i3,UL i4,UL i5, UL i6)
{ int i; z=i1;w=i2,jsr=i3; jcong=i4; a=i5; b=i6;
for(i=0;i<256;i=i+1) t[i]=KISS;
}
/* This is a test main program. It should compile and print 7
0's. */
int main(void){
int i; UL k;
settable(12345,65435,34221 ,12345,998 3651,95746 118);
for(i=1;i<1000001;i++){k=L FIB4;} printf("%u\n", k-1064612766U);
for(i=1;i<1000001;i++){k=S WB ;} printf("%u\n", k- 627749721U);
for(i=1;i<1000001;i++){k=K ISS ;} printf("%u\n", k-1372460312U);
for(i=1;i<1000001;i++){k=C ONG ;} printf("%u\n", k-1529210297U);
for(i=1;i<1000001;i++){k=S HR3 ;} printf("%u\n", k-2642725982U);
for(i=1;i<1000001;i++){k=M WC ;} printf("%u\n", k- 904977562U);
for(i=1;i<1000001;i++){k=F IB ;} printf("%u\n", k-3519793928U);
}
http://www.cs.yorku.ca/~oz/marsaglia-rng.html is the website where this was found. It has notes on the end that i did not include here to keep this post from being too long. It explains that the UNI generator does this:
Finally, because many simulations call for uniform
random variables in 0<x<1 or -1<x<1, I use #define
statements that permit inclusion of such variates
directly in expressions: using UNI will provide a
uniform random real (float) in (0,1), while VNI will
provide one in (-1,1).
I will be using the UNI(KISS) generator in the above code.
Thank you,
John Gjonola
#include <stdio.h>
#define znew (z=36969*(z&65535)+(z>>16)
#define wnew (w=18000*(w&65535)+(w>>16)
#define MWC ((znew<<16)+wnew )
#define SHR3 (jsr^=(jsr<<17), jsr^=(jsr>>13), jsr^=(jsr<<5))
#define CONG (jcong=69069*jcong+1234567
#define FIB ((b=a+b),(a=b-a))
#define KISS ((MWC^CONG)+SHR3)
#define LFIB4 (c++,t[c]=t[c]+t[UC(c+58)]
#define SWB (c++,bro=(x<y),t[c]=(x=t[U
#define UNI (KISS*2.328306e-10)
#define VNI ((long) KISS)*4.656613e-10
#define UC (unsigned char) /*a cast operation*/
typedef unsigned long UL;
/* Global static variables: */
static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160;
static UL a=224466889, b=7584631, t[256];
/* Use random seeds to reset z,w,jsr,jcong,a,b, and the table
t[256]*/
static UL x=0,y=0,bro; static unsigned char c=0;
/* Example procedure to set the table, using KISS: */
void settable(UL i1,UL i2,UL i3,UL i4,UL i5, UL i6)
{ int i; z=i1;w=i2,jsr=i3; jcong=i4; a=i5; b=i6;
for(i=0;i<256;i=i+1) t[i]=KISS;
}
/* This is a test main program. It should compile and print 7
0's. */
int main(void){
int i; UL k;
settable(12345,65435,34221
for(i=1;i<1000001;i++){k=L
for(i=1;i<1000001;i++){k=S
for(i=1;i<1000001;i++){k=K
for(i=1;i<1000001;i++){k=C
for(i=1;i<1000001;i++){k=S
for(i=1;i<1000001;i++){k=M
for(i=1;i<1000001;i++){k=F
}
http://www.cs.yorku.ca/~oz/marsaglia-rng.html is the website where this was found. It has notes on the end that i did not include here to keep this post from being too long. It explains that the UNI generator does this:
Finally, because many simulations call for uniform
random variables in 0<x<1 or -1<x<1, I use #define
statements that permit inclusion of such variates
directly in expressions: using UNI will provide a
uniform random real (float) in (0,1), while VNI will
provide one in (-1,1).
I will be using the UNI(KISS) generator in the above code.
Thank you,
John Gjonola
ASKER
Thanks but no go... Due to certain regulations the random number generator has to pass certain tests, and the one built into .net doesn't pass.
Thank you,
John Gjonola
Thank you,
John Gjonola
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Nice! Love the mersenne twister. That passes the test. Thank you so much!
John Gjonola
John Gjonola
I personally use MT in my chess engine (zobrist hash) and have always had pretty good results from it.
Greg
Greg
It's using System.Random namespace
// Generate random numbers with both bounds specified.
static void BothBoundsRandoms( int seed, int lower, int upper )
{
Console.WriteLine(
"\nRandom object, seed = {0}, lower = {1}, " +
"upper = {2}:", seed, lower, upper );
Random randObj = new Random( seed );
// Generate six random integers from the lower to
// upper bounds.
for( int j = 0; j < 6; j++ )
Console.Write( "{0,11} ",
randObj.Next( lower, upper) );
Console.WriteLine( );
}