0

I'm starting out in python.. The details I have written in the below.. It goes to an infinite loop and give me an error when I try to call the function inside itself.. Is this kind of recursion not allowed ?

Posting code below.. Thanks for all your help :)

The program assumes that we have 100 passengers boarding a plane. Assuming if the first one has lost his boarding pass, he finds a random seat and sits there. Then the other incoming passengers sit in their places if unoccupied or some other random seat if occupied. The final aim is to find the probability with which the last passenger will not sit in his/her own seat. I haven't added the loop part yet which would make it a proper simulation. The question above is actually a puzzle in probability. I am trying to verify the answer as I don't really follow the reasoning.

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);

Please tell me if y'all get the same error.. ALso tell me if I am breaking any rules coz thisi sthe first question I'm posting.. Sorry if it seems too long.

This is how it should've been... The code does work fine in this case with the following mods :

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)  

I am using Python 2.6.6 on Windows 7, using a software from Enthought Academic Version of Python. http://www.enthought.com/products/getepd.php

Also the answer to this puzzle is 0.5 which is actually what I am getting(almost) by running it 10000 times.

I didn't see it here but it had to be available online.. http://www.brightbubble.net/2010/07/10/100-passengers-and-plane-seats/

ajrocker
  • 7
  • 2
  • 7
  • 2
    You say "Please tell me if y'all get the same error" but you don't even post the traceback .... – Jochen Ritzel May 27 '11 at 14:42
  • A couple of python tips: prefer xrange over range (xrange only holds a reference to 1 int at a time, which can be useful when using it in long running loops like the body of your assign (long running being a relative term)), using a triple quoted string on the first line after "def" is preferred over a comment because it will give the function a docstring, recursion is often overused considering it's costs and complexity. This may not be the best problem to solve recursively. – marr75 May 27 '11 at 14:50
  • 1
    @marr75: Considering the usage of `print` as a function rather than a statement, ajrocker is either using Python 3 or one of the versions of Python 2 that support the Python 3 syntax, and in the case of Python 3 `range()` is equivalent to Python 2's `xrange()`. – JAB May 27 '11 at 14:59
  • @ All : okay.. very very noob mistake. sorry for having caused the trouble... I actually didn't give the correct input to the cio() function... But i am very thankful for the help... :) Thanks, Ajrocker – ajrocker May 27 '11 at 15:04
  • @ajrocker: Don't apologize. Fix the question to be more clear. Identify the Python version, for example. – S.Lott May 27 '11 at 16:42
  • @JAB thanks for the clarification. I tried to jump into python 3 when it came out but for many library and tool related reasons could not, I sometimes forget that a lot of new python students are probably using py3.x. – marr75 May 27 '11 at 18:06
  • @marr75: It's fine. I, for one, was one of those "new python students" three years ago, and encountered the lack of certain library support fairly early on. In fact, just today I stumbled back upon a python module for console programs that I really liked the syntax of but was never able to get working for Python 3 back then due to C extension mishaps, and have started trying to get it to work again. – JAB May 27 '11 at 18:13

2 Answers2

0

Recursion, while allowed, isn't your best first choice for this.

Python enforces an upper bound on recursive functions. It appears that your loop exceeds the upper bound.

You really want some kind of while loop in 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

This may be more what you're trying to do.

Note the change to your comments. Triple-quoted string just after the def.

Chinmay Kanchi
  • 54,755
  • 21
  • 79
  • 110
S.Lott
  • 359,791
  • 75
  • 487
  • 757
  • I agree but should the limit be as small as 99 ? i agree with your code though.. This way is actually more efficient. and the assert thing.. I would've never added that..

    Thanks

    – ajrocker May 27 '11 at 14:47
  • @ajrocker: 99? How did you determine that 99 was the upper bound on your recursion? That's incorrect. There's no upper bound on the algorithm you implemented. – S.Lott May 27 '11 at 14:56
  • I see your point.. But if the random number generators are truly random the expected value of getting the loop terminated would be 99, would you agree ? – ajrocker May 27 '11 at 15:08
  • @ajrocker: "expected value of getting the loop terminated would be 99". That's false. http://www.mathgoodies.com/lessons/vol6/independent_events.html. You have a sequence of 1-P=.99 independent "failure to terminate" events followed by a P=.01 terminate event. That failure-to-terminate sequence can have an arbitrary number of values in it. – S.Lott May 27 '11 at 15:24
  • I was actually implying that the expected value of the passenger trying to get a seat would be 99 (actually it will be lower). That is the passenger will take 99 tries till he finds a vacant seat and since there are as many seats as passengers, he would eventually get a seat.. – ajrocker May 28 '11 at 08:56
  • @ajrocker: I'm actually saying (not implying) that the expected value is not 99. – S.Lott May 31 '11 at 12:54
0

you may be able to find the exact solution using dynamic programming http://en.wikipedia.org/wiki/Dynamic_programming For this you will need to add memoization to your recursive function: What is memoization and how can I use it in Python?

If you just want to estimate the probability using simulation with random numbers then I suggest you break out of your recursive function after a certain depth when the probability is getting really small because this will only change some of the smaller decimal places (most likely.. you may want to plot the change in result as you change the depth).

to measure the depth you could add an integer to your parameters: f(depth): if depth>10: return something else: f(depth+1)

the maximum recursion depth allowed by default is 1000 although you can change this you will just run out of memory before you get your answer

Community
  • 1
  • 1
robert king
  • 14,265
  • 8
  • 84
  • 107
  • @ robert : Thanks for the answer.. Actually I am looking to allocate seats to the passengers using recursion, checking if the seat that is randomly generated for them is occupied and if so generating some other.. So I can't really quit that.. :) – ajrocker May 27 '11 at 14:51
  • @ All : okay.. very very noob mistake. sorry for having caused the trouble... I actually didn't give the correct input to the cio() function... But i am very thankful for the help... :) Thanks, Ajrocker – ajrocker May 27 '11 at 15:03