Бесконечный цикл в симуляции

Я начинаю с python. Подробности, которые я написал ниже.. Он переходит в бесконечный цикл и выдает мне ошибку, когда я пытаюсь вызвать функцию внутри себя.. Такая рекурсия не разрешена?

Код публикации ниже .. Спасибо за вашу помощь :)

Программа предполагает, что у нас 100 пассажиров садятся в самолет. Предполагая, что первый потерял посадочный талон, он находит случайное место и садится на него. Затем другие входящие пассажиры садятся на свои места, если они не заняты, или на другие случайные места, если они заняты. Конечная цель — найти вероятность того, что последний пассажир не сядет на свое место. Я еще не добавил часть петли, которая сделала бы ее правильной симуляцией. Приведенный выше вопрос на самом деле представляет собой загадку вероятности. Я пытаюсь проверить ответ, поскольку я действительно не следую рассуждениям.

import random
from numpy import zeros

rand = zeros((100,3))
# The rows are : Passenger number , The seat he is occupying and if his designated     seat is occupied. I am assuming that the passengers have seats which are same as the order in which they enter. so the 1st passenger enter has a designated seat number 1, 2nd to enter has no. 2 etc.

def cio(r):  # Says if the seat is occupied ( 1 if occupied, 0 if not)
    if rand[r][2]==1:
        return 1
    if rand[r][2]==0:
        return 0

def assign(ini,mov):    # The first is passenger no. and the second is the final seat he gets. So I keep on chaning the mov variable if the seat that he randomly picked was occupied too. 
    if cio(rand[mov][2])== 0 :
        rand[mov][2] = 1
        rand[mov][1] = ini
    elif cio(rand[mov][2])== 1 :
        mov2 = random.randint(0,99)
 #       print(mov2)            Was used to debug.. didn't really help
        assign(ini,mov2)        # I get the error pointing to this line :(

# Defining the first passenger's stats.
rand[0][0] = 1
rand[0][1] = random.randint(1,100)
m = rand[0][1]
rand[m][2]= 1

for x in range(99):
    rand[x+1][0] = x + 2

for x in range(99):
    assign(x+1,x+1)

if rand[99][0]==rand[99][1] :
    print(1);
else :
    print(0);

Пожалуйста, сообщите мне, если у всех возникает одна и та же ошибка.. ТАКЖЕ сообщите мне, если я нарушаю какие-либо правила, потому что это первый вопрос, который я публикую.. Извините, если это кажется слишком длинным.

Вот как это должно было быть... В этом случае код работает нормально со следующими модами:

def assign(ini,mov):
if cio(mov)== 0 :     """Changed here"""
    rand[mov][2] = 1
    rand[mov][1] = ini
elif cio(mov)== 1 :    """And here"""
    mov2 = random.randint(0,99)
    assign(ini,mov2)  

Я использую Python 2.6.6 в Windows 7, используя программное обеспечение Enthought Academic Version of Python. http://www.enthought.com/products/getepd.php

Также ответом на эту загадку является 0,5, что на самом деле я получаю (почти), запуская ее 10000 раз.

Я не видел его здесь, но он должен был быть доступен в Интернете. "nofollow">http://www.brightbubble.net/2010/07/10/100-passengers-and-plane-seats/


person ajrocker    schedule 27.05.2011    source источник
comment
Вы говорите: «Пожалуйста, скажите мне, если вы все получите ту же ошибку, но вы даже не отправляете трассировку ....   -  person Jochen Ritzel    schedule 27.05.2011
comment
Несколько советов по Python: предпочитайте xrange диапазону (xrange содержит ссылку только на 1 int за раз, что может быть полезно при использовании его в длинных циклах, таких как тело вашего назначения (длительное выполнение является относительным термином)), использование строки в тройных кавычках в первой строке после def предпочтительнее комментария, потому что это даст функции строку документации, рекурсией часто злоупотребляют, учитывая ее стоимость и сложность. Возможно, это не лучшая проблема для рекурсивного решения.   -  person marr75    schedule 27.05.2011
comment
@ marr75: Учитывая использование print как функции, а не оператора, ajrocker либо использует Python 3, либо одну из версий Python 2, поддерживающих синтаксис Python 3, а в случае Python 3 range() эквивалентен Python 2. xrange().   -  person JAB    schedule 27.05.2011
comment
@ Все : ладно.. очень-очень нубская ошибка. извините за беспокойство... На самом деле я не правильно ввел функцию cio()... Но я очень благодарен за помощь... :) Спасибо, Ajrocker   -  person ajrocker    schedule 27.05.2011
comment
@ajrocker: Не извиняйся. Исправьте вопрос, чтобы было понятнее. Например, укажите версию Python.   -  person S.Lott    schedule 27.05.2011
comment
@JAB спасибо за разъяснение. Я пытался перейти на Python 3, когда он вышел, но по многим причинам, связанным с библиотекой и инструментами, не смог, я иногда забываю, что многие новые студенты, изучающие Python, вероятно, используют py3.x.   -  person marr75    schedule 27.05.2011
comment
@ marr75: Все в порядке. Я, например, был одним из тех новых студентов, изучавших Python три года назад, и довольно рано столкнулся с отсутствием поддержки некоторых библиотек. На самом деле, только сегодня я наткнулся на модуль python для консольных программ, синтаксис которого мне очень понравился, но из-за неудач с расширением C я так и не смог заставить его работать на Python 3, и начал пытаться снова заставить его работать. .   -  person JAB    schedule 27.05.2011


