How to Use Routing Objects

Routing objects in Ciw are objects that determine what an individual’s next node will be. There are two types:

  • Network routing objects: these determine routing for the entire network;

  • Node routing objects: these determine routing from a particular node.

Ciw has a number of these built in, however their primary use is to be defined by the user. Examples of Network routing objects are:

  • ciw.routing.TransitionMatrix, allowing users to define transition matrices, that is a matrix of probabilities of being transferred to each node in the network after service at every other node.

  • ciw.routing.ProcessBased, allowing pre-defined routes to be given to individuals when they arrive, that is process-based routing.

However, the most flexible Network routing object is the generic ciw.routing.NetworkRouting. This takes in a list of Node routing objects. Node routing objects are objects that determine routing out of a particular node. A full list is given in the References section. The following are some of the most basic built-in routers available in Ciw, but importantly, they can also be user defined:

  • ciw.routing.Direct(to=2): Sends the individual directly to another node. For example here, a customer is always send to node 2.

  • ciw.routing.Leave(): The individual leaves the system.

  • ciw.routing.Probabilistic(destinations=[1, 3], probs=[0.1, 0.4]): Probabilistically sends the individual to either of the destination, according to their corresponding probabilities. In this case, they are send to node 1 with probability 0.1, node 3 with probability 0.4, and leave the system with the rest of the probability, 0.5.

Example

Consider a four node system:
  • At the node 1 customers are send directly to node 2;

  • At node 2 customers can be send to either nodes 1, 3 or 4 with probabilities 0.1, 0.5, and 0.4;

  • At node 3 customers can either repeat service there with probability 0.25, or leave the system;

  • At node 4, all customers leave the system.

We can construct a network routing object for this by choosing a set of node routing obejects from the list above. We place them in a list and use the routers keyword to create the network object. In this case, the network object would be:

>>> import ciw
>>> R = ciw.routing.NetworkRouting(
...     routers=[
...         ciw.routing.Direct(to=2),
...         ciw.routing.Probabilistic(destinations=[1, 3, 4], probs=[0.1, 0.5, 0.4]),
...         ciw.routing.Probabilistic(destinations=[3], probs=[0.25]),
...         ciw.routing.Leave()
...     ]
... )

This network object can then be used to create a network:

>>> N = ciw.create_network(
...     arrival_distributions=[ciw.dists.Exponential(rate=1), ciw.dists.Exponential(rate=1), ciw.dists.Exponential(rate=1), ciw.dists.Exponential(rate=1)],
...     service_distributions=[ciw.dists.Exponential(rate=2), ciw.dists.Exponential(rate=2), ciw.dists.Exponential(rate=2), ciw.dists.Exponential(rate=2)],
...     number_of_servers=[1, 2, 3, 1],
...     routing=R
... )

Notes

  • Note that a the routing keywork when creating a network object requires a network routing object, not a node routing object. This is true even when there is only one node in the network.

  • Note also that, similar to the use of most other keywords when creating a network object, that routing can be customer class dependent.

For example, a one node network with two customer classes, both classes having different routing:

>>> N = ciw.create_network(
...     arrival_distributions={
...         "Class 0": [ciw.dists.Exponential(rate=1)],
...         "Class 1": [ciw.dists.Exponential(rate=3)]
...     },
...     service_distributions={
...         "Class 0": [ciw.dists.Exponential(rate=2)],
...         "Class 1": [ciw.dists.Exponential(rate=2)]
...     },
...     number_of_servers=[2],
...     routing={
...         "Class 0": ciw.routing.NetworkRouting(routers=[ciw.routing.Leave()]),
...         "Class 1": ciw.routing.TransitionMatrix(transition_matrix=[[0.3]])
...     }
... )

Custom Routing Objects

Ciw allows for custom built routing objects. These allow for both time and state dependent routing, allowing flexible and routing logic. A guide is given here.