队列应用——打印任务
打印任务问题: 模拟流程
时间按照秒的单位流逝
按照概率生成打印作业,加入打印队列
如果打印机空闲,且队列不空,则取出队首作业
打印,记录此作业等待时间
如果打印机忙,则按照打印速度进行1秒打印
如果当前作业打印完成,则打印机进入空闲。
时间用尽,开始统计平均等待时间。
作业等待时间
生成作业时, 记录生成的时间戳
开始打印时,当前时间减去生成时间即可
作业的打印时间
生成作业时, 记录作业的页数
开始打印时,页数除以打印速度即可
代码显示
from pythonds.basic.Queue import Queue
import random
class Printer:
def __init__(self, ppm):
self.pagerate = ppm #打印速度
self.currentTask = None #打印任务
self.timeRemaining = 0 #任务倒计时
def tick(self): #打印1秒
if self.currentTask != None:
self.timeRemaining = self.timeRemaining - 1
if self.timeRemaining <= 0:
self.currentTask = None
def busy(self): #打印忙?
if self.currentTask != None:
return True
else:
return False
def startNext(self, newtask): #打印新作业
self.currentTask = newtask
self.timeRemaining = newtask.getPages() * 60 / self.pagerate
class Task:
def __init__(self, time):
self.timestamp = time #生成时间戳
self.pages = random.randrange(1, 21) #打印页数
def getStamp(self):
return self.timestamp
def getPages(self):
return self.pages
def waitTime(self, currenttime): #等待时间
return currenttime - self.timestamp
def newPrintTask():
num = random.randrange(1, 181) #1/180概率生成作业
if num == 180:
return True
else:
return False
def simulation(numSeconds, pagesPerMinute): #模拟
labprinter = Printer(pagesPerMinute)
printQueue = Queue()
waitingtimes = []
for currentSecond in range(numSeconds):
if newPrintTask():
task = Task(currentSecond) #时间流逝
printQueue.enqueue(task)
if (not labprinter.busy()) and (not printQueue.isEmpty()):
nexttask = printQueue.dequeue()
waitingtimes.append(nexttask.waitTime(currentSecond))
labprinter.startNext(nexttask)
labprinter.tick()
averageWait = sum(waitingtimes) / len(waitingtimes)
print("Average Wait %6.2f secs %3d tasks remaining."\
% (averageWait, printQueue.size())
for i in range(10):
simulation(3600, 5)
思考
为了评估打印模式设置进行决策, 我们用模拟程序来评估任务等待时间
通过两种情况模拟仿真结果的分析, 我们认识到如果有那么多学生要拿着打印好的程序源代码赶去上课的话,那么,必须得牺牲打印质量,提高打印速度。
模拟系统对现实的仿真
在不耗费现实资源的情况下——有时候真实的实验是无法进行的,可以以不同的设定,反复多次模拟来帮助我们进行决策。