¿Por qué esta afirmación recursiva es incorrecta?
Pregunta
Esta es una simulación bancaria que toma en cuenta 20 líneas de servicio diferentes con una sola cola, los clientes llegan siguiendo una tasa exponencial y reciben servicio durante un tiempo que sigue una distribución de probabilidad normal con media 40 y desviación estándar 20.
Las cosas funcionaron bien hasta que decidí excluir los valores negativos dados por la distribución normal usando este método:
def getNormal(self):
normal = normalvariate(40,20)
if (normal>=1):
return normal
else:
getNormal(self)
¿Estoy arruinando la llamada recursiva? No entiendo por qué no funcionaría. He cambiado el método getNormal () a:
def getNormal(self):
normal = normalvariate(40,20)
while (normal <=1):
normal = normalvariate (40,20)
return normal
Pero tengo curiosidad sobre por qué la declaración recursiva anterior se rompe.
Este es el código fuente completo, en caso de que esté interesado.
""" 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()
Solución
Creo que quieres
return getnormal(self)
en lugar de
getnormal(self)
Si la función se cierra sin llegar a una declaración de retorno, devuelve el valor especial Ninguno, que es un objeto Ninguno, por lo que Python se queja de un 'Ninguno'. La función abs () quiere un número y no sabe qué hacer con ninguno.
Además, podría evitar la recursión (y el costo de crear un nuevo marco de pila) utilizando
def getNormal(self):
normal = 0
while normal < 1:
normal = normalvariate(40,20)
return normal
Otros consejos
No estoy completamente seguro, pero creo que necesita cambiar su método a lo siguiente:
def getNormal(self):
normal = normalvariate(40,20)
if (normal>=1):
return normal
else:
return getNormal(self)
Necesitas tener:
return getNormal(self)
en lugar de
getNormal(self)
Realmente, sin embargo, no hay necesidad de recursión:
def getNormal(self):
normal = 0
while normal < 1:
normal = normalvariate(40,20)
return normal