Ответы (2)


Рекурсия, хотя и разрешена, не лучший выбор для этого.

Python применяет верхнюю границу рекурсивных функций. Похоже, что ваш цикл превышает верхнюю границу.

Вам действительно нужен какой-то цикл while в assign.

def assign(ini,mov):    
   """The first is passenger no. and the second is the final seat he gets. So I keep on chaning the mov variable if the seat that he randomly picked was occupied too. 
   """
   while cio(rand[mov][2])== 1:
      mov = random.randint(0,99)

   assert cio(rand[mov][2])== 0
   rand[mov][2] = 1
   rand[mov][1] = ini

Это может быть больше того, что вы пытаетесь сделать.

Обратите внимание на изменение ваших комментариев. Строка в тройных кавычках сразу после def.

person S.Lott    schedule 27.05.2011
comment
Я согласен, но должен ли предел быть всего 99? хотя я согласен с вашим кодом. Этот способ на самом деле более эффективен. и утверждение.. Я бы никогда не добавил это.. ‹p› Спасибо - person ajrocker; 27.05.2011
comment
@ajrocker: 99? Как вы определили, что 99 было верхней границей вашей рекурсии? Это неправильно. В алгоритме, который вы реализовали, нет верхней границы. - person S.Lott; 27.05.2011
comment
Я понимаю вашу точку зрения. Но если генераторы случайных чисел действительно случайны, ожидаемое значение завершения цикла будет 99, вы согласны? - person ajrocker; 27.05.2011
comment
@ajrocker: ожидаемое значение завершения цикла будет 99. Это неверно. mathgoodies.com/lessons/vol6/independent_events.html. У вас есть последовательность из 1-P=.99 независимых событий отказа для завершения, за которыми следует событие завершения P=.01. В этой последовательности с отказом завершения может быть произвольное количество значений. - person S.Lott; 27.05.2011
comment
На самом деле я имел в виду, что ожидаемая стоимость пассажира, пытающегося занять место, будет равна 99 (на самом деле она будет ниже). То есть пассажиру потребуется 99 попыток, пока он не найдет свободное место, и, поскольку мест столько же, сколько пассажиров, он в конечном итоге получит место. - person ajrocker; 28.05.2011
comment
@ajrocker: я на самом деле говорю (не подразумевая), что ожидаемое значение не равно 99. - person S.Lott; 31.05.2011

вы можете найти точное решение, используя динамическое программирование http://en.wikipedia.org/wiki/Dynamic_programming Для этого вам нужно будет добавить запоминание в вашу рекурсивную функцию: Что такое запоминание и как я могу его использовать это на Python?

Если вы просто хотите оценить вероятность, используя моделирование со случайными числами, я предлагаю вам выйти из вашей рекурсивной функции после определенной глубины, когда вероятность становится действительно малой, потому что это изменит только некоторые из меньших десятичных знаков (скорее всего... вы можете захотеть отобразить изменение результата при изменении глубины).

чтобы измерить глубину, вы можете добавить целое число к своим параметрам: f (глубина): если глубина> 10: вернуть что-то еще: f (глубина + 1)

максимальная глубина рекурсии, разрешенная по умолчанию, составляет 1000, хотя вы можете изменить это, у вас просто не хватит памяти, прежде чем вы получите ответ

person robert king    schedule 27.05.2011
comment
@ robert Спасибо за ответ. На самом деле я пытаюсь выделить места пассажирам с помощью рекурсии, проверяя, занято ли случайно сгенерированное для них место, и если да, то генерирую какое-то другое. Так что я не могу бросить это .. :) - person ajrocker; 27.05.2011
comment
@ Все : ладно.. очень-очень нубская ошибка. извините за беспокойство... На самом деле я не правильно ввел функцию cio()... Но я очень благодарен за помощь... :) Спасибо, Ajrocker - person ajrocker; 27.05.2011