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

StackOverflow https://stackoverflow.com/questions/823141

  •  05-07-2019
  •  | 
  •  

Вопрос

Это имитация банка, которая учитывает 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()
Это было полезно?

Решение

Я думаю, что вы хотите

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

Другие советы

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

def getNormal(self):

normal = normalvariate(40,20)

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

Вы должны иметь:

return getNormal(self)

вместо

getNormal(self)

Правда, рекурсия не нужна:

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

    return normal
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top