ChangingCapacity

Back Up Next

Modelling a Resource with capacity changes 

(Author: Klaus G. Muller; kgmuller at users.sourceforge.net)

SimPy's Resource construct basically models a group of homogeneous resource units with constant capacity. A typical example is an office with a number of manned service counters. The serving processes are all aggregated in the Resource instance. This is fine and straightforward to use if the capacity does not change (i.e., in above example, the staff does not take breaks). 

Fortunately, staff does take breaks in the real world. So, how does one model this without losing the convenience of the Resource abstraction?

A clean, logical approach is to model each resource unit with changing availability (in the example, each clerk) as a Process and control its contribution to the capacity of theResource by yield request,self,theResource and yield release,self,theResource commands. Effectively, a request reduces the capacity by one and a release increases it by one. One can interpret this as the serving Process instance owning one resource unit and deliberately providing or withdrawing it.

To ensure that the serving process has full control, one must set up the Resource with a priority queuing discipline and use a higher priority in serving processes' requests than in any resource user request.

If one uses 'Resource(. . .,qType=PriorityQ)', no pre-emption takes place for a serving unit's request, i.e., an ongoing user service is completed before the capacity is reduced. The example's clerk does not walk away in the middle of helping a customer. If immediate capacity reduction is required, one must program 'Resource(. . .,qType=PriorityQ,preemptable=True)'. This would be required e.g. in modelling the breakdown of a machine which makes part of a Resource.

 The following example program shows the typical structure of the proposed modelling approach for resources with varying capacity. The scenario is:

bulletAn office has nrClerks clerks and nrClerks counters.
bulletThe clerks take breaks. The time between breaks follows a negative exponential distribution, with a mean of 120 minutes. Breaks have  a fixed duration (20 minutes).
bulletThe clerks are courteous and complete any ongoing customer service before taking a break. 
bullet1000 customer arrivals are uniformly distributed over the working day of 8 hours.

 

from SimPy.Simulation import *
from random import *
class Clerk(Process):
    def work(self,myOffice):
        while True:
            yield hold,self,expovariate(1.0/120.0)
            yield request,self,myOffice,100 #leave desk
            print now(),[x.name for x in myOffice.activeQ]
            yield hold,self,20
            yield release,self,myOffice #return to desk

class Customer(Process):
    def visit(self,res):
        yield request,self,res
        yield hold,self,20 #get served
        yield release,self,res

nrClerks=3
initialize()
office=Resource(capacity=nrClerks,qType=PriorityQ)
for i in range(nrClerks):
    c=Clerk('Clerk %s'%i)
    activate(c,c.work(office))
for ctr in range(1000):
    cus=Customer('Customer %s'%ctr)
    activate(cus,cus.visit(office),at=uniform(0.0,8*60))
simulate(until=8*60)
OUTPUT:

61.1543704085 ['Clerk 1', 'Customer 121', 'Customer 73']
62.6304619713 ['Clerk 1', 'Clerk 2', 'Customer 73']
101.154370409 ['Clerk 1', 'Customer 610', 'Customer 794']
121.154370409 ['Clerk 2', 'Customer 747', 'Customer 656']
181.154370409 ['Clerk 2', 'Customer 987', 'Customer 676']
201.154370409 ['Clerk 0', 'Customer 899', 'Customer 584']
241.154370409 ['Clerk 2', 'Customer 905', 'Customer 369']
341.154370409 ['Clerk 2', 'Customer 649', 'Customer 816']
361.154370409 ['Clerk 1', 'Customer 272', 'Customer 722']
401.154370409 ['Clerk 0', 'Customer 993', 'Customer 916']
461.154370409 ['Clerk 0', 'Customer 874', 'Customer 155']

The output shows the office.activeQ whenever a clerk begins a break period, with the remaining capacity being used by customers. For example, 'Clerk 1' in the first line signifies that that clerk is now on break and his part of the counter capacity is unavailable to customers.

 

horizontal rule

©Copyright 2004, 2005, 2006, 2007, 2008 SimPy Developer Team.
For problems or questions regarding this web contact SimPy webmaster.
Last updated: 20/06/08.