2009-01-26 14 views
7

मैं एन-पक्षीय पक्षपाती मरने का अनुकरण करना चाहता हूं?मैं पाइथन में पक्षपातपूर्ण मरने का अनुकरण कैसे करूं?

def roll(N,bias): 
    '''this function rolls N dimensional die with biasing provided''' 
    # do something 
    return result 

>> N=6 
>> bias=(0.20,0.20,0.15,0.15,0.14,0.16,) 
>> roll(N,bias) 
    2 
+0

क्या आपने इसे अपने अंतिम प्रश्न के स्थान पर नहीं पूछा था? http://stackoverflow.com/questions/477237/how-do-i-simulate-flip-of-biased-coin-in-python –

+4

मुझे लगता है कि आपका मतलब एन-पक्षीय मरना है। एक एन-आयामी मर काफी अलग है। – babbageclunk

+0

डुप्लिकेट: http://stackoverflow.com/questions/477237/how-do-i-simulate-flip-of-biased-coin-in-python –

उत्तर

23

नियमित मरने से प्रत्येक नंबर 1-6 बराबर संभावना के साथ, 1/6 प्रदान करेगा। इसे uniform distribution (इसके संस्करण का निरंतर संस्करण, निरंतर संस्करण के विपरीत) के रूप में जाना जाता है। जिसका अर्थ है कि यदि X है एक यादृच्छिक चर एक भी भूमिका का परिणाम का वर्णन तो X~U[1,6] - X अर्थ 1 के माध्यम से 6.

यह [0,1) समय में एक नंबर चुनने के बराबर है मरने रोल के सभी संभव परिणाम के खिलाफ समान रूप से वितरित किया जाता है, इसे 6 वर्गों में विभाजित करना: [0,1/6), [1/6,2/6), [2/6,3/6), [3/6,4/6), [4/6,5/6), [5/6,1)

आप एक अलग वितरण का अनुरोध कर रहे हैं, जो पक्षपातपूर्ण है। यह प्राप्त करने का सबसे आसान तरीका है कि आप चाहते हैं कि पूर्वाग्रह के आधार पर अनुभाग [0,1) से 6 भागों में विभाजित करें। तो आपके मामले में आप इसे निम्नलिखित में विभाजित करना चाहते हैं: [0,0.2), [0.2,0.4), [0.4,0.55), 0.55,0.7), [0.7,0.84), [0.84,1)

आप wikipedia entry पर एक नज़र डालें, तो आप इस मामले में है कि देखेंगे, संचयी संभावना समारोह 6 बराबर-लंबाई भागों से बना नहीं किया जाएगा, लेकिन पूर्वाग्रह के अनुसार नहीं बल्कि 6 भागों जो लंबाई में मतभेद आपने उन्हें दिया बड़े पैमाने पर वितरण के लिए चला जाता है।

आप जिस भाषा का उपयोग कर रहे हैं उसके आधार पर प्रश्न पर वापस जाएं, बस इसे अपने मरने के रोल में अनुवाद करें।

import random 
sampleMassDist = (0.2, 0.1, 0.15, 0.15, 0.25, 0.15) 

# assume sum of bias is 1 
def roll(massDist): 
    randRoll = random.random() # in [0,1) 
    sum = 0 
    result = 1 
    for mass in massDist: 
     sum += mass 
     if randRoll < sum: 
      return result 
     result+=1 

print roll(sampleMassDist) 
+0

यहां एक छोटी सी समस्या है। फ़्लोटिंग पॉइंट नंबरों में सीमित सटीकता है, और इसलिए वजन का योग आम तौर पर बिल्कुल नहीं होगा 1. मुझे नहीं पता कि यह प्रभाव कितना महत्वपूर्ण है, लेकिन इसके बजाय वजन के लिए पूर्णांक का उपयोग करना सुरक्षित हो सकता है। –

+0

@wcoenen: वे * यादृच्छिक * संख्याएं हैं। यादृच्छिक संख्याओं का कोई वितरण कभी भी दिए गए पूर्वाग्रह से मेल नहीं खा सकता है। यदि संख्याओं का सेट दिए गए पूर्वाग्रह से मेल खाता है, तो हमें इसे वास्तव में यादृच्छिक रूप से अस्वीकार करना होगा। –

+0

बहुत अच्छी गणितीय व्याख्या के लिए धन्यवाद। –

8

अधिक भाषा अज्ञेयवादी, लेकिन आप एक लुकअप टेबल का उपयोग कर सकते हैं।

रेंज 0-1 में एक यादृच्छिक संख्या का उपयोग करें और किसी तालिका में मूल्य देखने: यहां गणित का एक छोटा सा

