|
| 1 | +.. _jockeying-customers: |
| 2 | + |
| 3 | +=================================== |
| 4 | +How to Simulate Jockeying Customers |
| 5 | +=================================== |
| 6 | + |
| 7 | +Jockeying is when a customer :ref:`reneges<reneging-customers>` from one queue but then joins another. In Ciw this is implemented in the same way as reneging, with the destinations determined by the routing object. |
| 8 | + |
| 9 | +Consider a two node network, the first node is an M/M/1, :math:`\lambda = 5` and :math:`\mu = 2`, queue where customers renege if they have spend more than 6 time units in the queue. Upon reneging they are sent to the second node. The second node has no arrivals, one server with exponential services :math:`\mu = 4`, and no reneging. |
| 10 | + |
| 11 | +First we need to define a :ref:`Routing object<routing-objects>`. Here the usual routing is to leave the system, so we can begin by inheriting the :code:`ciw.routing.Leave` class. The difference will be to re-define the object's :code:`next_node_for_jockeying` method:: |
| 12 | + |
| 13 | + >>> import ciw |
| 14 | + >>> class Jockey(ciw.routing.Leave): |
| 15 | + ... def next_node_for_jockeying(self, ind): |
| 16 | + ... """ |
| 17 | + ... Jockeys to Node 2 |
| 18 | + ... """ |
| 19 | + ... return self.simulation.nodes[2] |
| 20 | + |
| 21 | +Once this is defined, we can create the network object and run the simulation:: |
| 22 | + |
| 23 | + >>> N = ciw.create_network( |
| 24 | + ... arrival_distributions=[ciw.dists.Exponential(5), |
| 25 | + ... None], |
| 26 | + ... service_distributions=[ciw.dists.Exponential(2), |
| 27 | + ... ciw.dists.Exponential(4)], |
| 28 | + ... number_of_servers=[1, 1], |
| 29 | + ... routing=ciw.routing.NetworkRouting( |
| 30 | + ... routers=[Jockey(), ciw.routing.Leave()] |
| 31 | + ... ), |
| 32 | + ... reneging_time_distributions=[ciw.dists.Deterministic(6), |
| 33 | + ... None], |
| 34 | + ... ) |
| 35 | + |
| 36 | + >>> ciw.seed(0) |
| 37 | + >>> Q = ciw.Simulation(N, exact=5) |
| 38 | + >>> Q.simulate_until_max_time(11) |
| 39 | + |
| 40 | +Now we will see that the id number and arrival dates of the customers served at Node 2 are identical to the reneging times of the reneging customers, as the only way to get a service at Node 2 is to renege there:: |
| 41 | + |
| 42 | + >>> recs = Q.get_all_records() |
| 43 | + >>> [(r.id_number, r.exit_date) for r in recs if r.record_type == 'renege'] |
| 44 | + [(12, Decimal('8.0805')), (13, Decimal('8.1382')), (20, Decimal('10.441')), (21, Decimal('10.569')), (22, Decimal('10.758'))] |
| 45 | + >>> [(r.id_number, r.arrival_date) for r in recs if r.node == 2] |
| 46 | + [(12, Decimal('8.0805')), (13, Decimal('8.1382')), (20, Decimal('10.441')), (21, Decimal('10.569')), (22, Decimal('10.758'))] |
| 47 | + |
0 commit comments