标签:
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
):
- Does a new print task get created? If so, add it to the queue with the
currentSecond
as the timestamp.
- 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.
- The printer now does one second of printing if necessary. It also subtracts one second from the time required for that task.
- 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