How to Simulate Jockeying Customers

Jockeying is when a customer reneges 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.

Consider a two node network, the first node is an M/M/1, \(\lambda = 5\) and \(\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 \(\mu = 4\), and no reneging.

First we need to define a Routing object. Here the usual routing is to leave the system, so we can begin by inheriting the ciw.routing.Leave class. The difference will be to re-define the object’s next_node_for_jockeying method:

>>> import ciw
>>> class Jockey(ciw.routing.Leave):
...     def next_node_for_jockeying(self, ind):
...         """
...         Jockeys to Node 2
...         """
...         return self.simulation.nodes[2]

Once this is defined, we can create the network object and run the simulation:

>>> N = ciw.create_network(
...     arrival_distributions=[ciw.dists.Exponential(5),
...                            None],
...     service_distributions=[ciw.dists.Exponential(2),
...                            ciw.dists.Exponential(4)],
...     number_of_servers=[1, 1],
...     routing=ciw.routing.NetworkRouting(
...         routers=[Jockey(), ciw.routing.Leave()]
...     ),
...     reneging_time_distributions=[ciw.dists.Deterministic(6),
...                                  None],
... )

>>> ciw.seed(0)
>>> Q = ciw.Simulation(N, exact=5)
>>> Q.simulate_until_max_time(11)

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:

>>> recs = Q.get_all_records()
>>> [(r.id_number, r.exit_date) for r in recs if r.record_type == 'renege']
[(12, Decimal('8.0805')), (13, Decimal('8.1382')), (20, Decimal('10.441')), (21, Decimal('10.569')), (22, Decimal('10.758'))]
>>> [(r.id_number, r.arrival_date) for r in recs if r.node == 2]
[(12, Decimal('8.0805')), (13, Decimal('8.1382')), (20, Decimal('10.441')), (21, Decimal('10.569')), (22, Decimal('10.758'))]