02_python_queue

用Python实现队列

  • 将LIst首端作为队列的尾端,List末端作为队列的首端。
    • enqueue():复杂度为O(n)
    • dequeu():复杂度为O(1)
class Queue:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    def enqueue(self, item):
        self.items.insert(0,item)
    def dequeue(self):
        return self.items.pop()
    def size(self):
        return len(self.items)

q = Queue()
q.enqueue(4)
q.enqueue('dog')
q.enqueue(True)
print(q.size())
print(q.isEmpty())
q.enqueue(8.4)
print(q.dequeue())
print(q.dequeue())
print(q.size())
3
False
4
dog
2

热土豆

  • 类似于击鼓传花,传烫手的热土豆,鼓声停的时候,手里有土豆的小孩就要出列。
  • 约瑟夫问题:去掉鼓(因为鼓是随机因素),改为传过固定人数。

  • 用队列来实现热土豆问题的算法,参加游戏的人名列表,以及传土豆次数num,算法返回最后剩下的人名。
    • 模拟程序用队列来存放所有参加游戏的人名,按照传递土豆方向从队首排到队尾。
      • 游戏时,队首始终是持有土豆的人
    • 模拟游戏开始,只需要将队首的人出队,随即再到队尾入队,算是土豆的一次传递。
      • 传递了num次后,将队首的人移除,不再入队
      • 如此反复,直到队列中只剩余1人
class Queue:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    def enqueue(self, item):
        self.items.insert(0,item)
    def dequeue(self):
        return self.items.pop()
    def size(self):
        return len(self.items)
    
def hotPotato(namelist, num):
    simqueue = Queue()
    for name in namelist:
        simqueue.enqueue(name)
        
    while simqueue.size() > 1:
        for i in range(num):
            simqueue.enqueue(simqueue.dequeue())   #一次传递
        simqueue.dequeue()
        
    return simqueue.dequeue()

print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
Susan

打印任务

  • 打印任务:多人共享一台打印机,采取“先到先得”的队列来执行打印任务。
    • 打印机系统的容量:能够接收的等待时间内,系统能容纳多少用户以高频率提交多少打印任务。

  • 作业的等待时间:生成作业时,记录生成的时间戳;开始打印时,当前时间减去生成时间即可。
  • 作业的打印时间:生成作业时,记录作业的页数;开始打印时,页数除以打印速度即可。

  • 模拟流程
    • 创建打印队列对象
    • 对于每一秒(打印过程中的当前秒)
      • 是否有新的打印任务生成?如果有,把它加入打印队列,并把当前秒作为其时间戳
      • 如果打印机空闲并且有任务正在等待队列中:
        • 从打印队列中移除下一个打印任务并且将其提交给打印机
        • 从当前秒中减去时间戳,计算得到该任务的等待时间
        • 将该任务的等待时间添加到一个列表中,以用于后续操作
        • 基于打印任务的页数,求出需要多长的打印时间
      • 如果此时打印机正在工作中,则对于打印机而言,就工作了一秒钟;对于打印任务而言,它离打印结束又近了一秒钟(剩余打印时间减1)。
      • 如果此时打印任务已经完成,即剩余打印时间为0,打印机就进入空闲状态。
    • 时间用尽,开始统计平均等待时间
class Queue:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    def enqueue(self, item):
        self.items.insert(0,item)
    def dequeue(self):
        return self.items.pop()
    def size(self):
        return len(self.items)
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()))
    


if __name__ == "__main__":
    for i in range(10):
        simulation(3600, 5)  #打印速度5ppm,1小时的设定
       #simulation(3600, 10)  #打印速度10ppm,1小时的设定
Average Wait 125.04 secs   1 tasks remaining.
Average Wait  53.55 secs   0 tasks remaining.
Average Wait  97.95 secs   1 tasks remaining.
Average Wait  78.47 secs   0 tasks remaining.
Average Wait  56.47 secs   3 tasks remaining.
Average Wait  77.44 secs   1 tasks remaining.
Average Wait 111.82 secs   0 tasks remaining.
Average Wait  60.53 secs   0 tasks remaining.
Average Wait  11.33 secs   0 tasks remaining.
Average Wait  63.94 secs   0 tasks remaining.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值