Weighted random numbers are the probability of random numbers being extracted in different intervals according to their weights. here we will look at how Python uses weighted random numbers to solve the lottery and game brute force equipment problems, first, we will further explain the weighted random number:
About Weighted random numbers
For better understanding, let's first look at the comparison of three types of random problems:
1. n records exist, and m records are selected from them. The order of the selected records is different from that of the selected records.
Implementation idea: traverse all records by row and retrieve one data every n/m Records.
2. in the first case, the m Records selected must be sorted randomly.
Implementation idea: add a column of tags for n records, and the values are randomly selected from 1 to n without repeated data.
3. different from the 1 and 2 types of problems, if the record has a weight, how can we randomly select the records based on the weight. For example, if the weight of A is 10, the weight of B is 5, and the weight of C is 1, then AABB may appear when four weights are randomly selected.
This article focuses on the 3rd category of issues.
Implementation Method: Take four random records A: 10, B: 5, C: 1 as an example. (it doesn't matter whether weights are sorted)
For
A 10
B 5
C 1
First, assign the value of row n to row n plus row n-1 and perform recursion as follows:
A 10
B 15
C 16
Then, A random number is selected from [] each time. if it falls between [], A is selected. if it falls between (], B is selected, if the value falls between (16, 16], select C, as shown in the figure below. the selected range is large (with a high weight), and the probability of being selected is greater.
# Coding = UTF-8 import random def weighted_random (items): total = sum (w for _, w in items) n = random. uniform (0, total) # throw the dice for x, w in items in the pie chart: # traverse the interval where the dice are located if n
The above code is intuitive enough, but we will find that total is calculated every time, and the range is linearly traversed each time for the subtraction operation. in fact, we can save it first, just look up the table. use accumulate + bisect for binary search.
The more items, the more performance the binary search improves.
# Coding = UTF-8 class WeightRandom: def _ init _ (self, items): weights = [w for _, w in items] self. goods = [x for x, _ in items] self. total = sum (weights) self. acc = list (self. accumulate (weights) def accumulate (self, weights): # tired and. for example, accumulate ([100, 50])-> [,] cur = 0 for w in weights: cur = cur + w yield cur def _ call _ (self): return self. goods [bisect. bisect_right (self. acc, random. uniform (0, self. total)] wr = WeightRandom ([('iPhone ', 10), ('iPad', 40), ('itouch', 50)]) print wr ()
For more Python articles about lucky draw and game brute force using random numbers with weights, please pay attention to PHP!