[LeetCode] 由 “打印机任务队列" 所想
一、这是个基础问题
Ref: Python之队列模拟算法(打印机问题)【首先研究这个问题作为开始】
任务队列
定义一个任务队列,来管理任务,而无需关心队列的”任务类型"。
# 自定义队列类
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变化
queue.enqueue(queue.dequeue)
index变化,elem不变
position = index % Queue.size()
打印机类
三个状态:(1)接到一个新任务,就一个key: task timeRemaining(2)忙么?(3)执行任务一秒钟,更新任务状态。
所以,打印机类的”执行任务“,外层是一个”秒针滴答”的循环。
# 打印机类 需要实时监测是否正在执行打印任务
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 # 新任务需要的时间秒数: (有几张 * 一张需要多少秒)
任务类
创建一个 “随机大小“ 的任务;并设定好 “生日”。
类中的只读属性,可以考虑使用@property。
# 一个单独的打印任务
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.
二、基础总结
首先,这是一个 “模拟现实” 并做出评估的问题,思维模式具有一定的实际意义。
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.
[LeetCode] 由 “打印机任务队列" 所想的更多相关文章
- [LeetCode] 由 “找零钱" 所想
Ref: [Optimization] Dynamic programming[寻找子问题] Ref: [Optimization] Advanced Dynamic programming[优于re ...
- [Code] 变态之人键合一
目的也比较单纯,选一门语言,走向人键合一. 选了两本书作为操练场:<精通Python设计模式>.<Data Structure and Algorithm in Python> ...
- 装逼名词 bottom-half,软中断,preemptive选项
bottom-half http://bbs.csdn.net/topics/60226240 在中断,异常和系统调用里看Linux中断服务一般都是在关闭中断的情况下执行的,以避免嵌套而是控制复杂化L ...
- WPF打印票据
最近工作的内容是有关于WPF的,整体开发没有什么难度,主要是在打印上因为没有任何经验,犯了一些难,不过还好,解决起来也不是很费劲. WPF打印票据或者是打印普通纸张区别不大,只是说打印票据要把需要打的 ...
- 《转》高级Unix命令
原文链接:http://coolshell.cn/articles/1044.html 在Unix操作中有太多太多的命令,这些命令的强大之处就是一个命令只干一件事,并把这件事干好.Do one thi ...
- 一些不太常用的Linux命令
ACCTCOM 查看所有用户执行过的进程 acctcom | tail - 查看指定用户执行过的进程/命令 acctcom -u <username> | tail - 使用一个正则表达式 ...
- Python 实现队列
操作 Queue() 创建一个空的队列 enqueue(item) 往队列中添加一个item元素 dequeue() 从队列头部删除一个元素 is_empty() 判断一个队列是否为空 size() ...
- 高级Unix命令
在Unix操作中有太多太多的命令,这些命令的强大之处就是一个命令只干一件事,并把这件事干好.Do one thing, do it well.这是unix的哲学.而且Unix首创的管道可以把这些命令任 ...
- 数据结构之队列(Queue)
1,队列的定义 队列:是一种先进先出的数据结构,如下图所示,现进去的数据在队列前面(front),先出队列,后进入队列的数据在后面(rear),后出队列. 队列常用操作: q=Queue() #创建队 ...
随机推荐
- Ubuntu18设置mysql的sql_mode
原因: MySQL 5.7.5及以上功能依赖检测功能.如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引 ...
- DBUtils框架的使用(下)
刚才讲了使用QueryRunner插入.修改.更新数据,现在来学习一下使用QueryRunner进行数据库表查询. 通过QueryRunner类的query()方法即可完成数据库表的查询操作,但是在查 ...
- Django--路由层、伪静态页面、虚拟环境、视图层
路由层: 在路由匹配的时候,第一个参数是一个正则表达式,这也就意味着在路由匹配的时候按照正则匹配的规则去匹配,路由匹配的顺序是从上往下依次匹配的,只要匹配到一个,就会执行对应的函数,就不会执行下面的函 ...
- 关卡界面中个人信息随解锁关卡的移动(CocosCreator)
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 1.功能描述 在关卡很多的游戏里面,我们一般使用滑动来向玩家展示所有的关卡,为了清楚的让用户看到自己当前所在的关卡, ...
- 设计模式(C#)——12责任链模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 前言 在开发游戏过程中,当玩家合成一种道具的时候,对于不痛的道具,需要的碎片个数,类型是不同的.用传统的写法,就是 ...
- 百度地图Canvas实现十万CAD数据秒级加载
背景 前段时间工作室接到一个与地图相关的项目,我作为项目组成员主要负责地图方面的设计和开发.由于地图部分主要涉及的是前端页面的显示,作为一名Java后端的小白,第一次写了这么多HTML和JavaScr ...
- Windows GIT SSH 免密教程
Windows GIT SSH 免密教程 安装git客户端,最新下载地址如下 https://github.com/git-for-windows/git/releases/download/v2.2 ...
- postman 接口参数化操作
最近一直忙于AI模型的准确率任务中,这种操作需要大量的数据才能计算出模型的准确率.所以这里问遇到的问题和之前数据随机参数化有点不同,之前的参数比如说用户姓名或用户身份证号,这样数据可以在postman ...
- 使用ansible对思科交换机备份
先决条件 - 了解ansible基本操作 - 了解网络设备相关操作 - 了解linux相关操作 安装 安装EPEL yum install https://dl.fedoraproject.org/p ...
- Minimum spanning tree for each edge(倍增LCA)
https://vjudge.net/contest/320992#problem/J 暑期训练的题. 题意:给你一个n个点,m条边的无向图.对于每一条边,求包括该边的最小生成树. 思路:首先想到求一 ...