您的位置:首页 > 其它

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

2008-10-16 10:08 323 查看
刚才不知怎么突然想到这个问题。先把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 //

// Public Instance Methods

//

/**//*=====================================Next=====================================

**Returns: An int [0.._int4.MaxValue)

**Arguments: None

**Exceptions: None.

==============================================================================*/

/**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next"]/*' />

public virtual int Next() {

return (int)(Sample()*Int32.MaxValue);

}

/**//*=====================================Next=====================================

**Returns: An int [minvalue..maxvalue)

**Arguments: minValue -- the least legal value for the Random number.

** maxValue -- the greatest legal return value.

**Exceptions: None.

==============================================================================*/

/**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next1"]/*' />

public virtual int Next(int minValue, int maxValue) {

if (minValue>maxValue) {

throw new ArgumentOutOfRangeException("minValue",String.Format(Environment.GetResourceString("Argument_MinMaxValue"), "minValue", "maxValue"));

}

int range = (maxValue-minValue);

//This is the case where we flipped around (e.g. MaxValue-MinValue);

if (range<0) {

long longRange = (long)maxValue-(long)minValue;

return (int)(((long)(Sample()*((double)longRange)))+minValue);

}

return ((int)(Sample()*(range)))+minValue;

}

/**//*=====================================Next=====================================

**Returns: An int [0..maxValue)

**Arguments: maxValue -- the greatest legal return value.

**Exceptions: None.

==============================================================================*/

/**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next2"]/*' />

public virtual int Next(int maxValue) {

if (maxValue<0) {

throw new ArgumentOutOfRangeException("maxValue", String.Format(Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), "maxValue"));

}

return (int)(Sample()*maxValue);

}

/**//*=====================================Next=====================================

**Returns: A double [0..1)

**Arguments: None

**Exceptions: None

==============================================================================*/

/**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextDouble"]/*' />

public virtual double NextDouble() {

return Sample();

}

/**//*==================================NextBytes===================================

**Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.

**Returns:Void

**Arugments: buffer -- the array to be filled.

**Exceptions: None

==============================================================================*/

/**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextBytes"]/*' />

public virtual void NextBytes(byte [] buffer){

if (buffer==null) throw new ArgumentNullException("buffer");

for (int i=0; i<buffer.Length; i++) {

buffer[i]=(byte)(Sample()*(Byte.MaxValue+1));

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