Почему это рекурсивное утверждение неверно?

Это банковская симуляция, которая учитывает 20 различных обслуживающих линий в одной очереди, клиенты приходят по экспоненциальной ставке и обслуживаются в течение времени, которое следует за нормальным распределением вероятности со средним 40 и стандартным отклонением 20.

Все работало нормально, пока я не решил исключить отрицательные значения, заданные нормальным распределением, используя этот метод:

def getNormal(self):

    normal = normalvariate(40,20)

    if (normal>=1):
        return normal
    else:
        getNormal(self)

Из-за чего программа время от времени выдаёт мне этот экран: ЭКРАН

Я испорчу рекурсивный вызов? Я не понимаю, почему это не сработает. Я изменил метод getNormal() на:

def getNormal(self):

    normal = normalvariate(40,20)

    while (normal <=1):
        normal = normalvariate (40,20)

    return normal

Но мне любопытно, почему предыдущее рекурсивное утверждение обанкротилось.

Это полный исходный код, если вам интересно.

""" bank21: One counter with impatient customers """
from SimPy.SimulationTrace import *
from random import *

## Model components ------------------------



class Source(Process):
    """ Source generates customers randomly """

    def generate(self,number):       
        for i in range(number):

            c = Customer(name = "Customer%02d"%(i,))

            activate(c,c.visit(tiempoDeUso=15.0))


            validateTime=now()
            if validateTime<=600:
                interval = getLambda(self)
                t = expovariate(interval)

                yield hold,self,t #esta es la rata de generación
            else:
                detenerGeneracion=999
                yield hold,self,detenerGeneracion



class Customer(Process):
    """ Customer arrives, is served and  leaves """

    def visit(self,tiempoDeUso=0):       
        arrive = now()       # arrival time                     
        print "%8.3f %s: Here I am     "%(now(),self.name)

        yield (request,self,counter),(hold,self,maxWaitTime)    
        wait = now()-arrive  # waiting time                     
        if self.acquired(counter):                              
            print "%8.3f %s: Waited %6.3f"%(now(),self.name,wait)

            tiempoDeUso=getNormal(self)
            yield hold,self,tiempoDeUso
            yield release,self,counter                          
            print "%8.3f %s: Completed"%(now(),self.name)
        else:
            print "%8.3f %s: Waited %6.3f. I am off"%(now(),self.name,wait)

## Experiment data -------------------------

maxTime = 60*10.5  # minutes                                 
maxWaitTime = 12.0 # minutes. maximum time to wait              

## Model  ----------------------------------

def model():                                                    
    global counter                                              
    #seed(98989)
    counter = Resource(name="Las maquinas",capacity=20)                            
    initialize()
    source = Source('Source')
    firstArrival= expovariate(20.0/60.0) #chequear el expovariate
    activate(source,
             source.generate(number=99999),at=firstArrival)   
    simulate(until=maxTime)                                     


def getNormal(self):

    normal = normalvariate(40,20)

    if (normal>=1):
        return normal
    else:
        getNormal(self)

def getLambda (self):

        actualTime=now()
        if (actualTime <=60):
            return 20.0/60.0
        if (actualTime>60)and (actualTime<=120):
            return 25.0/60.0
        if (actualTime>120)and (actualTime<=180):
            return 40.0/60.0
        if (actualTime>180)and (actualTime<=240):
            return 30.0/60.0
        if (actualTime>240)and (actualTime<=300):
            return 35.0/60.0
        if (actualTime>300)and (actualTime<=360):
            return 42.0/60.0
        if (actualTime>360)and (actualTime<=420):
            return 50.0/60.0
        if (actualTime>420)and (actualTime<=480):
            return 55.0/60.0
        if (actualTime>480)and (actualTime<=540):
            return 45.0/60.0
        if (actualTime>540)and (actualTime<=600):
            return 10.0/60.0
## Experiment  ----------------------------------
model()

3 ответа

Решение

Я думаю ты хочешь

return getnormal(self)

вместо

getnormal(self)

Если функция завершается, не нажимая оператор return, она возвращает специальное значение None, которое является объектом NoneType, поэтому Python жалуется на NoneType. Функция abs() хочет число, и она не знает, что делать с None.

Кроме того, вы можете избежать рекурсии (и затрат на создание нового стека), используя

def getNormal(self):
    normal = 0
    while normal < 1:
        normal = normalvariate(40,20)
    return normal

Тебе нужно иметь:

return getNormal(self)

вместо

getNormal(self)

На самом деле, рекурсия не нужна:

def getNormal(self):
    normal = 0
    while normal < 1:
        normal = normalvariate(40,20)

    return normal

Я не совсем уверен, но я думаю, что вам нужно изменить свой метод на следующий:

def getNormal(self):

normal = normalvariate(40,20)

if (normal>=1):
    return normal
else:
    return getNormal(self)
Другие вопросы по тегам