2009-05-05 9 views
0

これは、1つのキューで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() 
+0

他の人々はまだ、離散イベントシミュレーションを書く見ることがうれしいです。私は2年前に卒業論文の巨大なシミュレーションに6ヶ月を費やしました。 –

+0

直交問題では、モジュールレベルの関数にパラメータとして "self"を渡すのはなぜですか? –

答えて

8

は、私はあなたが

return getnormal(self) 

代わりの

getnormal(self) 

関数がreturn文を押すことなく終了した場合したいと思います、それはNoneTypeオブジェクトがある特別な値Noneを返しませんそれがPythonが「NoneType」について不平を言う理由です。 abs()関数は数値を必要とし、Noneをどうしたらよいか分からない。

また、あなたはあなたが持っている必要があります

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

Doh ..私はすでにそれを行っていた(編集に加えられた)。しかし、ありがとう。私はあまりにも長い間、同じコードを探してきたと思います。 – andandandand

+0

私はこれを常に自分自身で行います。SchemeでプログラミングをしてPythonやC++に戻ったときには特に悪いことです(戻り値は常に最後のステートメントの結果であるため、明示的に返す必要はありません)。 – Charlie

1

を使用して再帰(および新しいスタックフレームを作成するコスト)を避けることができます:

return getNormal(self) 

代わりの

getNormal(self) 

実際には、再帰の必要はありません:

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

    return normal 
1

私は全くわからないが、私はあなたが以下にあなたの方法を変更する必要があると思う:

def getNormal(self): 

normal = normalvariate(40,20) 

if (normal>=1): 
    return normal 
else: 
    return getNormal(self) 
関連する問題