完善的超市结账模拟程序
根据要求修改 marketmodel.py 文件,添加顾客随机选择收银员与比对左中右三队收银员的队列长度,选择最短的队列进行排队
"""
File: marketmodel.py
"""
from cashier import Cashier
from customer import Customer
import random
class MarketModel(object):
def __init__(self, lengthOfSimulation, numsOfCashiers, averageTimePerCus,
probabilityOfNewArrival):
self._probabilityOfNewArrival = probabilityOfNewArrival
self._numsOfCashiers = numsOfCashiers
self._lengthOfSimulation = lengthOfSimulation
self._averageTimePerCus = averageTimePerCus
#self._cashier = Cashier()
self._cashier = self.zhaoPinShouYinYuan(self._numsOfCashiers)
def runSimulation(self):
"""Run the clock for n ticks."""
for currentTime in range(self._lengthOfSimulation):
# Attempt to generate a new customer
customer = Customer.generateCustomer(
self._probabilityOfNewArrival,
currentTime,
self._averageTimePerCus)
# Send customer to cashier if successfully generated
# 随机的
# 而且选择一个距离其 < 2 的
# 队伍最短的一个收银员
if customer != None:
cashierIndex = random.randint(0,self._numsOfCashiers - 1)
minLengthOfQueue = self._cashier[cashierIndex].lengthOfQueue()
for i in range(cashierIndex - 1, cashierIndex + 2):
if i >= 0 and i < self._numsOfCashiers:
if self._cashier[i].lengthOfQueue() < minLengthOfQueue:
cashierIndex = i
minLengthOfQueue = self._cashier[i].lengthOfQueue()
self._cashier[cashierIndex].addCustomer(customer)
# Tell cashier to provide another unit of service
# Tell all cashier to work
for i in range(0,self._numsOfCashiers):
self._cashier[i].serveCustomers(currentTime)
def zhaoPinShouYinYuan(self, numsOfCashiers):
"""返回收银员列表"""
return [Cashier() for i in range(numsOfCashiers)]
def __str__(self):
result = ""
for cashier in self._cashier:
result += str(cashier)
result += "\n\n"
return result
"""
File: cashier.py
Author: Ken Lambert
"""
from linkedqueue import LinkedQueue
class Cashier(object):
"""Represents a cashier."""
def __init__(self):
"""Maintains a queue of customers,
number of customers served, total customer wait time,
and a current customer being processed."""
self._totalCustomerWaitTime = 0
self._customersServed = 0
self._currentCustomer = None
self._queue = LinkedQueue()
def addCustomer(self, c):
"""Adds an arriving customer to my line."""
self._queue.add(c)
def serveCustomers(self, currentTime):
"""Serves my cuatomers during a given unit of time."""
if self._currentCustomer is None:
# No customers yet
if self._queue.isEmpty():
return
else:
# Pop first waiting customer and tally results
self._currentCustomer = self._queue.pop()
self._totalCustomerWaitTime += \
currentTime - \
self._currentCustomer.arrivalTime()
self._customersServed += 1
# Give a unit of service
self._currentCustomer.serve()
# If current customer is finished, send it away
if self._currentCustomer.amountOfServiceNeeded() == 0:
self._currentCustomer = None
def lengthOfQueue(self):
"""返回此收银员的队伍长度."""
return len(self._queue)
def __str__(self):
"""Returns my results: my total customers served,
my average wait time per customer, and customers left on my queue."""
result = "TOTALS FOR THE CASHIER\n" + \
"Number of customers served: " + \
str(self._customersServed) + "\n"
if self._customersServed != 0:
aveWaitTime = self._totalCustomerWaitTime /\
self._customersServed
result += "Number of customers left in queue: " + \
str(len(self._queue)) + "\n" + \
"Average time customers spend\n" + \
"waiting to be served: " + \
"%5.2f" % aveWaitTime
return result
修改客户所用的时间,使客户的处理时间随机
"""
File: customer.py
Author: Ken Lambert
Customer's processing time varies around the average,
so give it a random time between 1 and average time * 2 - 1.
"""
import random
class Customer(object):
"""Represents a customer."""
@classmethod
def generateCustomer(cls, probabilityOfNewArrival,
arrivalTime,
averageTimePerCustomer):
"""Returns a Customer object if the probability
of arrival is greater than or equal to a random number.
Otherwise, returns None, indicating no new customer.
"""
if random.random() <= probabilityOfNewArrival:
return Customer(arrivalTime, averageTimePerCustomer)
else:
return None
def __init__(self, arrivalTime, averageTimePerCustomer):
"""Maintains the arrival time and amount of service needed."""
self._arrivalTime = arrivalTime
self._amountOfServiceNeeded = random.randint(1,2*averageTimePerCustomer-1)
def arrivalTime(self):
"""Returns the arrival time."""
return self._arrivalTime
def amountOfServiceNeeded(self):
"""Returns the amount of service needed."""
return self._amountOfServiceNeeded
def serve(self):
"""Accepts a unit of service from the cashier."""
self._amountOfServiceNeeded -= 1
程序入口
"""
File: marketapp.py
Author: Ken Lambert
Terminal-based simulation of a supermarket checkout process.
"""
from marketmodel import MarketModel
def main():
print("Welcome to the Market Simulator!\n")
lengthOfSimulation = int(input("Enter the total running time: "))
numsOfCashiers = int(input("请输入收银员数量"))
averageTimePerCus = int(input("Enter the average processing time per customer: "))
probabilityOfNewArrival = float(input("Enter the probability of a new arrival: "))
if lengthOfSimulation < 1 or lengthOfSimulation > 1000:
print("Running time must be an integer greater than 0" + \
"\nand less than or equal to 1000")
elif numsOfCashiers < 1 or numsOfCashiers > 10:
print("收银员数量请规定在1-10之间")
elif averageTimePerCus <= 0 or averageTimePerCus >= lengthOfSimulation:
print("Average time per customer must be an integer" + \
"\ngreater than 0 and less than running time")
elif probabilityOfNewArrival <= 0 or probabilityOfNewArrival > 1:
print("Probability must be geater than 0" + \
"\nand less than or equal to 1")
else:
model = MarketModel(lengthOfSimulation, numsOfCashiers, averageTimePerCus,
probabilityOfNewArrival)
model.runSimulation()
print(model)
if __name__ == "__main__":
main()