[LeetCode] 由 「打印機任務隊列" 所想

1、這是個基礎問題

Ref: Python之隊列模擬算法(打印機問題)【首先研究這個問題做爲開始】算法

任務隊列

定義一個任務隊列,來管理任務,而無需關心隊列的」任務類型"。app

# 自定義隊列類
class Queue(object):
def __init__(self): #初始化空隊列 self.items = [] def isEmpty(self): #是否爲空 return self.items == [] def enqueue(self, item): #入隊,索引爲0,即隊尾在左側 self.items.insert(0,item) def dequeue(self): #出隊,列表最後一個,即隊首在右側 return self.items.pop() def size(self): #查看隊列的大小 return len(self.items)

  

遍歷循環隊列

index不變,elem變化dom

queue.enqueue(queue.dequeue)函數

 

index變化,elem不變測試

position = index % Queue.size()spa

 

 

打印機類

三個狀態:(1)接到一個新任務,就一個key: task timeRemaining(2)忙麼?(3)執行任務一秒鐘,更新任務狀態。.net

因此,打印機類的」執行任務「,外層是一個」秒針滴答」的循環3d

# 打印機類 須要實時監測是否正在執行打印任務
class Printer(object):
def __init__(self, ppm): self.pagerate = ppm # 頁面打印速率:打印一張須要多少秒 self.currentTask = None # 初始化當前任務 self.timeRemaining = 0 # 初始化剩餘時間 # 計算正在執行的打印任務的剩餘時長,即減去當前秒(1秒時長)後的時長 def tick(self): 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 # 新任務須要的時間秒數: (有幾張 * 一張須要多少秒)

 

任務類

建立一個 「隨機大小「 的任務;並設定好 「生日」code

類中的只讀屬性,能夠考慮使用@property。blog

# 一個單獨的打印任務
class Task(object):
def __init__(self,time): self.timestamp = time # 出生時間:任務被建立和被放入打印隊列時的時間節點 self.pages = random.randrange(1,21) # 隨機大小:隨機生成1-20頁的單個任務的打印頁數 # 對外接口:獲取時間節點,此處沒用到。 def getStamp(self): return self.timestamp # 對外接口:獲取頁數 def getPages(self): return self.pages # 已經等待了多久;用於檢索任務開始打印前在隊列中的等待時長 def waitTime(self, currenttime): return currenttime - self.timestamp

  

開始模擬

例如:評估下」一小時內「 使用一臺 「每分鐘打印五張」 打印機的狀況,進行模擬。

每一秒,要考慮兩個事情:(1)有新任務?(2)能處理新任務?(3)打印機處理一次。

# 指定時長、指定打印速率下的打印函數
def simulation(numSeconds, pagesPerMinute):
labprinter
= Printer(pagesPerMinute) # 實例化打印機類,參數爲頁/分鐘 printQueue = Queue() # 建立打印隊列 waitingtimes = [] # 初始化等待時長列表

# 模擬:時間是 一秒一秒 地流逝,每一秒都要考慮兩個事情。 for currentSecond in range(numSeconds): #在指定時長numSeconds內的當前秒時 # (a) 有新來的打印任務嚒?
if newPrintTask(): #如有打印任務,則 task = Task(currentSecond) #建立打印任務,並記錄當前時間節點 printQueue.enqueue(task) #將該打印任務入隊
# (b) 若打印機不忙碌,且打印隊列不爲空,則 if (not labprinter.busy()) and (not printQueue.isEmpty()): nexttask = printQueue.dequeue() #出隊 waitingtimes.append(nexttask.waitTime(currentSecond)) #將該任務等待時長加入等待列表 labprinter.startNext(nexttask) #打印該任務

# (c) 打印機執行一次 labprinter.tick() #計算正在執行的打印任務的剩餘時長,並在一次任務結束後將打印機設爲空閒

averageWait = sum(waitingtimes) / len(waitingtimes) #平均等待時長 print("Average Wait %6.2f secs %3d tasks remaining." % (averageWait, printQueue.size()))

 

隨機任務

條件判斷之模擬,1/180的機率去作一件事。

# 使用隨機函數建立打印任務
def newPrintTask():
    num = random.randrange(1, 181)              #生成隨機數,平均3分鐘有一個任務
    if num == 180:                              
        return True                             #有打印任務
    else:
        return False                            #沒有打印任務

  

程序測試

if __name__ == '__main__':
    for i in range(10):                         #獲取10次打印狀況
        simulation(3600, 5)                     #獲取1小時內,每分鐘打印5張的打印狀況

Output: 

Average Wait  58.35 secs   0 tasks remaining.
Average Wait  85.43 secs   0 tasks remaining.
Average Wait  83.68 secs   4 tasks remaining.
Average Wait 107.12 secs   0 tasks remaining.
Average Wait  71.05 secs   0 tasks remaining.
Average Wait  30.77 secs   3 tasks remaining.
Average Wait 143.09 secs   0 tasks remaining.
Average Wait 195.75 secs   4 tasks remaining.
Average Wait 265.95 secs   1 tasks remaining.
Average Wait  70.94 secs   0 tasks remaining.

 

  

2、基礎總結

首先,這是一個 「模擬現實」 並作出評估的問題,思惟模式具備必定的實際意義。

Input 端的兩個隨機特性;

    • 隨機輸入
    • 隨機負載

代碼樣例以下:

for currentSecond in range(numSeconds): 
  if random.randrange(0, 180) == 180    # 隨機輸入
    task = Task(currentSecond)      # 隨機負載
    printQueue.enqueue(task) 

  

class Task(object):

    def __init__(self,time):
        self.timestamp = time
        self.pages = random.randrange(1,21)     # 隨機負載

 

End.

相關文章
相關標籤/搜索