【问题标题】:Infinite loop in simulation模拟中的无限循环
【发布时间】:2011-05-27 14:23:15
【问题描述】:

我从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)  

我在 Windows 7 上使用 Python 2.6.6,使用的是 Python 的 Enthought Academic Version 的软件。 http://www.enthought.com/products/getepd.php

这个谜题的答案也是 0.5,这实际上是我通过运行 10000 次得到的(几乎)。

我没有在这里看到它,但它必须在线提供.. http://www.brightbubble.net/2010/07/10/100-passengers-and-plane-seats/

【问题讨论】:

  • 你说“请告诉我你们是否都遇到同样的错误”,但你甚至没有发布回溯......
  • 一些python技巧:更喜欢xrange而不是range(xrange一次只保存一个对1个int的引用,这在长时间运行的循环中使用它时很有用,比如你的assign的主体(long运行是一个相对术语)),在“def”之后的第一行使用三引号字符串优于注释,因为它会给函数一个文档字符串,考虑到它的成本和复杂性,递归经常被过度使用。这可能不是递归解决的最佳问题。
  • @marr75:考虑到将print 用作函数而不是语句,ajrocker 正在使用 Python 3 或支持 Python 3 语法的 Python 2 版本之一,并且在Python 3 range() 的 case 等价于 Python 2 的 xrange()
  • @All : 好的.. 非常非常菜鸟的错误。很抱歉造成了麻烦...实际上我没有为 cio() 函数提供正确的输入...但我非常感谢您的帮助... :) 谢谢,Ajrocker
  • @ajrocker:不要道歉。修正问题以更清楚。例如,确定 Python 版本。

标签: python recursion infinite-loop


【解决方案1】:

虽然允许递归,但它不是您最好的首选。

Python 对递归函数实施上限。您的循环似乎超出了上限。

你真的想要某种 while 循环分配。

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

这可能是你想要做的更多。

注意对您的 cmets 的更改。在 def 之后的三引号字符串。

【讨论】:

  • 我同意,但限制应该小到 99 吗?我同意你的代码。。这种方式实际上更有效。和断言的东西..我永远不会添加那个..

    谢谢

  • @ajrocker: 99?您如何确定 99 是递归的上限?这是不正确的。您实现的算法没有上限。
  • 我明白你的意思。但如果随机数生成器是真正随机的,那么终止循环的预期值为 99,你同意吗?
  • @ajrocker:“终止循环的预期值为 99”。那是假的。 mathgoodies.com/lessons/vol6/independent_events.html。您有一系列 1-P=.99 独立的“终止失败”事件,然后是 P=.01 终止事件。该失败终止序列可以包含任意数量的值。
  • 我实际上是在暗示试图获得座位的乘客的期望值为 99(实际上它会更低)。也就是说,乘客将尝试 99 次,直到找到一个空座位,并且由于座位与乘客一样多,他最终会得到一个座位..
【解决方案2】:

您也许可以使用动态规划找到确切的解决方案 http://en.wikipedia.org/wiki/Dynamic_programming 为此,您需要在递归函数中添加记忆: What is memoization and how can I use it in Python?

如果你只是想使用随机数模拟来估计概率,那么我建议你在概率变得非常小时时在一定深度后打破你的递归函数,因为这只会改变一些较小的小数位(大多数可能......您可能希望在更改深度时绘制结果变化)。

要测量深度,您可以在参数中添加一个整数: f(深度): 如果深度>10: 还东西 否则:f(深度+1)

默认情况下允许的最大递归深度为 1000,尽管您可以更改此设置,但在得到答案之前您只会耗尽内存

【讨论】:

  • @robert :感谢您的回答。实际上我正在寻找使用递归为乘客分配座位的方法,检查为他们随机生成的座位是否被占用,如果是,则生成其他座位。所以我真的不能放弃.. :)
  • @All : 好的.. 非常非常菜鸟的错误。很抱歉造成了麻烦...实际上我没有为 cio() 函数提供正确的输入...但我非常感谢您的帮助... :) 谢谢,Ajrocker
猜你喜欢
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2019-11-13
  • 2012-12-24
相关资源
最近更新 更多