2012-04-29 41 views
4

我試圖用Python解決生日悖論。我很接近,但最後一塊讓我無所適從。我使用random來生成一個數字列表,給出了要創建的項目的範圍和數量。這樣可行。生日悖論列表是非類型

然後檢查一下(上面生成的)列表是否有重複。這樣可行。

然後我嘗試生成給定(n)的列表。這是我遇到麻煩的地方。它生成一個列表,然後返回「NoneType」不可迭代。令我困惑的是,該列表已生成,但Python並未將其視爲列表。

下面的代碼:

def make_bd(n, r): 
    """Generates (r) numbers of birthdays in a range (n).""" 
    import random 
    t = [random.randrange(n) for i in range(r)] 
    print (t) 


def has_dupe(test): 
    """Here I test to see if I can detect a duplicate birthday. 
This is based on problem #4.""" 

    d = [] 
    count = 0 
    for number in test: 
     if number in d: 
      count = count + 1 
     d.append(number) 
    if count >= 1: 
     return True 
    return False 

def dupebd(n,r,t): 
    count_dupe = 0 
    for i in range(n): 
     if has_dupe(make_bd(r,t)): 
      count_dupe = count_dupe + 1 
    print (float(count)/n)  

dupebd(50,365,23) 

這裏的結果:

>>> has_dupe(make_bd(50,6)) 
[13, 3, 8, 29, 34, 44] 
Traceback (most recent call last): 
    File "<pyshell#45>", line 1, in <module> 
    has_dupe(make_bd(50,6)) 
    File "<pyshell#44>", line 7, in has_dupe 
    for number in test: 
TypeError: 'NoneType' object is not iterable 
+1

注意你的算法會快很多,如果在'has_dupe'使用一組而不是列表爲'D'作爲測試一組中的成員比列表中的成員快得多。您也可以在發現一個重複項時立即返回「True」來使操作短路。你也可以用'len(set(test))== len(test)'''做同樣的測試,因爲集合不包含重複項。 –

+0

我會爲此努力。 –

回答

7

在第5行打印t,但不回吧,讓make_bd回報None。該行更改爲

return t 
+0

就是這樣!我還在上一個打印語句中錯誤地指定了count_dupe,但是添加返回修復了NoneType問題。謝謝! –

0
from random import randint 

def make_bd(n, d): 
    """Generates n birthdays in range(d).""" 
    return [randint(1, d) for _ in xrange(n)] 

def has_dupe(bd): 
    """Test to see if list of birthdays contains one or more duplicates. 
     This is based on problem #4. 
    """ 
    return len(set(bd)) < len(bd) 

def dupe_bd(n, d, t): 
    dupes = sum(has_dupe(make_bd(n,d)) for _ in xrange(t)) 
    return dupes/float(t) 

def exactProbability(n, d): 
    probUnique = 1.0 
    d = float(d) 
    for i in xrange(n): 
     probUnique *= (d - i)/d 
    return 1.0 - probUnique 

for n in xrange(18,26): 
    print("{:d} people: {:0.4f} probability of shared birthday (exact: {:0.4f})".format(n, dupe_bd(n, 365, 1000), exactProbability(n, 365))) 

18 people: 0.3640 probability of shared birthday (exact: 0.3469) 
19 people: 0.3790 probability of shared birthday (exact: 0.3791) 
20 people: 0.4020 probability of shared birthday (exact: 0.4114) 
21 people: 0.4070 probability of shared birthday (exact: 0.4437) 
22 people: 0.4720 probability of shared birthday (exact: 0.4757) 
23 people: 0.4980 probability of shared birthday (exact: 0.5073) 
24 people: 0.5290 probability of shared birthday (exact: 0.5383) 
25 people: 0.5450 probability of shared birthday (exact: 0.5687)