Python은 가중치 난수를 사용하여 복권 및 게임 장비 폭발 문제를 해결합니다.

高洛峰
풀어 주다: 2017-03-02 11:28:24
원래의
2453명이 탐색했습니다.

가중 난수 정보

이해를 돕기 위해 먼저 세 가지 유형의 난수 문제를 비교해 보겠습니다.
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를 선택하세요. 그림과 같이 간격이 큰 쪽(가중치가 높은 쪽)이 선정될 확률이 높아집니다. 🎜>

복권 및 게임에 적용됩니다. 폭발물 장비Python은 가중치 난수를 사용하여 복권 및 게임 장비 폭발 문제를 해결합니다.

권위 있는 무작위화는 게임 개발, 각종 복권 추첨 및 폭발물 장비 등에 많이 사용됩니다.

필요에 따라 작동하여 각 아이템이 나타날 확률을 구성합니다.
의 아이디어 오늘 우리가 이야기할 가중 무작위 알고리즘은 매우 간단합니다. 즉, 모든 항목은 가중치에 따라 간격으로 구성되며, 가중치가 큰 간격은 더 커집니다. 그러면 파이 차트로 상상될 수 있습니다. 주사위를 던져 어느 범위에 속하는지 확인해보세요. "

예를 들어 연말 복권이 있는데, 그 아이템은 아이폰/아이패드/아이터치입니다.

주최자가 설정한 무게는 [('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([(&#39;iphone&#39;, 10), (&#39;ipad&#39;, 40), (&#39;itouch&#39;, 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([(&#39;iphone&#39;, 10), (&#39;ipad&#39;, 40), (&#39;itouch&#39;, 50)]) 
print wr()
로그인 후 복사


복권 및 게임 장비 폭발 문제를 해결하기 위한 Python의 가중치 난수 사용과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요! >


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!