[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 692
  • Last Modified:

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+119)]+t[UC(c+178)])
#define SWB (c++,bro=(x<y),t[c]=(x=t[UC(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,9983651,95746118);
for(i=1;i<1000001;i++){k=LFIB4;} printf("%u\n", k-1064612766U);
for(i=1;i<1000001;i++){k=SWB ;} printf("%u\n", k- 627749721U);
for(i=1;i<1000001;i++){k=KISS ;} printf("%u\n", k-1372460312U);
for(i=1;i<1000001;i++){k=CONG ;} printf("%u\n", k-1529210297U);
for(i=1;i<1000001;i++){k=SHR3 ;} printf("%u\n", k-2642725982U);
for(i=1;i<1000001;i++){k=MWC ;} printf("%u\n", k- 904977562U);
for(i=1;i<1000001;i++){k=FIB ;} 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
0
publicvoid
Asked:
publicvoid
  • 2
  • 2
1 Solution
 
jatinderalaghCommented:
Why don't you use the Random class with in FrameWork library

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( );
    }
0
 
publicvoidAuthor Commented:
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
0
 
gregoryyoungCommented:
its just basic operations ... Do you need help expanding them or ?

Also take a look at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritycryptographyrngcryptoserviceproviderclasstopic.asp there are good random number generators in the framework ... just not the Random class.

Personally I would use http://www.codeproject.com/csharp/CsharpMersenneTwister.asp its an algorithm known as the mersenne twister which is also pretty quick.

Greg
0
 
publicvoidAuthor Commented:
Nice!  Love the mersenne twister.  That passes the test.  Thank you so much!

John Gjonola
0
 
gregoryyoungCommented:
I personally use MT in my chess engine (zobrist hash) and have always had pretty good results from it.

Greg
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now