2014-01-15 2 views
3

'p'또는 'q'의 입력 빈도를 기반으로 'p'를 생성하기 위해 다음 클래스를 구현했습니다. 그러나 빈도가 옵션을 저장하는 데 사용되는 목록의 크기보다 작아지면이 구현이 중단됩니다. p의 값에 상관없이 작동하도록 구현할 수있는 방법이 있습니까?확률 가중치 임의의 문자열 생성기

from random import random 

class AlleleGenerator(object): 
    """ 
    allele generator - will break if p < 0.001 
    """ 
    def __init__(self, p): 
     """construct class and creates list to select from""" 
     self.values = list() 
     for i in xrange(int(1000*p)): 
      self.values.append('p') 
     while len(self.values) <= 1000: 
      self.values.append('q') 
    def next(self): 
     """Returns p or q based on allele frequency""" 
     rnd = int(random() * 1000) 
     return self.values[rnd] 
    def __call__(self): 
     return self.next() 
+2

필수 읽기 : 예를 들어, generator function 사용을 고려할 수 //eli.thegreenplace : [가중 무작위로 생성 (HTTP에 Bendersky의 기사를. net/2010/01/22/weighted-random-generation-in-python /)을 파이썬으로 작성했습니다. – DSM

답변

6

self.values을 사용하지 마십시오. next에서 단지 0과 1 사이의 난수를 생성하고, 난수가 적은 p 넘으면 'p'를 반환 : 함수가 충분 때

from random import random 

class AlleleGenerator(object): 
    def __init__(self, p): 
     """construct class and creates list to select from""" 
     self.p = p 
    def next(self): 
     """Returns p or q based on allele frequency"""    
     return 'p' if random() < self.p else 'q' 
    def __call__(self): 
     return self.next() 

는 또한 not to use classes 조심. 이상의 두 가지 값에 적응해야하는 경우,

from random import random 

def allele_generator(p): 
    while True: 
     yield 'p' if random() < p else 'q' 

agen = allele_generator(0.001) 
for i in range(3): 
    print(next(agen)) 
+0

균일하게 배포하려면'random.uniform()'를 사용하는 것이 좋습니다. 나는'random.random()'이 통계적으로 정확한 알고리즘을 만들기에 충분하게 균등하게 분산 된 값들의 시퀀스를 산출한다고 생각하지 않는다. –

+2

@SilasRay : [random.uniform] (http://hg.python.org/cpython/file/0056aaf42bf7/Lib/random.py#l340)는'random.random'을 호출합니다. 'random.uniform'는 임의의 범위'[a, b]에 난수를 생성 할 때 유용합니다. '[0, 1]'범위에서는'random.random'을 사용하십시오. – unutbu

+0

흠, 사실 ... 코드를 살펴보면 인터넷 검색에서 Wichman-Hill을 사용하여 안정적으로 훌륭한 균일 한 분포가 생성 된 것으로 보입니다. 나는 교정했다. :) –