Question

Here is what I'm trying to implement in SimPy:

Customers firstly enter Server A for 5 minutes of service. Then each customer is split into two, one goes to Server B for 3 minutes of service, one goes to Server C for 2 minutes of service.

I wrote the following code but it seems not working based on the output. Also I'm not sure the way I use the copy function is correct, because I want to split EACH customer that is leaving Server A, but I feel my code may only work with the very first customer.

Any help would be appreciated.

from SimPy.Simulation import *
from copy import *

class Source(Process):                               
    def generate(self):                 
        for i in range(5):
            c = Customer(name="Customer%02d" % (i))  
            activate(c, c.runA())
            yield hold, self, 10                    

class Customer(Process):
    def runA(self):
        print("%7.4f %s (original) enters server A" % (now(), self.name))
        yield hold, self, 5
        print("%7.4f %s (original) leaves server A" % (now(), self.name))

        dup1 = copy(self)
        dup2 = copy(self)
        activate(dup1, dup1.runB())
        activate(dup2, dup2.runC())

    def runB(self):
        print("%7.4f %s (copy) enters server B" % (now(), self.name))
        yield hold, self, 3
        print("%7.4f %s (copy) leaves server B" % (now(), self.name))

    def runC(self):
        print("%7.4f %s (copy) enters server C" % (now(), self.name))
        yield hold, self, 2
        print("%7.4f %s (copy) leaves server C" % (now(), self.name))

initialize()
s = Source()                                         
activate(s, s.generate(), at=0.0)
simulate(until=100.0)

Output:

 0.0000 Customer00 (original) enters server A
 5.0000 Customer00 (original) leaves server A
10.0000 Customer01 (original) enters server A
15.0000 Customer01 (original) leaves server A
20.0000 Customer02 (original) enters server A
25.0000 Customer02 (original) leaves server A
30.0000 Customer03 (original) enters server A
35.0000 Customer03 (original) leaves server A
40.0000 Customer04 (original) enters server A
45.0000 Customer04 (original) leaves server A
logout
Was it helpful?

Solution

I'm afraid copy a Simpy Process is not such simple, I think because they are generators (see) and because they hold internal variables for the simulation.

To make your code work you can modify RunA(self) as follow. Here we create two new Process-Customers that look like self instead of copy it.

def runA(self):
    print("%7.4f %s (original) enters server A" % (now(), self.name))
    yield hold, self, 5
    print("%7.4f %s (original) leaves server A" % (now(), self.name))

    dup1 = Customer(name = self.name)
    dup2 = Customer(name = self.name)

    activate(dup1, dup1.runB())
    activate(dup2, dup2.runC())

This works well because you have only one variable to copy. In more complicated cases you can use the var(Object) method but be aware that the Process class holds many variables you probably shouldn't copy.

Also, I recommend this tutorials on SimPy to help you design your simulation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top