2016-08-06 53 views
0

嘗試了python中的一些OOP,我嘗試創建一個Monty Hall問題模擬,它給出了奇怪的結果。我實現了玩家可以選擇的三種不同的策略,既可以選擇第一個門,也可以選擇第二個關閉的門,或者在它們之間隨意選擇。Python OOP Monty Hall沒有給出預期的結果

import random 

class Door(): 
    behind = None 
    is_open = False 
    is_chosen = False 
    def __init__(self,name=None): 
    self.name = name 
    def open(self): 
    self.is_open = True 
    def choose(self): 
    self.is_chosen = True 

class Goat(): 
    is_a = 'goat' 

class Car(): 
    is_a = 'car' 

class Player(): 
    door = None 
    def choose(self,door): 
    self.door = door 
    self.door.choose() 
    def open(self): 
    self.door.open() 
    if self.door.behind.is_a == 'car': 
     return True 
    return False 


def play(strategy): 
    player = Player() 
    items = [Goat(),Goat(),Car()] 
    doors = [Door(name='a'),Door(name='b'),Door(name='c')] 
    for door in doors: 
    item = items.pop() 
    door.behind = item 
    random.shuffle(doors) 
    player.choose(random.choice(doors)) 
    if strategy == 'random': 
    if random.choice([True,False]): 
     for door in doors: 
     if not door.is_open and not door.is_chosen: 
      final = door 
      break 
    else: 
     final = player.door 
    elif strategy == 'switch': 
    for door in doors: 
     if not door.is_open and not door.is_chosen: 
     final = door 
     break 
    elif strategy == 'stay': 
    final = player.door 
    player.choose(final) 
    if player.open(): 
    return True 
    else: 
    return False 


## Play some games 
for strategy in ['random','switch','stay']: 
    results = [] 
    for game in range(0,10000): 
    if play(strategy): 
     results.append(True) 
    else: 
     results.append(False) 

    ## Gather the results 
    wins = 0 
    loses = 0 
    for game in results: 
    if game: 
     wins += 1 
    else: 
     loses += 1 
    print 'results:\tstrategy={}\twins={}\tloses={}'.format(strategy,str(wins),str(loses)) 

但每次我運行它的時候,我得到的是這樣的:

results:  strategy=random wins=3369  loses=6631 
results:  strategy=switch wins=3369  loses=6631 
results:  strategy=stay wins=3320  loses=6680 

爲什麼這讓幾乎每個策略相同的結果? 「轉換」策略不應該給出66%的勝率和「停留」給出33%的比率?

+0

順便說一句,它並沒有太大的差別了這一方案,但它在Python 2建議對你的類繼承'對象「,比如'class Door(object)',這樣你就可以得到新的類而不是舊的類(在Python 3中不存在舊類)。另外,爲什麼還要製作特別的山羊和汽車課程?您可能只需使用「山羊」和「汽車」字符串對象。它會更有效率,因爲解釋器知道字符串是不可變的,因此它可以在檢測到重複的字符串文字時「回收」相同的字符串對象。 –

回答

1

你沒有正確玩遊戲。參賽者選擇了一扇門之後,主人在另外兩扇門後面顯示一隻山羊,然後爲參賽者提供切換的機會 - 您可以選擇三個門而不是兩個門。這裏有一個修訂play()功能:

def play(strategy): 
    player = Player() 
    items = [Goat(), Goat(), Car()] 
    doors = [Door(name='a'), Door(name='b'), Door(name='c')] 

    random.shuffle(items) 

    for door in doors: 
     item = items.pop() 
     door.behind = item 

    player.choose(random.choice(doors)) 

    # player has chosen a door, now show a goat behind one of the other two 

    show = None 
    for door in doors: 
     if not (door.is_open or door.is_chosen) and door.behind.is_a == 'goat': 
      show = door 
      show.open() 
      break 

    # The player has now been shown a goat behind one of the two doors not chosen 

    if strategy == 'random': 
     if random.choice([True, False]): 
      for door in doors: 
       if not (door.is_open or door.is_chosen): 
        final = door 
        break 
     else: 
      final = player.door 

    elif strategy == 'switch': 
     for door in doors: 
      if not (door.is_open or door.is_chosen): 
       final = door 
       break 

    elif strategy == 'stay': 
     final = player.door 

    player.choose(final) 

    return player.open() 

產生類似的結果:

results: strategy=random wins=4977 loses=5023 
results: strategy=switch wins=6592 loses=3408 
results: strategy=stay wins=3368 loses=6632 
+0

D'oh!我不知道我怎麼沒有看到!我正慢慢開始把這個OOP事情弄下來...... – user1777667

相關問題