2013-03-22 2 views
0

с помощью питону 3.3, я должен ответить на следующие вопросы:Вероятности вытягивать Discs (питон)

из коробки полных дисков, мы хотели бы знать вероятность вытягивать два синих диски в ряде когда все диски в коробке либо красные, либо синие. Напишите функцию, которая может вычислить эту вероятность для поля, заполненного любым количеством красных дисков и любым количеством синих дисков. Тест-драйв, который вы можете использовать: если в коробке содержится 15 синих дисков и 6 красных дисков , у вас есть 50% -ный шанс рисовать два синих диска подряд.

Теперь напишите функцию, которая вычисляет вероятность рисования n синих дисков в строке для , где n находится между 0 и числом дисков в поле.

я попытался с помощью этой модели

import random 
def random_pick(some_list, probabilities): 
    x = random.uniform(0, 1) 
    cumulative_probability = 50.0 
    for item, item_probability in zip(some_list, probabilities): 
     cumulative_probability += item_probability 
     if x < cumulative_probability: break 
    return item 

я почти полностью утрачена. Пожалуйста помоги.

+1

Существует три способа решения этой проблемы. Первое - это [Моделирование по методу Монте-Карло] (http://en.wikipedia.org/wiki/Monte_Carlo_method), где вы пробуете большое количество случайных значений и подсчитываете результаты. Второй - фактически рассчитать вероятности посредством математического анализа. Третий - перечислить все возможные результаты. –

+0

Как указывает Марк, существует множество способов решить эту проблему, о которой вы должны знать. Я дал ответ на самый простой вопрос для такой проблемы, но я поддержал Марка, потому что я думаю, что знание других статистических методов, с помощью которых вы могли бы достичь решения, важно. – Tawnos

+0

@Mark, Monte Carlo на самом деле не решает его, но может обеспечить полезное приближение –

ответ

0

P(blue) = P(blue 1) * P(blue 2) * ... * P(blue n) Если есть 15 синих дисков и 6 красных, всего 21. P(blue 1) - 15/21 = .7143. Сейчас осталось 20 дисков, 14 из которых синие. Таким образом, P(blue 2) составляет 14/20 = 0,7. 0.7143 * 0.7 = 0.5

Вы можете повторить это, несмотря на то, что вам нужно много тянуть.

В псевдокоде:

probabilityOfBlue (numBlueInDeck, numRedInDeck, numBlueToPull) 
    if (numBlueToPull > numBlueInDeck or numBlueToPull < 0 or (numBlueInDeck + numRedInDeck) == 0) 
    return 0 

    probability = 1.0 
    i = 0 
    while i < numBlueToPull 
    probability = probability * (numBlueInDeck/(numBlueInDeck + numRedInDeck)) 
    numBlueInDeck = numBlueInDeck - 1 
    i = i + 1 

    return probability 
+0

Большое спасибо.У меня есть проблема с реализацией этой информации в формате функции. Вы можете мне помочь? – Kuma

+0

добавлен псевдокод с использованием итерационного решения. Так как это домашнее задание, я оставляю это для вас, чтобы реализовать фактический код :) – Tawnos

+0

спасибо, Какую часть функции выполняет 15 и 6? а также относится ли эта функция к первому или второму вопросу, который я задал? – Kuma

1

Вероятность нанесения одного синий диска равна отношению синих дисков к общему количеству дисков, например, если у вас есть 2 синих диски и 2 красных дисков у вас есть 0.5 изменение рисунка синим.

Если вы хотите нарисовать второй диск, так как вы уже удалили один синий цвет, вам нужно рассчитать вероятность с одним меньшим (синим) диском. Итак, теперь у вас есть 1 синий 2 красных диска и, следовательно, 1/3 проб. Поскольку эта вероятность зависит от первого условия, вам нужно умножить две вероятности, т. Е. 1/2 * 1/3.

В общем:

def prob_blue_inrow(numb, numr, n): 
    p = numb/(numr + numb * 1.0) 
    if (n == 1): 
    return p 
    else: 
    return p * prob_blue_inrow(numb - 1, numr, n - 1) 

print(prob_blue_inrow(15, 6, 2)) 
+0

спасибо :) эта функция для первого или второго вопроса? – Kuma

+0

это второй, если вы передаете 2 для 'n', то это первый тоже – perreal

+0

Это ответ для обоих. Для первого n = 2. Это рекурсивное решение, которое может вызвать проблемы, если numb, numr и n слишком велики (переполнение стека). Тем не менее, это хвост рекурсивный, поэтому контекст кадра можно отбросить, и он, вероятно, будет работать в сборке без отладки практически для любого значения n. – Tawnos

1

Перечень всех случаев не слишком ресурсоемкие для этого случая

>>> from itertools import combinations 
>>> sum('r' not in x for x in combinations('b' * 15 + 'r' * 6, 2)) 
105 
>>> sum(1 for x in combinations('b'*15+'r'*6, 2)) 
210 
>>> 105/210.0 
0.5 

Даже 1000 синий и 1000 красный можно перечислить гораздо меньше, чем за секунду. Он работает очень плохо, если вы увеличиваете количество образцов, чтобы сказать 3, хотя :)

+0

как это можно записать как функцию? – Kuma

+0

@AkumaUkpo Я стараюсь быть вежливым здесь, но stackoverflow на самом деле не является форумом, чтобы задавать основные вопросы синтаксиса. Мое скромное мнение заключается в том, что проблема, которую вы решаете решить, немного еще слишком сложна. Я могу порекомендовать www.learnpythonthehardway.org как отличный учебник по основам. – ecline6

Смежные вопросы