【问题标题】:Need help modeling a train system with SimPy需要帮助使用 SimPy 对火车系统进行建模
【发布时间】:2012-03-17 08:35:52
【问题描述】:

我需要帮助在 SimPy 中建模火车系统(如地铁系统),问题是我的“模拟”老师要我使用 Python + SimPy,但我不知道如何使用它,经过一周阅读有关 SimPy 我设法理解了银行示例,这很容易,但现在我仍然不知道如何为老师给我的问题建模......

这个问题很大而且很广泛,但我只需要一点帮助,而不是整个项目完成,所以,如果有人可以提供帮助,我将不胜感激。

帮助我入门的简化问题是这样的:

假设您有 3 个车站(A、B、C),相隔一定距离(比如说 100m),我有 2 列火车,一列在 A 上,一列在 C 上(train1 从 A 到 C,tran2 从 C 到A)每列火车都有最大速度(假设两者都为 50m/s)和加速度(假设为 5m/s^2 和 -5m/s^2 用于制动),他们所要做的就是在每个车站停下来几秒钟(假设是 24 秒)然后继续到下一个车站,当他们到达终点时,他们等待并额外等待 20 秒(换轨)然后重新开始。

车站有乘客限制(不需要模拟),唯一的问题是每个车站的乘客数量是随机的,当火车到达时,有人起床,有人下车......

所以,基本上我需要一个小模型的火车和这 3 个车站的车站...如果有人可以帮助我...

真正的问题有 22 个车站、2 个额外的变道车站、随机等待时间、42 列不同最大速度和容量的列车、根据车站和一天中的时间产生不同的乘客数量等等......所有这东西我以后可以管理,但火车站系统的建模逻辑我似乎无法弄清楚......谢谢你的帮助!

【问题讨论】:

    标签: python model simulation traffic-simulation simpy


    【解决方案1】:

    我绝不是 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()
    

    【讨论】:

    猜你喜欢
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多