python数据结构学习笔记-2016-11-05-03-计算机仿真

来源:互联网 发布:英魂之刃刷点卷软件 编辑:程序博客网 时间:2024/06/05 07:04

        8.4 应用:计算机仿真

        8.4.1 航空公司票务柜台

        本节对航空公司票务柜台进行仿真模拟。

        队列系统建模

       我们通过离散时间仿真来建模,这个仿真是一系列能显著改变系统的事件。它由时间驱动,并运行给定的时间。用户可以使用一些参数来设定系统。在这里,这些参数是

  • 系统运行的时长;
  • 柜台数量;
  • 完成一次交易的时间;
  • 顾客到来的时间分布。
        最后还要设定一些规则。

  • 顾客到来之后,自动加入到队列当中,每一个时间单位内至多只能到来一名顾客;
  • 一位顾客完成交易后,如果后面还有顾客等待,其后的一名顾客接着与柜台交易;
  • 顾客与柜台完成交易后,顾客离去,柜台此时处于空闲状态,等待下一名顾客与之交易。
        平均等待时间就等于所有顾客的等待时间之和除以顾客数量。

        随机事件

        本例中顾客到来就是随机事件。我们可以设定在单位时间内顾客到来的概率,可以理解为平均多长时间来一名顾客。再使用随机数生成器,生成[0, 1]之间的随机数,与顾客到来的概率进行比较,若小于,则顾客到来;若大于,则顾客不会来。


         8.4.2 实现

         系统参数

  • 系统运行时间是25min;
  • 柜台数量是2;
  • 顾客平均交易时间是3min;
  • 平均2min来一名顾客。

         顾客类

         顾客类中有两个属性,一个是ID号码,用于最后的信息打印输出,另一个是顾客到来时间,即第几分钟到来。这个值决定这这名顾客的等待时间。此外,还有两个方法,用于访问这两个属性。

# 顾客类class Passenger(object):    def __init__(self, idNum, arrivalTime):        self._idNum = idNum        self._arrivalTime = arrivalTime         def idNum(self):        return self._idNum    def timeArrived(self):        return self._arrivalTime
         

        柜台类

        柜台类中有三个属性,第一个是柜台的编号,第二个是当前顾客交易将会完成的时间,第三个是当前正在进行交易的顾客。另外,还有五个方法,第一个是返回柜台编号,第二个是判断柜台是否处于空闲状态,第三个是判断柜台与顾客是否完成交易,第四个是交易开始,最后一个是交易结束,柜台又处于空闲状态。

# 柜台类class TicketAgent(object):    def __init__(self, idNum):        self._idNum = idNum        self._passenger = None        self._stopTime = -1    # 柜台编号    def idNum(self):        return self._idNum    # 判断柜台是否空闲    def isFree(self):        return self._passenger is None    # 判断柜台与顾客是否完成交易    def isFinished(self, curTime):        return self._passenger is not None and self._stopTime == curTime    # 交易开始,需传入顾客,以及交易结束时间    def startService(self, passenger, stopTime):        self._passenger = passenger        self._stopTime = stopTime    # 交易结束,柜台又处于空闲状态    def stopService(self):        thePassenger = self._passenger        self._passenger = None        return thePassenger

      仿真类

      仿真类的属性比较多,首先是三个用户定义的参数,其后是创建队列和柜台实例,最后是两个在运行过程中跟踪的数据,是顾客的等待时间之和以及顾客数量。另外还有五个方法,第一个是运行系统,在一个循环内执行另外三个方法,分别是顾客到来并进入队列、顾客开始交易以及顾客完成交易离去。系统运行结束后,打印结果。

#-*-coding: utf-8-*-# 仿真类from myarray import Arrayfrom llistqueue import Queuefrom simpeople import TicketAgent, Passengerfrom random import randomclass TicketCounterSimulation(object):    def __init__(self, numAgents, numMinutes, betweenTime, serviceTime):        # 用户定义参数        self._arriveProb = 1.0 / betweenTime        self._serviceTime = serviceTime        self._numMinutes = numMinutes        # 仿真组件        self._passengerQ = Queue()        self._theAgents = Array(numAgents)        for i in range(numAgents):            self._theAgents[i] = TicketAgent(i+1)                # 仿真过程中,计算的参数        self._totalWaitTime = 0        self._numPassengers = 0    # 运行仿真    def run(self):        for curTime in range(1, self._numMinutes+1):            self._handleArrival(curTime)            self._handleBeginService(curTime)            self._handleEndService(curTime)    # 打印结果    def printResults(self):        numServed = self._numPassengers - len(self._passengerQ) # 所有交易过的顾客人数        avgWait = float(self._totalWaitTime) / numServed        print ""        print "Number of passengers served = %d" % numServed        print "Number of passengers remaining in line = %d" % len(self._passengerQ)        print "The average wait time was %4.2f minutes." % avgWait    # 处理第一条规则    def _handleArrival(self, curTime):        odds = random()        if odds <= self._arriveProb: # 使用随机数生成器,生成[0, 1]之间的随机数,与顾客到来的概率进行比较,若小于,则顾客到来;若大于,则顾客不会来。            self._numPassengers += 1            passenger = Passenger(self._numPassengers, curTime) # 使用self._numPassengers来记录顾客的编号            self._passengerQ.enqueue(passenger) # 顾客进入队列排队             print "Time %6d Passenger %d arrived." % (curTime, passenger.idNum())    # 处理第二条规则    def _handleBeginService(self, curTime):        for i in range(len(self._theAgents)):            if self._theAgents[i].isFree() and not self._passengerQ.isEmpty(): # 查看柜台是否空闲以及队列中是否还有顾客                passenger = self._passengerQ.dequeue() # 柜台空闲且队列中还有顾客,则将一名顾客出列,到相应的柜台开始交易                self._totalWaitTime += (curTime - passenger.timeArrived())                self._theAgents[i].startService(passenger, curTime+self._serviceTime)                print "Time %6d Agent %d started serving passenger %d" % (curTime, self._theAgents[i].idNum(), passenger.idNum())                    # 处理第三条规则    def _handleEndService(self, curTime):        for i in range(len(self._theAgents)):            if self._theAgents[i].isFinished(curTime): # 查看柜台是否已完成交易                passenger = self._theAgents[i].stopService()                print "Time %6d Agent %d stopped serving passenger %d" % (curTime, self._theAgents[i].idNum(), passenger.idNum())if __name__ == "__main__":    TCSimulation = TicketCounterSimulation(2, 25, 2, 3)    TCSimulation.run()    TCSimulation.printResults()




0 0
原创粉丝点击