0.00 - 0.20 1 
0.20 - 0.40 2 
0.40 - 0.55 3 
0.55 - 0.70 4 
0.70 - 0.84 5 
0.84 - 1.00 6 
+1

पक्षपातपूर्ण मरने के संदर्भ में, यह यादृच्छिक संख्या के समान वितरण का उल्लेख करने के लिए भुगतान कर सकता है :) –

4
import random 

def roll(sides, bias_list): 
    assert len(bias_list) == sides 
    number = random.uniform(0, sum(bias_list)) 
    current = 0 
    for i, bias in enumerate(bias_list): 
     current += bias 
     if number <= current: 
      return i + 1 

पूर्वाग्रह आनुपातिक हो जाएगा: अजगर में, यहाँ एक बहुत ही अधूरा, काम कर रहे, हालांकि उदाहरण है।

>>> print roll(6, (0.20, 0.20, 0.15, 0.15, 0.14, 0.16)) 
6 
>>> print roll(6, (0.20, 0.20, 0.15, 0.15, 0.14, 0.16)) 
2 

भी (बेहतर) पूर्णांकों का उपयोग किया जा सका:

>>> print roll(6, (10, 1, 1, 1, 1, 1)) 
5 
>>> print roll(6, (10, 1, 1, 1, 1, 1)) 
1 
>>> print roll(6, (10, 1, 1, 1, 1, 1)) 
1 
>>> print roll(6, (10, 5, 5, 10, 4, 8)) 
2 
>>> print roll(6, (1,) * 6) 
4 
+0

स्वच्छ समाधान का सुझाव देने के लिए धन्यवाद। –

1

अलग probablities साथ यादृच्छिक वस्तुओं के लिए Walker's alias method के लिए नुस्खा देखें।
एक उदाहरण, संभावनाओं के साथ ए बी सी या डी तार .1 .1 .3 .3।4 -

abcd = dict(A=1, D=4, C=3, B=2) 
    # keys can be any immutables: 2d points, colors, atoms ... 
wrand = Walkerrandom(abcd.values(), abcd.keys()) 
wrand.random() # each call -> "A" "B" "C" or "D" 
       # fast: 1 randint(), 1 uniform(), table lookup 

चियर्स
- डेनिस

+0

अच्छा लग रहा है लेकिन क्या आप विस्तृत करेंगे? –

+0

डेविड, कुछ पक्षों पर पूर्वाग्रहित मरने/1 डी वितरण के लिए, टेबल लुकअप ठीक है, वाकर की विधि ओवरकिल; 312 में कई सितारों के वितरण के लिए , वाकर का उपयोग करें। (क्या नुस्खा/इसके रेफरी बिल्कुल समझ में आया?) – denis

0

बस एक अधिक कुशल (और pythonic3) समाधान सुझाने के लिए, एक संचित मूल्यों का वेक्टर में खोज करने के लिए bisect उपयोग कर सकते हैं - कि इसके अलावा precomputed किया जा सकता है और उम्मीद में संग्रहीत किया जाता है कि फ़ंक्शन के बाद की कॉल उसी "पूर्वाग्रह" (प्रश्न अनुपालन का पालन करने के लिए) देखेंगे।

from bisect import bisect 
from itertools import accumulate 
from random import uniform 

def pick(amplitudes): 
    if pick.amplitudes != amplitudes: 
     pick.dist = list(accumulate(amplitudes)) 
     pick.amplitudes = amplitudes 
    return bisect(pick.dist, uniform(0, pick.dist[ -1 ])) 
pick.amplitudes = None 

अजगर 3 संचित के अभाव में, एक बस संचयी योग की गणना करने के लिए एक सरल पाश लिख सकते हैं।

0
from random import random 
biases = [0.0,0.3,0.5,0.99] 
coins = [1 if random()<bias else 0 for bias in biases] 
1

यह आश्चर्य की बात है कि np.random.choice उत्तर यहां दिया गया नहीं है।

from numpy import random 
def roll(N,bias): 
    '''this function rolls N dimensional die with biasing provided''' 
    return random.choice(np.range(N),p=bias) 

पी का विकल्प देता है, जहां एक हमारे लिए np.range(N) कि "संभावनाओं एक में प्रत्येक प्रविष्टि के साथ जुड़े"। "यदि नमूना नहीं दिया गया है तो में सभी प्रविष्टियों पर एक समान वितरण मानता है"।

0

मैं एक शब्दकोश एक घटना और इसी संभावना देने के लिए एक कोड बनाया है, यह है कि संभावना की स्थिति यानी संबंधित कुंजी वापस देता है।

import random 


def WeightedDie(Probabilities): 


    high_p = 0 
    rand = random.uniform(0,1) 

    for j,i in Probabilities.items(): 
     high_p = high_p + i 
     if rand< high_p: 
      return j 
संबंधित मुद्दे