Ciw icon indicating copy to clipboard operation
Ciw copied to clipboard

State-dependent service function

Open TheoBoucher opened this issue 7 years ago • 3 comments

first, thanks for this great project and contributors.

I want to create a queue network consisting of two transitive_nodes, and at node 2 the service time is state dependent, which means the service time is a function of the amount of customers currently waiting at node 2. Here i tried with the "n" variable as the one used in the baulking function, but it doesn't work, how could i get it work? Please help me.

import ciw 

def probability_of_baulking(n):
     if n < 3:
        return 0.0
    if n < 7:
        return 0.5
    return 1.0

def state_dependent_function(n):
      return 5*n

N = ciw.create_network(
      Arrival_distributions={'Class 0': [['Exponential', 5], 'NoArrivals']},
      Service_distributions={'Class 0': [['Exponential', 10], ['UserDefined', state_dependent_function]]},
      Transition_matrices=[[0.0, 1.0],[0.0,0.0]],
      Baulking_functions={'Class 0': [probability_of_baulking,0]},
      Number_of_servers=[1,2]
)
```	

TheoBoucher avatar Jan 17 '18 19:01 TheoBoucher

Hi @TheoBoucher, at present this isn't implemented in Ciw.

It would definitely be a good addition and I suggest we keep this issue up to track it's implementation (perhaps @geraintpalmer change the title to be "Implement state-dependent service distributions".

It would be possible to do implement this using inheritance and changing the specific function that the interior ciw.Node object uses which would be something like this:

import ciw

class ServiceDependentNode(ciw.Node):
    def get_service_time(self, clss, current_time):
        return 5 * len(self.individuals)
    
N = ciw.create_network(
    Arrival_distributions=[['Exponential', 0.2]],
    Service_distributions=[['Exponential', 0.1]],  # The way I've done this means this isn't actually necessary
    Number_of_servers=[3]
)

Q = ciw.Simulation(N, node_class=ServiceDependentNode)

That's not an ideal solution and in fact implementing state dependent service time distributions would be made easier once #134 is done.

I hope that's slightly helpful :)

drvinceknight avatar Jan 18 '18 12:01 drvinceknight

Hi @drvinceknight Thanks for the help, I changed the ciw.Node class as follows, and it works for the 2 nodes network:

class ServiceDependentNode(ciw.Node):
	def get_service_time(self, clss, current_time):
		if self.simulation.network.customer_classes[clss].service_distributions[self.id_number-1][0] == 'UserDefined':
			return 5 * (len(self.all_individuals)+1)
		return self.simulation.service_times[self.id_number][clss]()
        
N = ciw.create_network(
	Arrival_distributions={'Class 0': [['Deterministic', 2], 'NoArrivals']},
	Service_distributions={'Class 0': [['Exponential', 2], ['UserDefined']]},
	Transition_matrices=[[0.0, 1.0],[0.0,0.0]],
	Number_of_servers=[1,1]
)

Q = ciw.Simulation(N, node_class=ServiceDependentNode)

TheoBoucher avatar Jan 18 '18 16:01 TheoBoucher

This in now possible in version 2.0.0:

https://ciw.readthedocs.io/en/latest/Guides/time_dependent.html

The API has changed a lot, which makes this sort of manipulation standard procedure now.

geraintpalmer avatar Jul 10 '19 14:07 geraintpalmer