码迷,mamicode.com
首页 > 其他好文 > 详细

Algorithm - Queue Exercise

时间:2016-06-30 21:48:43      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

Simulation: Hot Potato

In this game children line up in a circle and pass an item from neighbor to neighbor as fast as they can. 

技术分享

 

At a certain point in the game, the action is stopped and the child who has the item (the potato) is removed from the circle. Play continues until only one child is left.

 

 We use a queue to simulate the circle. Assume the front child hold the potato. Upton passing the potato, the simulation will simply dequeue and then immediately enqueue that child.Puting her at the end of line.. She will then wait until all the others have been at the front before it will be her turn again. After num dequeue/enqueue operations, the child at the front will be removed permanently and another cycle will begin. This process will continue until only one name remains (the size of the queue is 1).

 

 技术分享

 1 from pythonds.basic.queue import Queue
 2 
 3 def hotPotato(namelist, num):
 4     simqueue = Queue()
 5     for name in namelist:
 6         simqueue.enqueue(name)
 7 
 8     while simqueue.size() > 1:
 9         for i in range(num):
10             simqueue.enqueue(simqueue.dequeue())
11 
12         simqueue.dequeue()
13 
14     return simqueue.dequeue()
15 
16 print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))

 

 

 

Simulation: Printing Tasks

the students send printing tasks to the sharded printer, the tasks are placed in a queue to be processed in a first-come first-served maner.

the question is whether the printers is capable of handling a certain amount of work. if it cannot, studnets will be waiting too long for pirnting and may miss their next class.

 

Consider the following situation in a computer science laboratory. On any average day about 10 students are working in the lab at any given hour. These students typically print up to twice during that time, and the length of these tasks ranges from 1 to 20 pages. The printer in the lab is older, capable of processing 10 pages per minute of draft quality. The printer could be switched to give better quality, but then it would produce only five pages per minute. The slower printing speed could make students wait too long. What page rate should be used?

 

技术分享

 

 

For example, students may print a paper from 1 to 20 pages in length. If each length from 1 to 20 is equally likely, the actual length for a print task can be simulated by using a random number between 1 and 20 inclusive. This means that there is equal chance of any length from 1 to 20 appearing.

 

If there are 10 students in the lab and each prints twice, then there are 20 print tasks per hour on average. 

 技术分享

 

Algorithm:

Step 1. Create a queue of print tasks. Each task will be given a timestamp upon its arrival. The queue is empty to start.

Step 2. For each second (currentSecond):

  1. Does a new print task get created? If so, add it to the queue with the currentSecond as the timestamp.
  2. If the printer is not busy and if a task is waiting,
    • Remove the next task from the print queue and assign it to the printer.
    • Subtract the timestamp from the currentSecond to compute the waiting time for that task.
    • Append the waiting time for that task to a list for later processing.
    • Based on the number of pages in the print task, figure out how much time will be required.
  3. The printer now does one second of printing if necessary. It also subtracts one second from the time required for that task.
  4. If the task has been completed, in other words the time required has reached zero, the printer is no longer busy.

Step 3. After the simulation is complete, compute the average waiting time from the list of waiting times generated.

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

    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

 

 

 1 import random
 2 
 3 class Task:
 4     def __init__(self,time):
 5         self.timestamp = time
 6         self.pages = random.randrange(1,21)
 7 
 8     def getStamp(self):
 9         return self.timestamp
10 
11     def getPages(self):
12         return self.pages
13 
14     def waitTime(self, currenttime):
15         return currenttime - self.timestamp

 

 

 

from pythonds.basic.queue import Queue

import random

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()))

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

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

 

 

 Code

from pythonds.basic.queue import Queue

import random

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

    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

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 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()))

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

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

 

 

技术分享

 

技术分享

 

 

 

Algorithm - Queue Exercise

标签:

原文地址:http://www.cnblogs.com/elewei/p/5631238.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!