Bisect
2018-07-08 本文已影响0人
raku
#coding=utf-8
import random
import bisect
n = random.uniform(0, 6)#在饼图扔骰子
print n
n = random.uniform(0, 6)#在饼图扔骰子
print n
n = random.uniform(0, 6)#在饼图扔骰子
print n
def weighted_random(items):
total = sum(w for _,w in items)
n = random.uniform(0, total)#在饼图扔骰子
for x, w in items:#遍历找出骰子所在的区间
if n<w:
break
n -= w
return x
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])
#coding=utf-8
class WeightRandom:
def __init__(self, items):
weights = [w for _,w,_ in items] # weights 是一个数组 数组中的元素来自于items中每个tuple中的w
self.goods = [x for x,_,_ in items]
self.total = sum(weights)
self.acc = list(self.accumulate(weights))
def accumulate(self, weights):#累和.如accumulate([10,40,50])->[10,50,100]
cur = 0
for w in weights:
cur = cur+w
yield cur
def __call__(self):
# print 'call acc', self.acc, self.goods
# self.acc 是概率和 [10, 50, 100]
rand = random.uniform(0, self.total)
rs = bisect.bisect_right(self.acc , rand)
print 'rs', rand, rs, self.goods[rs]
return self.goods[rs]
wr = WeightRandom([('iphone', 10, 10), ('ipad', 40, 10), ('itouch', 50, 10)])
ipadcount = 0
iphonecount = 0
itouchcount = 0
for i in range(1000):
rs = wr() ##call被调用
if rs == 'iphone':
iphonecount += 1
if rs == 'itouch':
itouchcount += 1
if rs == 'ipad':
ipadcount += 1
print iphonecount, ipadcount, itouchcount
def test():
items = [('iphone', 10), ('ipad', 40), ('itouch', 50)]
weights = [w for _,w in items]
print weights
def tty(weights):
cur = 0
for w in weights:
cur = cur+w
yield cur
rs = tty(weights) #得到一个generator对象
print 'rs', list(rs) # 一个数组
# test()