打印機序列:
平均每天大約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.