@@ -11,6 +11,8 @@ def get_distribution(dist):
1111 Returns instances of the distribution classes that
1212 correspond to the indicator string in the .yml file.
1313 """
14+ if (dist is None ) or (dist == 'None' ):
15+ return None
1416 if dist [0 ] == 'Uniform' :
1517 return ciw .dists .Uniform (dist [1 ], dist [2 ])
1618 if dist [0 ] == 'Deterministic' :
@@ -36,14 +38,18 @@ def get_distribution(dist):
3638def create_network (arrival_distributions = None ,
3739 baulking_functions = None ,
3840 class_change_matrices = None ,
41+ class_change_time_distributions = None ,
3942 number_of_servers = None ,
4043 priority_classes = None ,
4144 queue_capacities = None ,
4245 service_distributions = None ,
4346 routing = None ,
4447 batching_distributions = None ,
4548 ps_thresholds = None ,
46- server_priority_functions = None ):
49+ server_priority_functions = None ,
50+ reneging_time_distributions = None ,
51+ reneging_destinations = None ,
52+ ):
4753 """
4854 Takes in kwargs, creates dictionary.
4955 """
@@ -60,6 +66,8 @@ def create_network(arrival_distributions=None,
6066 params ['baulking_functions' ] = baulking_functions
6167 if class_change_matrices != None :
6268 params ['class_change_matrices' ] = class_change_matrices
69+ if class_change_time_distributions is not None :
70+ params ['class_change_time_distributions' ] = class_change_time_distributions
6371 if priority_classes != None :
6472 params ['priority_classes' ] = priority_classes
6573 if queue_capacities != None :
@@ -72,6 +80,10 @@ def create_network(arrival_distributions=None,
7280 params ['ps_thresholds' ] = ps_thresholds
7381 if server_priority_functions != None :
7482 params ['server_priority_functions' ] = server_priority_functions
83+ if reneging_time_distributions is not None :
84+ params ['reneging_time_distributions' ] = reneging_time_distributions
85+ if reneging_destinations is not None :
86+ params ['reneging_destinations' ] = reneging_destinations
7587
7688 return create_network_from_dictionary (params )
7789
@@ -105,6 +117,13 @@ def create_network_from_yml(directory_name):
105117 for dist in params ['service_distributions' ][clss ]:
106118 dists .append (get_distribution (dist ))
107119 params ['service_distributions' ][clss ] = dists
120+ for clss in params ['reneging_time_distributions' ]:
121+ dists = [get_distribution (dist ) for dist in params ['reneging_time_distributions' ][clss ]]
122+ params ['reneging_time_distributions' ][clss ] = dists
123+ if 'class_change_time_distributions' in params :
124+ for clss , dist_original in enumerate (params ['class_change_time_distributions' ]):
125+ dists = [get_distribution (dist ) for dist in dist_original ]
126+ params ['class_change_time_distributions' ][clss ] = dists
108127 validify_dictionary (params )
109128 return create_network_from_dictionary (params )
110129
@@ -116,6 +135,8 @@ def create_network_from_dictionary(params_input):
116135 params = fill_out_dictionary (params_input )
117136 validify_dictionary (params )
118137 # Then make the Network object
138+ number_of_classes = params ['number_of_classes' ]
139+ number_of_nodes = params ['number_of_nodes' ]
119140 arrivals = [params ['arrival_distributions' ]['Class ' + str (clss )]
120141 for clss in range (len (params ['arrival_distributions' ]))]
121142 services = [params ['service_distributions' ]['Class ' + str (clss )]
@@ -125,17 +146,23 @@ def create_network_from_dictionary(params_input):
125146 else :
126147 routing = [params ['routing' ]['Class ' + str (clss )]
127148 for clss in range (len (params ['routing' ]))]
128- priorities = [params ['priority_classes' ]['Class ' + str (clss )]
129- for clss in range (len (params ['priority_classes' ]))]
149+ if isinstance (params ['priority_classes' ], dict ):
150+ priorities = [params ['priority_classes' ]['Class ' + str (clss )]
151+ for clss in range (len (params ['priority_classes' ]))]
152+ preempt_priorities = [False for _ in range (number_of_nodes )]
153+ if isinstance (params ['priority_classes' ], tuple ):
154+ priorities = [params ['priority_classes' ][0 ]['Class ' + str (clss )]
155+ for clss in range (len (params ['priority_classes' ][0 ]))]
156+ preempt_priorities = params ['priority_classes' ][1 ]
130157 baulking_functions = [params ['baulking_functions' ]['Class ' + str (clss )]
131158 for clss in range (len (params ['baulking_functions' ]))]
132159 batches = [params ['batching_distributions' ]['Class ' + str (clss )]
133160 for clss in range (len (params ['batching_distributions' ]))]
134- number_of_classes = params ['number_of_classes' ]
135- number_of_nodes = params ['number_of_nodes' ]
136161 queueing_capacities = [float (i ) if i == "Inf" else i for i in params ['queue_capacities' ]]
137162 class_change_matrices = params .get ('class_change_matrices' ,
138163 {'Node ' + str (nd + 1 ): None for nd in range (number_of_nodes )})
164+ class_change_time_distributions = params .get ('class_change_time_distributions' ,
165+ [[None for clss1 in range (number_of_classes )] for clss2 in range (number_of_classes )])
139166 number_of_servers , schedules , nodes , classes , preempts = [], [], [], [], []
140167 for c in params ['number_of_servers' ]:
141168 if isinstance (c , (tuple , list )):
@@ -163,6 +190,7 @@ def create_network_from_dictionary(params_input):
163190 class_change_matrices ['Node ' + str (nd + 1 )],
164191 schedules [nd ],
165192 preempts [nd ],
193+ preempt_priorities [nd ],
166194 params ['ps_thresholds' ][nd ],
167195 params ['server_priority_functions' ][nd ]))
168196 for clss in range (number_of_classes ):
@@ -173,15 +201,22 @@ def create_network_from_dictionary(params_input):
173201 routing ,
174202 priorities [clss ],
175203 baulking_functions [clss ],
176- batches [clss ]))
204+ batches [clss ],
205+ params ['reneging_time_distributions' ]['Class ' + str (clss )],
206+ params ['reneging_destinations' ]['Class ' + str (clss )],
207+ class_change_time_distributions [clss ]))
177208 else :
178209 classes .append (CustomerClass (
179210 arrivals [clss ],
180211 services [clss ],
181212 routing [clss ],
182213 priorities [clss ],
183214 baulking_functions [clss ],
184- batches [clss ]))
215+ batches [clss ],
216+ params ['reneging_time_distributions' ]['Class ' + str (clss )],
217+ params ['reneging_destinations' ]['Class ' + str (clss )],
218+ class_change_time_distributions [clss ]))
219+
185220 n = Network (nodes , classes )
186221 if all (isinstance (f , types .FunctionType ) for f in params ['routing' ]):
187222 n .process_based = True
@@ -214,6 +249,14 @@ def fill_out_dictionary(params_input):
214249 if isinstance (params ['batching_distributions' ], list ):
215250 btch_dists = params ['batching_distributions' ]
216251 params ['batching_distributions' ] = {'Class 0' : btch_dists }
252+ if 'reneging_time_distributions' in params :
253+ if isinstance (params ['reneging_time_distributions' ], list ):
254+ reneging_dists = params ['reneging_time_distributions' ]
255+ params ['reneging_time_distributions' ] = {'Class 0' : reneging_dists }
256+ if 'reneging_destinations' in params :
257+ if isinstance (params ['reneging_destinations' ], list ):
258+ reneging_dests = params ['reneging_destinations' ]
259+ params ['reneging_destinations' ] = {'Class 0' : reneging_dests }
217260
218261 default_dict = {
219262 'name' : 'Simulation' ,
@@ -235,8 +278,13 @@ def fill_out_dictionary(params_input):
235278 'ps_thresholds' : [1 for _ in range (len (
236279 params ['number_of_servers' ]))],
237280 'server_priority_functions' : [
238- None for _ in range (len (params ['number_of_servers' ]))
239- ]
281+ None for _ in range (len (params ['number_of_servers' ]))],
282+ 'reneging_time_distributions' : {'Class ' + str (i ): [
283+ None for _ in range (len (params ['number_of_servers' ]))]
284+ for i in range (len (params ['arrival_distributions' ]))},
285+ 'reneging_destinations' : {'Class ' + str (i ): [
286+ - 1 for _ in range (len (params ['number_of_servers' ]))]
287+ for i in range (len (params ['arrival_distributions' ]))},
240288 }
241289
242290 for a in default_dict :
@@ -254,28 +302,38 @@ def validify_dictionary(params):
254302 params ['number_of_classes' ] ==
255303 len (params ['arrival_distributions' ]) ==
256304 len (params ['service_distributions' ]) ==
257- len (params ['batching_distributions' ]))
305+ len (params ['batching_distributions' ]) ==
306+ len (params ['reneging_time_distributions' ]) ==
307+ len (params ['reneging_destinations' ])
308+ )
258309 else :
259310 consistant_num_classes = (
260311 params ['number_of_classes' ] ==
261312 len (params ['arrival_distributions' ]) ==
262313 len (params ['service_distributions' ]) ==
263314 len (params ['routing' ]) ==
264- len (params ['batching_distributions' ]))
315+ len (params ['batching_distributions' ]) ==
316+ len (params ['reneging_time_distributions' ]) ==
317+ len (params ['reneging_destinations' ])
318+ )
265319 if not consistant_num_classes :
266320 raise ValueError ('Ensure consistant number of classes is used throughout.' )
267321 if all (isinstance (f , types .FunctionType ) for f in params ['routing' ]):
268322 consistant_class_names = (
269323 set (params ['arrival_distributions' ]) ==
270324 set (params ['service_distributions' ]) ==
271325 set (params ['batching_distributions' ]) ==
326+ set (params ['reneging_time_distributions' ]) ==
327+ set (params ['reneging_destinations' ]) ==
272328 set (['Class ' + str (i ) for i in range (params ['number_of_classes' ])]))
273329 else :
274330 consistant_class_names = (
275331 set (params ['arrival_distributions' ]) ==
276332 set (params ['service_distributions' ]) ==
277333 set (params ['routing' ]) ==
278334 set (params ['batching_distributions' ]) ==
335+ set (params ['reneging_time_distributions' ]) ==
336+ set (params ['reneging_destinations' ]) ==
279337 set (['Class ' + str (i ) for i in range (params ['number_of_classes' ])]))
280338 if not consistant_class_names :
281339 raise ValueError ('Ensure correct names for customer classes.' )
@@ -285,8 +343,11 @@ def validify_dictionary(params):
285343 len (obs ) for obs in params ['arrival_distributions' ].values ()] + [
286344 len (obs ) for obs in params ['service_distributions' ].values ()] + [
287345 len (obs ) for obs in params ['batching_distributions' ].values ()] + [
346+ len (obs ) for obs in params ['reneging_time_distributions' ].values ()] + [
347+ len (obs ) for obs in params ['reneging_destinations' ].values ()] + [
288348 len (params ['routing' ])] + [
289349 len (params ['number_of_servers' ])] + [
350+ len (params ['server_priority_functions' ])] + [
290351 len (params ['queue_capacities' ])]
291352 else :
292353 num_nodes_count = [
@@ -295,12 +356,15 @@ def validify_dictionary(params):
295356 len (obs ) for obs in params ['service_distributions' ].values ()] + [
296357 len (obs ) for obs in params ['routing' ].values ()] + [
297358 len (obs ) for obs in params ['batching_distributions' ].values ()] + [
359+ len (obs ) for obs in params ['reneging_time_distributions' ].values ()] + [
360+ len (obs ) for obs in params ['reneging_destinations' ].values ()] + [
298361 len (row ) for row in [obs for obs in params ['routing' ].values ()][0 ]] + [
299362 len (params ['number_of_servers' ])] + [
363+ len (params ['server_priority_functions' ])] + [
300364 len (params ['queue_capacities' ])]
301365 if len (set (num_nodes_count )) != 1 :
302366 raise ValueError ('Ensure consistant number of nodes is used throughout.' )
303- if not all (isinstance (f , types .FunctionType ) for f in params ['routing' ]):
367+ if not all (isinstance (f , types .FunctionType ) for f in params ['routing' ]):
304368 for clss in params ['routing' ].values ():
305369 for row in clss :
306370 if sum (row ) > 1.0 or min (row ) < 0.0 or max (row ) > 1.0 :
@@ -320,7 +384,16 @@ def validify_dictionary(params):
320384 for row in nd :
321385 if sum (row ) > 1.0 or min (row ) < 0.0 or max (row ) > 1.0 :
322386 raise ValueError ('Ensure that class change matrix is valid.' )
387+ if 'class_change_time_distributions' in params :
388+ wrong_num_classes = any (len (row ) != params ['number_of_classes' ] for row in params ['class_change_time_distributions' ]) or (len (params ['class_change_time_distributions' ]) != params ['number_of_classes' ])
389+ if wrong_num_classes :
390+ raise ValueError ('Ensure correct number of customer classes used in class_change_time_distributions.' )
323391 for n in params ['number_of_servers' ]:
324392 if isinstance (n , str ) and n != 'Inf' :
325393 if n not in params :
326394 raise ValueError ('No schedule ' + str (n ) + ' defined.' )
395+ possible_destinations = list (range (1 , params ['number_of_nodes' ] + 1 )) + [- 1 ]
396+ for dests in params ['reneging_destinations' ]:
397+ correct_destinations = all (d in possible_destinations for d in params ['reneging_destinations' ][dests ])
398+ if not correct_destinations :
399+ raise ValueError ('Ensure all reneging destinations are possible.' )
0 commit comments