Ken Lambert著《数据结构》第八章编程项目

完善的超市结账模拟程序

根据要求修改 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()


猜你喜欢

转载自blog.csdn.net/sinat_39013092/article/details/81261587