数据结构之队列(2)

数据结构之队列(2)

模拟算法:打印任务
一个实验室,在任意的一个小时内,有10名学生在场,每人会发起2次打印,每次1-20页。打印机有两种模式可选:草稿模式:每分钟10页;正常模式:每分钟5页,打印质量好。
问题:如何设定打印机模式,让大家在不等太久的前提下尽量提高打印质量?

问题建模:
打印机的属性:模式、是否空闲;
任务的属性:提交时间、打印页数;
打印队列:FIFO性质的打印任务队列;

一小时内,共可能出现20个任务,每秒出现任务的概率为1/180,打印页数为1-20,即出现1-20页的概率均相同。
统一时间:最小单位设为秒,来记录时间的流逝,设定结束时间(一个小时,360秒);
同步过程:即在一个时间单位内,此处为1秒内,都有可能生成打印任务以及实施打印任务;

模拟流程:
按照1/180的概率生成打印任务,加入打印队列;
判断打印机是否空闲,如果空闲,且队列不为空时,取出队首的任务开始打印,记录此任务的等待时间;如果打印机忙,则按照此时打印机的速度进行一个单位时间的打印,判断当前任务是否执行完毕,执行完毕则打印机进入空闲;
设置的时间段结束,开始统计平均等待时间。
任务的等待时间:生成任务时,记录生成的时间戳,当开始打印时,用当前的打印时间减去生成的时间戳即为任务的等待时间;
任务的打印时间:生成任务时,记录任务的页数,开始打印时,用页数/打印机速度即可。

1.定义任务类,包含生成任务的时间戳、任务的页数

class Task():
    def __init__(self,time):
        self.timestamp = time
        self.pages = random.randrange(1,21)

    def get_Stamp(self):
        return self.timestamp

    def getPages(self):
        return self.pages

    def waitTime(self,currenttime):
        return currenttime - self.timestamp

2.定义打印机类,包含打印机的打印速度、是否忙、工作时间;

class Printer():
    def __init__(self,ppm):
        self.pagerate = ppm
        self.currentTask = None
        self.timeRemaining = 0

    def tick(self):
        if self.currentTask != None:
            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

3.生成新的打印任务,按概率1/180

def newPrintTask():
    num = random.randrange(1,181)
    if num == 180:
        return True
    else:
        return False

4.模拟整个过程,要设置打印机的速度、整个模拟时长

def simulation(numSeconds,pagesPerMiniute):
    labprinter = Printer(pagesPerMiniute)
    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()))

5.测试

for i in range(10):
    simulation(3600,10)

6.结果
当速率为5时:

Average Wait 193.17 secs   1 tasks remaining
Average Wait  42.75 secs   0 tasks remaining
Average Wait 181.32 secs   7 tasks remaining
Average Wait 128.25 secs   1 tasks remaining
Average Wait  81.63 secs   2 tasks remaining
Average Wait 132.13 secs   0 tasks remaining
Average Wait 130.29 secs   1 tasks remaining
Average Wait  75.00 secs   0 tasks remaining
Average Wait 408.78 secs   1 tasks remaining
Average Wait  77.00 secs   0 tasks remaining

当速率为10时:

Average Wait   0.00 secs   0 tasks remaining
Average Wait  31.95 secs   0 tasks remaining
Average Wait  11.65 secs   0 tasks remaining
Average Wait  27.10 secs   0 tasks remaining
Average Wait   5.22 secs   0 tasks remaining
Average Wait  16.50 secs   0 tasks remaining
Average Wait   2.27 secs   0 tasks remaining
Average Wait  29.05 secs   0 tasks remaining
Average Wait  36.06 secs   0 tasks remaining
Average Wait  47.04 secs   0 tasks remaining
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值