2012-02-27 35 views
2

我需要SimPy建模火車系統(如地鐵系統)的幫助,問題是我的「模擬」老師想讓我使用Python + SimPy,而我沒有線索如何使用它,經過一週閱讀關於SimPy我設法瞭解銀行的例子,這很容易,但現在我仍然不知道如何模擬老師給我的問題...需要SimPy建模火車系統的幫助

這個問題很大而且很廣泛,但我只需要一點幫助,而不是整個項目的完成,所以,如果有人能夠幫助我,我會非常欣賞。

降低的問題,這將有助於我開始是這樣的:

想象你有3個站(A,B,C)相隔一段距離(可以說100米)和我有2個火車,一個在A和C上的一個(train1從A到C,tran2從C到A),其中每個列車具有最大速度(可以說50米/秒)和加速度(例如5米/秒^ 2和-5米/ s^2),他們所要做的就是在每個車站停下幾秒鐘(讓我們說24秒)並繼續到下一個車站,當他們到達最後時,他們會等待和額外的20秒(更換導軌)然後再重新開始。

該站有乘客的限制(他們不需要模擬)的唯一的事情是,每個站都有乘客的隨機數,當列車到達一定起牀,別人得到了下來...

所以,基本上我需要一個小火車模型和這3個車站的車站...如果有人能幫助我,請...

真正的問題有22個車站,2個車站改變車道,等待的隨機時間,42個具有不同最大速度和容量的列車,根據車站和一天中的不同時間產生的不同乘客數量等......我可以稍後管理所有這些東西,但是火車站的建模邏輯系統我似乎無法弄清楚...感謝您的幫助!

回答

7

我絕不用的SimPy的專家,但這應該讓你開始:

""" 
Simulation of a train network 
""" 
from SimPy.Simulation import * 
from math import sqrt 
from random import randint 
from itertools import cycle 

def timeTo(A, maxV, d): 
    """ 
    Given a trapezoidal velocity envelope defined by 
    A  constant acceleration, m/s/s 
    maxV maximumum velocity, m/s 
    return time in seconds required to travel 
    d  distance, m 
    """ 
    tA = float(maxV)/A   # time to accelerate to maxV 
    dA = A*tA*tA    # distance traveled during acceleration from 0 to maxV and back to 0 
    if (d < dA):    # train never reaches full speed? 
     return sqrt(4.0*d/A)  # time needed to accelerate to half-way point then decelerate to destination 
    else: 
     return 2*tA + (d-dA)/maxV # time to accelerate to maxV plus travel at maxV plus decelerate to destination 

class Train(Process): 
    def __init__(self, name, sim, accel=1.0, maxV=50.0, passengers=0, maxPassengers=400): 
     super(Train, self).__init__(name, sim) 
     self.accel = accel 
     self.maxV = maxV 
     self.p  = passengers 
     self.maxP = maxPassengers 

    def roll(self, route): 
     here = route.next()  # starting location 
     for dest in route: 
      # travel to next station 
      print "{:.1f}s: {} leaving {} for {}".format(self.sim.now(), self.name, here, dest) 
      yield hold, self, timeTo(self.accel, self.maxV, here.distanceTo[dest]) 
      # arrive at next station 
      here = dest 
      print "{:.1f}s: {} at {}".format(self.sim.now(), self.name, here) 
      yield hold, self, here.arrive(self) 

    def getOff(self, num): 
     if self.p >= num: 
      print " {} passengers got off".format(num) 
      self.p -= num 
     else: 
      num = self.p 
      print " train is empty - only {} passengers got off".format(num) 
      self.p = 0 

    def getOn(self, num): 
     if (self.maxP is None) or (self.p + num <= self.maxP): 
      print " {} passengers got on".format(num) 
      self.p += num 
     else: 
      num = self.maxp - self.p 
      print " train is full - only {} passengers got on".format(num) 
      self.p = self.maxp 

class TrackNode(object): 
    def __init__(self, name, delay=5.0): 
     self.name = name 
     self.delay = delay 
     self.distanceTo = {} 
    def arrive(self, train): 
     pass 
    def __str__(self): 
     return self.name 

class Station(TrackNode): 
    def arrive(self, train): 
     train.getOff(randint(1,15)) 
     train.getOn(randint(1,15)) 
     return self.delay 

class Switch(TrackNode): 
    def arrive(self, train): 
     print(" switching tracks") 
     return self.delay 

class SampleRailroad(Simulation): 
    def run(self, maxTime=100.0): 
     self.initialize() 
     # create places 
     x = Switch("switch x", 20.0) 
     A = Station("Station A", 24.0) 
     B = Station("Station B", 27.0) 
     C = Station("Station C", 25.0) 
     y = Switch("switch y", 18.0) 
     # distances between places 
     x.distanceTo[A] = 50.0 
     A.distanceTo[B] = 5000.0 
     B.distanceTo[C] = 2000.0 
     C.distanceTo[y] = 80.0 
     y.distanceTo[C] = 80.0 
     C.distanceTo[B] = 2000.0 
     B.distanceTo[A] = 5000.0 
     A.distanceTo[x] = 50.0 
     # set up first train 
     sf = Train("Santa Fe 219", self) 
     self.activate(sf, sf.roll(cycle([A,B,C,y,C,B,A,x])), at=0.0) 
     # set up second train 
     cn = Train("Canadian National 41", self, maxPassengers=200) 
     self.activate(cn, cn.roll(cycle([C,B,A,x,A,B,C,y])), at=5.0) 
     # start simulating! 
     self.simulate(until=maxTime) 

def main(): 
    rr = SampleRailroad() 
    rr.run(800.0) 

if __name__=="__main__": 
    main() 
+0

我創建了一個框架simplying這些類型的模擬用的simpy。請參閱:https://github.com/dov/onedmotion/blob/master/xz-motion.py。 – 2015-06-07 10:41:50