가중 난수 정보
이해를 돕기 위해 먼저 세 가지 유형의 난수 문제를 비교해 보겠습니다.
1. n개의 레코드가 있습니다. m개 레코드 중에서 선택한 레코드의 순서는 중요하지 않습니다.
구현 아이디어: 모든 레코드를 행별로 순회하고 n/m 레코드마다 하나의 데이터를 가져옵니다
2. 유형 1에서는 선택한 m 레코드도 무작위로 정렬해야 합니다
구현 아이디어: n개의 레코드에 대해 마커 열을 추가하면 값은 1과 n 사이에서 무작위로 선택된 중복되지 않은 데이터입니다.
3. 1종, 2종 문제와 다르게, 레코드에 가중치가 있는 경우 가중치를 기준으로 무작위로 선택하는 방법입니다. 예를 들어 A의 가중치가 10, B의 가중치가 5, C의 가중치가 1이라면 4를 무작위로 선택했을 때 AABB가 나타날 것입니다.
세 번째 유형의 질문이 이 글의 초점입니다.
구현 아이디어: A:10, B:5, C:1 중에서 무작위로 선택된 4개의 레코드를 예로 듭니다(가중치 기준으로 정렬되어 있는지는 중요하지 않습니다)
A 10의 경우
B 5
C 1
먼저 n번째 행의 값을 n번째 행과 n-1번째 행에 대입하고 다음과 같이 재귀적으로 실행합니다.
A 10
B 15
C 16
그런 다음 매번 [1,16]에서 무작위로 숫자를 선택합니다. [1,10]에 속하면 A를 선택하고, (10,15]에 속하면 B를 선택합니다. (16),16] 중에서 C를 선택하세요. 그림과 같이 간격이 큰 쪽(가중치가 높은 쪽)이 선정될 확률이 높아집니다. 🎜>
복권 및 게임에 적용됩니다. 폭발물 장비
권위 있는 무작위화는 게임 개발, 각종 복권 추첨 및 폭발물 장비 등에 많이 사용됩니다.필요에 따라 작동하여 각 아이템이 나타날 확률을 구성합니다.
의 아이디어 오늘 우리가 이야기할 가중 무작위 알고리즘은 매우 간단합니다. 즉, 모든 항목은 가중치에 따라 간격으로 구성되며, 가중치가 큰 간격은 더 커집니다. 그러면 파이 차트로 상상될 수 있습니다. 주사위를 던져 어느 범위에 속하는지 확인해보세요. "
주최자가 설정한 무게는 [('iphone ', 10), ('ipad', 40), ('itouch', 50)].아이디어는 한 줄의 코드, 즉 random.choice(['iphone']*10으로 설명할 수 있습니다. + ['ipad']*40 + ['itouch']*50).
이하에서는 일반함수로 작성하겠습니다.
#coding=utf-8 import random 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)])
#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):#累和.如accumulate([10,40,50])->[10,50,100] 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()
복권 및 게임 장비 폭발 문제를 해결하기 위한 Python의 가중치 난수 사용과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요! >