Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / General / May 2005

Tip: Looking for answers? Try searching our database.

Random numbers

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Terry Holland - 25 May 2005 09:55 GMT
I am writing an application that needs a list of unique random numbers
between Lower and Upper limits.

The code im using is shown along with some result sets.  What can I do to
make the results more random?

===============================================

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
GetList(50)
End Sub
Function GetList(ByVal intListLength As Integer)
Dim intNumber As Integer
For intNumber = 1 To intListLength
Debug.WriteLine(RandomNumber(50, 1))
Next
End Function

Public Function RandomNumber(ByVal MaxNumber As Integer, Optional ByVal
MinNumber As Integer = 0) As Integer
Dim objRandmon As New System.Random
Return objRandmon.Next(MinNumber, MaxNumber)
End Function
===============================================

Here are a few result sets

49, 6, 6, 6, 6, 6, 6, 6, 6, 23, 23, 23, 23, 23, 23, 23, 23, 23, 15, 15, 15,
15, 15, 15, 15, 15, 15, 33, 33, 33, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 42, 42, 42, 42, 42

37, 17, 17, 17, 17, 17, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 3, 3, 3, 3,
3, 3, 3, 3, 3, 44, 44, 44, 44, 44, 44, 44, 44, 44, 13, 13, 13, 13, 13, 13,
13, 5, 5, 5, 5, 5, 5, 22, 22, 22

6, 6, 6, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8

38, 38, 38, 38, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 34, 34

13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 40, 40, 40, 40, 40, 40

9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 28, 28
Gus Gustafson - 25 May 2005 12:19 GMT
Terry, it appears that you do not have a well behaved random number
generator. I have attached a C# class that generates well behaved random
numbers. However, if you want a quick and dirty use the following:

BEGIN QUICK AND DIRTY

           ulong       ia = 106 ;
           ulong       ic = 1283 ;
           ulong       im = 6075 ;
           ulong       j = 0 ;
           ulong       jhi = <set to Upper limit> ;
           ulong       jlo = <set to Lower limit> ;
           ulong       jran = ( im - 7 ) ;

           jran = ( jran * ia + ic ) % im ;
           j = jlo + ( ( jhi - jlo + 1 ) * jran ) /im ;

END QUICK AND DIRTY

See section 7.1 and following in

       http://www.library.cornell.edu/nr/bookcpdf.html

for a discussion of both, but especially for the quick and dirty. The
section includes other constants thgat can be used depending upon the machine
overflow.

BEGIN C# class

namespace CNA_Library
   {
   using System ;
   using System.Configuration ;
   using System.Data ;
   using System.Data.SqlClient ;
   using System.Drawing ;
   using System.Text ;
   using System.Web ;
   using System.Web.Mail ;
   using CNA_Library ;

 
    public class Random_Variants
       {

// *********************************** Compilation unit constants

                const      int     IA = ( 16807 ) ;
                const      int     IM = ( 2147483647 ) ;
                const      float   AM = ( 1.0f /
                                          ( float ) IM ) ;
                const      int     IQ = ( 127773 ) ;
                const      int     IR = ( 2836 ) ;
                const      int     NTAB = ( 32 ) ;
                const      int     NDIV = ( 1 + ( IM - 1 ) /
                                                NTAB ) ;
                const      float   EPS = ( ( float ) 1.2e-7 ) ;
                const      float   RNMX = ( 1.0f - EPS ) ;
       
       protected static    long[]  iv = new long [ NTAB ] ;
       protected static    long    iy = 0 ;
         

// ********************************************************* ran1

       /// <remarks>
       /// "Minimal" random number generator of Park and Miller
       /// with Bays and Durham shuffle and added safeguards.  
       /// Returns a random  variate between 0.0 and 1.0, ex-
       /// clusive of the endpoint values.
       ///
       /// Call with initialize set to a negative integer to
       /// initialize; thereafter, do not alter initialize
       /// between successive deviates in a sequence.  
       ///
       /// RNMX should approximate the largest floating point
       /// value that is less than 1.
       ///
       /// From "Numerical Recipes in C: The Art of Scientific
       /// Computing", ISBN 0-521-43108-5, pg 280.  See section
       /// 7.1 in
       ///
       ///     http://www.library.cornell.edu/nr/bookcpdf.html
       /// </remarks>

       private float ran1 ( ref long initialize )
           {
           long    j ;
           long    k = 0 ;
           float   temp ;
           
           if ( ( initialize <= 0 ) || ( iy == 0 ) )
               {
                                      // avoid initialize == 0
               if ( -( initialize ) < 1 )
                   {
                   initialize = 1 ;
                   }
               else
                   {
                   initialize = - ( initialize ) ;
                   }
                                      // load shuffle table
                                      // ( after 8 warmups)
               for ( j = ( NTAB + 7 ); ( j >= 0 ); j-- )
                   {
                   k = ( initialize ) / IQ ;
                   initialize = IA * ( initialize - k * IQ ) -
                                IR * k ;
                   if ( initialize < 0 )
                       {
                       initialize += IM ;
                       }
                   if ( j < NTAB )
                       {
                       iv [ j ] = initialize ;
                       }
                   }
               iy = iv [ 0 ] ;
               }
                                       // starts here when not
                                       // initializing

                                       // compute initialize=
                                       //     (IA*initialize)%IM
                                       // without overflow
                                       // using Schrange's
                                       // method
           k = ( initialize ) / IQ ;
           initialize = IA * ( initialize - k * IQ ) - IR * k ;
           if ( initialize < 0 )
               {
               initialize += IM ;
               }
           j = iy / NDIV ;             // in range 0..NTAB-1
           iy = iv [ j ] ;             // retrieve previous
           iv [ j ] = initialize ;     // refill shuffle table

                                       // do not include end-
                                       // points in the returned
                                       // value
           if ( ( temp = ( float ) ( AM * iy ) ) > RNMX )
               {
               temp = ( float ) RNMX ;
               }
               
           return ( temp ) ;
           }

// ***************************************** long_uniform_variate

       /// <summary>
       /// long long_uniform_variate ( long  initialize,
       ///                             long  minimum,
       ///                             long  maximum )
       /// </summary
       /// <param name='initialize'>
       /// long containing and initializing indicator, should
       /// be -1 and then never changed.
       /// </param>
       /// <param name='minimum'>
       /// long containing the smallest long value to be
       /// returned.
       /// </param>
       /// <param name='maximum'>
       /// long containing the largest long value to be
       /// returned.
       /// </param>
       /// <returns>
       /// long containing a random value in the range minimum
       //  to maximum, exclusive.  This function does not return
       /// the maximum value.  If the value of maximum is de-
       /// sired, add one to the supplied value.  For example,
       /// if the desired range of values is 1 through 4, includ-
       /// ing the value 4, invoke the function as:
       ///
       ///     long_uniform_variate ( 1, 5 )
       /// </returns>

       public long long_uniform_variate ( ref long  initialize,
                                              long  minimum,
                                              long  maximum )
           {

           return ( ( minimum +
                   ( int ) ( ( float ) ( maximum - minimum ) *
                               ran1 ( ref initialize ) ) ) ) ;
           }
   
       } // class
   } // namespace

