Transfer from http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.gocalf.com%2Fblog%2Funbalanced-coin.htmlUsing equal probability Rand5 to generate equal probability Rand3
The problem itself is very clear, but do not know what the topic is good, let's say so first.
Problem Description: There is now a function called Rand5, which can generate a random integer in the range of [0, 5) equal probability, requiring this function to write a Rand3 function (in addition to any function or data source that can produce a random number), generating a random integer in the range of [0, 3) equal probabilities.
The first time I encountered this problem, I really made a silly, self-righteous proof that the topic is non-solution. In fact, from the point of view of probability, the requirement of the topic is to use a 1/5 probability source, in some way generate 1/3 of the probability output. As we all know, the probability algorithm has addition and multiplication, and in my memory, the algorithms are "a set of well-defined rules used to solve a problem in a finite step", an important feature of the algorithm is the poor nature, that an algorithm must ensure that the execution of a finite number of steps after the end. So a finite number of 1/5 is not possible by addition and multiplication to 1/3, because neither addition nor multiplication will bring new factors to the denominator, so 3 of the denominator is not likely to occur at all.
However, I have overlooked such a formula:
∑I=0∞ ( 2 5) i = 11 − 25= 5 3
Based on this idea, let's take a look at what this algorithm looks like:
123456789 |
Rand3(){ xRand5(3x;} |
The algorithm is very simple, X is the number we will eventually output, as long as it is not in the range of [0, 3), and constantly call Rand5 to update it. Intuitively, the algorithm output of the number is only 0, 1, 2 of these three, and no partiality for any one, then obviously the probability of each number is 1/3, let us to strictly calculate.
Take the output 0 as an example to see what the probability is. The first valid value of x is obtained by RAND5. The probability that Rand5 returns 0 is 1/5, and if this happens, we get 0, otherwise we have a chance to call it again to get new data if Rand5 returns 3 or 4. After the second call to Rand5, there is a 1/5 probability that the probability of getting 0,2/5 3 or 4 causes the loop to continue executing, so repeatedly. So the probability is calculated as:
P=====15+25X(15+25X(15+25X(?)))15X∑∞I=0(25)I15X1 1−25 15 x 5313
Well, the calculation shows that the probability of Rand3 output 0 is indeed 1/3, for the other two numbers is the same.
Then this code is not an algorithm, whether it satisfies the poor nature of the algorithm? I am not sure, although it does not stop the probability is 0, however this probability is a limit value, alas, go back to review the limit knowledge first.
"November 7, 2013 Add" Today, I think, for the above function, you need to understand the time it consumes. Specifically, it is to know that the average call per Rand3, the equivalent of the number of times the call Rand5. According to the algorithm can be known, the RAND3 function is executed once, there is a 3/5 probability is to call only once Rand5 can stop, just call two times Rand5 after the probability of downtime is (2/5) * (3/5). By analogy, the probability of a stop after the K-Rand5 is called (2/5) ^ (k-1) * (3/5). Based on this probability distribution, it is possible to calculate the mathematical expectation of the number of Rand5 to be called before the outage, i.e.
∑K=1∞KXP(K)=∑K=1∞K35(25)K−1= 35x1 (1 − 25) 2=53
As you can see, the RAND3 function runs every time, averaging 1.67 calls to Rand5.
More generally, when we are based on the above algorithm, the distribution of a random signal to another random signal, if each consumption of M-source signal, there is a probability of p can produce a target signal, then on average, the number of source signals required before the outage is expected to be:
∑K=1∞k⋅ m⋅ p⋅ (1 −p) k−1< Span id= "mathjax-span-244" class= "Mo" >= mp
"November 7, 2013 add End"
Change the topic, if ask to use Rand5 write Rand7 what to do? Very simple, with two Rand5 can spell out the RAND25, and then the previous method can be:
12345 |
def rand7 (): x = -1 while not 0 <= x Span class= "o" >< 21: x = rand5< Span class= "P" > () * 5 + rand5 () Span class= "K" >return x % 7 |
123456789 |
Span class= "kt" >int rand7 () {int xdo {x = rand5 () Span class= "o" >* 5 + rand5 (); } while (x >= ); return x % 7;} |
"November 7, 2013" Can be calculated directly, according to this method, the average number of times per run Rand7, calls to Rand5. Here m equals 2,p equals 21/25, so the final result is 50/21, about 2.38.
Using equal probability Rand5 to generate equal probability Rand3