数据结构之队列(2)
模拟算法:打印任务
一个实验室,在任意的一个小时内,有10名学生在场,每人会发起2次打印,每次1-20页。打印机有两种模式可选:草稿模式:每分钟10页;正常模式:每分钟5页,打印质量好。
问题:如何设定打印机模式,让大家在不等太久的前提下尽量提高打印质量?
问题建模:
打印机的属性:模式、是否空闲;
任务的属性:提交时间、打印页数;
打印队列:FIFO性质的打印任务队列;
一小时内,共可能出现20个任务,每秒出现任务的概率为1/180,打印页数为1-20,即出现1-20页的概率均相同。
统一时间:最小单位设为秒,来记录时间的流逝,设定结束时间(一个小时,360秒);
同步过程:即在一个时间单位内,此处为1秒内,都有可能生成打印任务以及实施打印任务;
模拟流程:
按照1/180的概率生成打印任务,加入打印队列;
判断打印机是否空闲,如果空闲,且队列不为空时,取出队首的任务开始打印,记录此任务的等待时间;如果打印机忙,则按照此时打印机的速度进行一个单位时间的打印,判断当前任务是否执行完毕,执行完毕则打印机进入空闲;
设置的时间段结束,开始统计平均等待时间。
任务的等待时间:生成任务时,记录生成的时间戳,当开始打印时,用当前的打印时间减去生成的时间戳即为任务的等待时间;
任务的打印时间:生成任务时,记录任务的页数,开始打印时,用页数/打印机速度即可。
1.定义任务类,包含生成任务的时间戳、任务的页数
class Task():
def __init__(self,time):
self.timestamp = time
self.pages = random.randrange(1,21)
def get_Stamp(self):
return self.timestamp
def getPages(self):
return self.pages
def waitTime(self,currenttime):
return currenttime - self.timestamp
2.定义打印机类,包含打印机的打印速度、是否忙、工作时间;
class Printer():
def __init__(self,ppm):
self.pagerate = ppm
self.currentTask = None
self.timeRemaining = 0
def tick(self):
if self.currentTask != None:
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
3.生成新的打印任务,按概率1/180
def newPrintTask():
num = random.randrange(1,181)
if num == 180:
return True
else:
return False
4.模拟整个过程,要设置打印机的速度、整个模拟时长
def simulation(numSeconds,pagesPerMiniute):
labprinter = Printer(pagesPerMiniute)
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()))
5.测试
for i in range(10):
simulation(3600,10)
6.结果
当速率为5时:
Average Wait 193.17 secs 1 tasks remaining
Average Wait 42.75 secs 0 tasks remaining
Average Wait 181.32 secs 7 tasks remaining
Average Wait 128.25 secs 1 tasks remaining
Average Wait 81.63 secs 2 tasks remaining
Average Wait 132.13 secs 0 tasks remaining
Average Wait 130.29 secs 1 tasks remaining
Average Wait 75.00 secs 0 tasks remaining
Average Wait 408.78 secs 1 tasks remaining
Average Wait 77.00 secs 0 tasks remaining
当速率为10时:
Average Wait 0.00 secs 0 tasks remaining
Average Wait 31.95 secs 0 tasks remaining
Average Wait 11.65 secs 0 tasks remaining
Average Wait 27.10 secs 0 tasks remaining
Average Wait 5.22 secs 0 tasks remaining
Average Wait 16.50 secs 0 tasks remaining
Average Wait 2.27 secs 0 tasks remaining
Average Wait 29.05 secs 0 tasks remaining
Average Wait 36.06 secs 0 tasks remaining
Average Wait 47.04 secs 0 tasks remaining