END C# class

HTH

Gus
Signature

Gus Gustafson

> I am writing an application that needs a list of unique random numbers
> between Lower and Upper limits.
[quoted text clipped - 47 lines]
> 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 11, 11,
> 11, 11, 11, 11, 11, 11, 28, 28
Terry Holland - 25 May 2005 14:23 GMT
Thanks for your response Gus

Im not familiar with C# so I'm trying to convert quick and dirty function to
VB.Net.  I'm ok with most of it but Im not sure what the following line
converts to
   jran = ( jran * ia + ic ) % im ;

With regard to the .NET inbuilt System.Random class, am I to assume that if
I need to call this from within a loop to generate a list of 'random'
numbers that it is in fact totally useless or am I doing something wrong?

Most examples that I see this code
   objRandmon.Next(MinNumber, MaxNumber)
being used in is to generate one number in response to a user input.  As far
as I can work out the randomness is in "when the user inputs" rather than
anything in this class.
While I can see this as being useful in some circumstances it is not very
useful for generating lists.

Regards

Terry Holland

> Terry, it appears that you do not have a well behaved random number
> generator. I have attached a C# class that generates well behaved random
[quoted text clipped - 243 lines]
> > 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 11, 11,
> > 11, 11, 11, 11, 11, 11, 28, 28
Phil Wilson - 25 May 2005 20:34 GMT
You're making a new Random object on every call to RandomNumber. When you
don't pass a seed in the constructor, the code uses a time ticker as the
seed, so you'll see the same results every time you call until the tick
count increases, then you get the same value while that tick count is the
current one.

For a proper sequence, and better performance, create the Random object
once, perhaps with a seed of your choice, then call Next on that.
Signature

Phil Wilson [MVP Windows Installer]
----

> Thanks for your response Gus
>
[quoted text clipped - 287 lines]
> 11,
>> > 11, 11, 11, 11, 11, 11, 28, 28
Terry Holland - 31 May 2005 09:42 GMT
Thanks

Works fine now

Terry
M. Foco - 26 May 2005 14:36 GMT
> Public Function RandomNumber(ByVal MaxNumber As Integer, Optional ByVal
> MinNumber As Integer = 0) As Integer
> Dim objRandmon As New System.Random
> Return objRandmon.Next(MinNumber, MaxNumber)
> End Function

Try creating just one global System.Random object. You'll gain both speed
and correctness.
The System.Random number generator is initialized with the timer, creating
two different random number generators in short time will initialize them
both with the same sequence (and you'll get repeating numbers).

--
Marco *PaN!* Foco

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.