Почему это рекурсивное утверждение неверно?
Это банковская симуляция, которая учитывает 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)