如何生成任意给定区间的随机值序列

刚才不知怎么突然想到这个问题。先把C#中Random类的代码贴过来,回头好好看看:

  1 /**//*============================================================
  2 **
  3 ** Class:  Random.cs
  4 **
  5 **                                        
  6 **
  7 ** Purpose: A random number generator.
  8 **
  9 ** Date:  July 8, 1998
 10 ** 
 11 ===========================================================*/
 12 namespace System {
 13     
 14     using System;
 15     using System.Runtime.CompilerServices;
 16     /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random"]/*' />
 17     [Serializable()] public class Random {
 18       //
 19       // Private Constants 
 20       //
 21       private const int MBIG =  Int32.MaxValue;
 22       private const int MSEED = 161803398;
 23       private const int MZ = 0;
 24     
 25       
 26       //
 27       // Member Variables
 28       //
 29       private int inext, inextp;
 30       private int[] SeedArray = new int[56];
 31     
 32       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random"]/*' />
 33       public Random() 
 34         : this(Environment.TickCount) {
 35       }
 36     
 37       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random1"]/*' />
 38       public Random(int Seed) {
 39         int ii;
 40         int mj, mk;
 41     
 42         //Initialize our Seed array.
 43         //This algorithm comes from Numerical Recipes in C (2nd Ed.)
 44         mj = MSEED - Math.Abs(Seed);
 45         SeedArray[55]=mj;
 46         mk=1;
 47         for (int i=1; i<55; i++) {  //Apparently the range [1..55] is special (Knuth) and 
 48                     //so we're wasting the 0'th position.
 49           ii = (21*i)%55;
 50           SeedArray[ii]=mk;
 51           mk = mj - mk;
 52           if (mk<0) mk+=MBIG;
 53           mj=SeedArray[ii];
 54         }
 55         for (int k=1; k<5; k++) {
 56           for (int i=1; i<56; i++) {
 57         SeedArray[i] -= SeedArray[1+(i+30)%55];
 58         if (SeedArray[i]<0) SeedArray[i]+=MBIG;
 59           }
 60         }
 61         inext=0;
 62         inextp = 21;
 63         Seed = 1;
 64       }
 65     
 66       //
 67       // Package Private Methods
 68       //
 69     
 70       /**//*====================================Sample====================================
 71       **Action: Return a new random number [0..1) and reSeed the Seed array.
 72       **Returns: A double [0..1)
 73       **Arguments: None
 74       **Exceptions: None
 75       ==============================================================================*/
 76       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Sample"]/*' />
 77       protected virtual double Sample() {
 78           int retVal;
 79           int locINext = inext;
 80           int locINextp = inextp;
 81 
 82           if (++locINext >=56) locINext=1;
 83           if (++locINextp>= 56) locINextp = 1;
 84           
 85           retVal = SeedArray[locINext]-SeedArray[locINextp];
 86           
 87           if (retVal<0) retVal+=MBIG;
 88           
 89           SeedArray[locINext]=retVal;
 90 
 91           inext = locINext;
 92           inextp = locINextp;
 93                     
 94           //Including this division at the end gives us significantly improved
 95           //random number distribution.
 96           return (retVal*(1.0/MBIG));
 97       }
 98     
 99       //
100       // Public Instance Methods
101       // 
102     
103     
104       /**//*=====================================Next=====================================
105       **Returns: An int [0.._int4.MaxValue)
106       **Arguments: None
107       **Exceptions: None.
108       ==============================================================================*/
109       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next"]/*' />
110       public virtual int Next() {
111         return (int)(Sample()*Int32.MaxValue);
112       }
113     
114       /**//*=====================================Next=====================================
115       **Returns: An int [minvalue..maxvalue)
116       **Arguments: minValue -- the least legal value for the Random number.
117       **           maxValue -- the greatest legal return value.
118       **Exceptions: None.
119       ==============================================================================*/
120       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next1"]/*' />
121       public virtual int Next(int minValue, int maxValue) {
122           if (minValue>maxValue) {
123               throw new ArgumentOutOfRangeException("minValue",String.Format(Environment.GetResourceString("Argument_MinMaxValue"), "minValue""maxValue"));
124           }
125           
126           int range = (maxValue-minValue);
127     
128           //This is the case where we flipped around (e.g. MaxValue-MinValue);
129           if (range<0) {
130               long longRange = (long)maxValue-(long)minValue;
131               return (int)(((long)(Sample()*((double)longRange)))+minValue);
132           }
133           
134           return ((int)(Sample()*(range)))+minValue;
135       }
136     
137     
138       /**//*=====================================Next=====================================
139       **Returns: An int [0..maxValue)
140       **Arguments: maxValue -- the greatest legal return value.
141       **Exceptions: None.
142       ==============================================================================*/
143       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next2"]/*' />
144       public virtual int Next(int maxValue) {
145           if (maxValue<0) {
146               throw new ArgumentOutOfRangeException("maxValue", String.Format(Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), "maxValue"));
147           }
148           return (int)(Sample()*maxValue);
149       }
150     
151     
152       /**//*=====================================Next=====================================
153       **Returns: A double [0..1)
154       **Arguments: None
155       **Exceptions: None
156       ==============================================================================*/
157       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextDouble"]/*' />
158       public virtual double NextDouble() {
159         return Sample();
160       }
161     
162     
163       /**//*==================================NextBytes===================================
164       **Action:  Fills the byte array with random bytes [0..0x7f].  The entire array is filled.
165       **Returns:Void
166       **Arugments:  buffer -- the array to be filled.
167       **Exceptions: None
168       ==============================================================================*/
169       /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextBytes"]/*' />
170       public virtual void NextBytes(byte [] buffer){
171         if (buffer==nullthrow new ArgumentNullException("buffer");
172         for (int i=0; i<buffer.Length; i++) {
173           buffer[i]=(byte)(Sample()*(Byte.MaxValue+1)); 
174         }
175       }
176     }
177 
178 }

posted @ 2008-10-16 10:08  EagleFish(邢瑜琨)  阅读(2667)  评论(0编辑  收藏  举报