打印机序列:
平均每天大约10名学生在任何给定时间在实验室工作。这些学生通常在此期间打印两次,这些任务的长度范围从1到20页。实验室中的打印机较旧,每分钟以草稿质量可以处理10页。打印机可以切换以提供更好的质量,但是它将每分钟只能处理五页。较慢的打印速度可能会使学生等待太久。当学生提交打印任务时,我们将把他们添加到等待列表中,一个打印任务的队列。 当打印机完成任务时,它将检查队列,以检查是否有剩余的任务要处理。我们感兴趣的是学生等待他们的论文打印的平均时间。这等于任务在队列中等待的平均时间量。学生可以打印长度从 1 到 20 页的纸张。如果从 1 到 20 的每个长度有同样的可能性,则可以通过使用 1 和 20 之间的随机数来模拟打印任务的实际长度。这意味着出现从 1 到 20 的任何长度的机会是平等的
具体思路:
1. 创建打印任务的队列,每个任务都有个时间戳。队列启动的时候为空。
2. 每秒(currentsecond):
是否创建新的打印任务?如果是,将 currentSecond 作为时间戳添加到队列。
如果打印机不忙并且有任务在等待
从打印机队列中删除一个任务并将其分配给打印机
从 currentSecond 中减去时间戳,以计算该任务的等待时间。
将该任务的等待时间附件到列表中稍后处理。
根据打印任务的页数,确定需要多少时间。
打印机需要一秒打印,所以得从该任务的所需的等待时间减去一秒
如果任务已经完成,换句话说,所需的时间已经达到零,打印机空闲。
3. 模拟完成后,从生成的等待时间列表中计算平均等待时间。
#Author:KangZP
from pythonds.basic.queue import Queue
import random
#定义一个Printer类,tick是一个任务为非空闲的递减的计数器,,busy确认任务是否空闲,startnext确认新任务的打印时间
class Printer:
def __init__(self,ppm):
self.pagerate=ppm
self.currenttask=None
self.timeremain=0
def tick(self):
if self.currenttask!=None:
self.timeremain=self.timeremain-1
if self.timeremain<=0:
self.currenttask=None
def busy(self):
if self.currenttask!=None:
return True
else:
return False
def startnext(self,newtask):
self.currenttask=newtask
self.timeremain=newtask.getpages()*60/self.pagerate
#定义一个Task类,getstamp用来标记任务,getpages用来获取任务的页数,waittime获取新任务需要的等待时间
class Task:
def __init__(self,time):
self.timestamp=time
self.pages=random.randrange(1,21) #每个任务的打印页数随机产生random.randrange ([start,] stop [,step])
def getstamp(self):
return self.timestamp
def getpages(self):
return self.pages
def waittime(self,currenttime):
return currenttime - self.timestamp
#newprinttask决定是否创建一个新的打印任务
def newprinttask():
num=random.randrange(1,181)
if num==180:
return True
else:
return False
#仿真函数,numsecond代表模拟的总的时间,pagesperminute表示每分钟的打印机的打印速率
def simulation(numsecond,pagesperminute):
labprinter=Printer(pagesperminute)
printqueue=Queue() #建立一个打印机队列
waittimes=[]
for currentsecond in range(numsecond):
if newprinttask():
task=Task(currentsecond)
printqueue.enqueue(task) #加入打印机队列
if (not labprinter.busy()) and (not printqueue.isEmpty()):
nexttask=printqueue.dequeue()
waittimes.append(nexttask.waittime(currentsecond)) #列表waittimes加入新任务的等待时间
labprinter.startnext(nexttask)
labprinter.tick()
averagewait=sum(waittimes)/len(waittimes)
print("Average wait %6.2f secs %3d tasks remaining."%(averagewait,printqueue.size()))
for i in range(10):
simulation(3600,5)#3600为一个小时
——————————————————————————————————————————
模拟结果:
Average wait 128.00 secs 0 tasks remaining.
Average wait 462.00 secs 2 tasks remaining.
Average wait 46.89 secs 0 tasks remaining.
Average wait 88.08 secs 0 tasks remaining.
Average wait 130.26 secs 0 tasks remaining.
Average wait 74.33 secs 0 tasks remaining.
Average wait 60.62 secs 0 tasks remaining.
Average wait 35.14 secs 1 tasks remaining.
Average wait 180.95 secs 7 tasks remaining.
Average wait 214.44 secs 0 tasks remaining.