Two days ago, before going to bedAlgorithmIntroduction: the random function contains an exercise question.
5.1-2 describes an implementation of the random (a, B) process. It only calls random (). As a function of A and B, yourProgramWhat is the expected running time?
Note: Random (a, B) generates a, A + 1, A + 2 ,..., B function generator, and the probability of generating each integer is equal, the same as 1/(B-A + 1 ).
I was familiar with seeing this question,The concept of using random (0, 1) to generate 0 or 1 to form a binary number to implement random (A, B ).But after thinking about it, I feel a problem is a bit unclear in my mind.
Run the random () function K times, so that 2 k> = (B-A + 1), The Integer Range of [K) is obtained,How to map [K) to the Integer Range of [a, B] to ensure that the probability of each integer is equal, the same as 1/(B-A + 1 ).
1. if K exists so that 2 k = (B-A + 1), you only need to correspond the number of binary values to the integer [a, B, the probability is equal to 1/(B-A + 1.
For example, random (3, 6), k = 2. At this time, the ing relationship can be 00 ~ 3,01 ~ 4,10 ~ 5, 11 ~ 6. The probability of generation is 1/4.
2. if K does not exist to make it 2 k = (B-A + 1), the probability of generating an integer of [1/2 K) is K, less than 1/(B-A + 1 ). [k) how to map to [a, B] Integer Range.
Idea 1: Expand the [k) range so that 2 K can be divisible by (B-A + 1). In this way, when [K) is divided into N segments, each segment corresponds to an integer in [a, B.
However, this idea is not feasible because such a K value does not exist. either 2 k = (B-A + 1), or 2 k> (B-A + 1) and cannot be divisible by (B-A + 1.
Train of Thought 2: Take the truncation ing of the parameter, that is, the first part of [K) is mapped to [a, B], so that although the probability of generating an integer is equal, but not equal to 1/(B-A + 1), and how to deal with the value after [K.
This idea is feasible. If the value of the post-generation part is generated, it will continue to call itself and re-random. from the result output analysis, the final result output of random (A, B) is only an integer in [a, B], and the probability of each integer is equal, therefore, the probability value is 1/(B-A + 1 ).
ImplementationCodeAs follows:
Int Random ( Int A, Int B ){ Int M = 1 ; Int Len = B-A + 1 ; Int K = 0 ; // Calculate the smallest positive integer k so that 2 ^ K> = Len While (M < Len) {k ++ ; M * = 2 ;} M = 0 ; For ( Int I = 0 ; I <K; I ++) {M + = Random ( 0 , 1 )*( 1 < I );} If (M + 1 > Len) {return random (a, B );} Else {Return m + A ;}}
Due to the existence of redundancy, the worst case of the running time of this method is that the method calls itself infinitely recursively. the minimum running time is O (log (B-A + 1 )).
More similar questions can be displayed from the above exercise questions.
Use rand5 () to generate rand7 (). rand5 () to generate an integer from 1 to 5, and rand7 () to generate an integer from 1 to 7.
The solution is the same as the exercises mentioned above. an integer space generated by rand5 () is mapped to an integer space [1, 7]. The probability is equal and equal to 1/7.
The following describes several interesting implementations.
1. Use a preset ArrayThis method is simple, easy to understand, but not scalable and requires additional storage space.
1 Int Rand7 () 2 { 3 Int Vals [ 5 ] [ 5 ] = { 4 { 1 , 2 , 3 , 4 , 5 }, 5 { 6 , 7 , 1 , 2 , 3 }, 6 { 4 , 5 ,6 , 7 , 1 }, 7 { 2 , 3 , 4 , 5 , 6 }, 8 { 7 , 0 , 0 ,0 , 0 } 9 }; 10 Int Result = 0 ; 11 While (Result = 0 ) 12 { 13 Int I =Rand5 (); 14 Int J = Rand5 (); 15 Result = Vals [I- 1 ] [J- 1 ]; 16 } 17 Return Result; 18 }
2. General implementation methodsScalable. It consists of three steps: constructing a large integer interval, limiting an integer interval, and finally ing an integer interval.
1 Int Rand7 () 2 { 3 Int I; 4 Do { 5 I = 5 * (Rand5 ()- 1 ) + Rand5 (); // Returns an integer range []. 6 } While (I> 21 ); // Control the Integer Range of [] to [1, 21]. 7 Return I % 7 + 1 ; // Map [1, 21] to [1, 7] 8 }
3. the seemingly correct method is actually incorrect.
1 IntRand7 ()2 {3IntI;4I = rand5 () + rand5 () + rand5 () + rand5 () + rand5 () + rand5 () + rand5 () +Rand5 ();5ReturnI %7+1;6}
Like method 2, a new integer interval is constructed, but the integer interval constructed in method 3 is not equal probability.
In code 4th, 5 ^ 7 Possible computations will be generated, but these may eventually be mapped to the Integer Range of [7, 35, however, the probability of an integer in the [7, 35] interval is not equal.
For example, the interval of [1/8] can be obtained by accumulating the interval [3/8] Three times. However, the probability of each integer in [3/8] is not equal to 1/8, and, respectively.
References:
Introduction to Algorithms
Http://stackoverflow.com/questions/137783/expand-a-random-range-from-1-5-to-1-7? Page = 1 & tab = votes # tab-top
--