66
77import networkx as nx
88
9- from .auxiliary import random_choice
9+ from .auxiliary import random_choice , flatten_list
1010from .data_record import DataRecord
1111from .server import Server
1212
@@ -54,19 +54,20 @@ def __init__(self, id_, simulation):
5454 else :
5555 self .next_event_date = float ("Inf" )
5656 self .blocked_queue = []
57+ self .len_blocked_queue = 0
5758 if not isinf (self .c ):
5859 self .servers = self .create_starting_servers ()
5960 self .highest_id = self .c
6061 self .simulation .deadlock_detector .initialise_at_node (self )
6162 self .preempt = node .preempt
6263 self .interrupted_individuals = []
64+ self .number_interrupted_individuals = 0
6365 self .all_servers_total = []
6466 self .all_servers_busy = []
6567
6668 @property
6769 def all_individuals (self ):
68- return [i for priority_class in self .individuals
69- for i in priority_class ]
70+ return flatten_list (self .individuals )
7071
7172 def __repr__ (self ):
7273 """
@@ -132,12 +133,20 @@ def begin_interrupted_individuals_service(self, current_time, srvr):
132133 resampling service time)
133134 """
134135 ind = [i for i in self .interrupted_individuals ][0 ]
136+ if ind .is_blocked :
137+ node_blocked_to = self .simulation .nodes [ind .destination ]
138+ ind .destination = False
139+ node_blocked_to .blocked_queue .remove ((self .id_number , ind .id_number ))
140+ node_blocked_to .len_blocked_queue -= 1
141+ ind .is_blocked = False
135142 ind .service_time = self .get_service_time (ind .customer_class ,
136143 current_time )
137144 ind .service_end_date = self .increment_time (self .get_now (current_time ),
138145 ind .service_time )
146+ ind .interrupted = False
139147 self .attach_server (srvr , ind )
140148 self .interrupted_individuals .remove (ind )
149+ self .number_interrupted_individuals -= 1
141150
142151 def begin_service_if_possible_change_shift (self , current_time ):
143152 """
@@ -146,14 +155,16 @@ def begin_service_if_possible_change_shift(self, current_time):
146155 """
147156 free_servers = [s for s in self .servers if not s .busy ]
148157 for srvr in free_servers :
149- if len ( self .interrupted_individuals ) > 0 :
158+ if self .number_interrupted_individuals > 0 :
150159 self .begin_interrupted_individuals_service (current_time , srvr )
151- elif len ([i for i in self .all_individuals if not i .server ]) > 0 :
152- ind = [i for i in self .all_individuals if not i .server ][0 ]
153- ind .service_start_date = self .get_now (current_time )
154- ind .service_end_date = self .increment_time (
155- ind .service_start_date , ind .service_time )
156- self .attach_server (srvr , ind )
160+ else :
161+ inds_without_server = [i for i in self .all_individuals if not i .server ]
162+ if len (inds_without_server ) > 0 :
163+ ind = inds_without_server [0 ]
164+ ind .service_start_date = self .get_now (current_time )
165+ ind .service_end_date = self .increment_time (
166+ ind .service_start_date , ind .service_time )
167+ self .attach_server (srvr , ind )
157168
158169 def begin_service_if_possible_release (self , current_time ):
159170 """
@@ -162,14 +173,16 @@ def begin_service_if_possible_release(self, current_time):
162173 """
163174 if self .free_server () and (not isinf (self .c )):
164175 srvr = self .find_free_server ()
165- if len ( self .interrupted_individuals ) > 0 :
176+ if self .number_interrupted_individuals > 0 :
166177 self .begin_interrupted_individuals_service (current_time , srvr )
167- elif len ([i for i in self .all_individuals if not i .server ]) > 0 :
168- ind = [i for i in self .all_individuals if not i .server ][0 ]
169- ind .service_start_date = self .get_now (current_time )
170- ind .service_end_date = self .increment_time (
171- ind .service_start_date , ind .service_time )
172- self .attach_server (srvr , ind )
178+ else :
179+ inds_without_server = [i for i in self .all_individuals if not i .server ]
180+ if len (inds_without_server ) > 0 :
181+ ind = inds_without_server [0 ]
182+ ind .service_start_date = self .get_now (current_time )
183+ ind .service_end_date = self .increment_time (
184+ ind .service_start_date , ind .service_time )
185+ self .attach_server (srvr , ind )
173186
174187 def block_individual (self , individual , next_node ):
175188 """
@@ -181,8 +194,10 @@ def block_individual(self, individual, next_node):
181194 individual .customer_class )
182195 next_node .blocked_queue .append (
183196 (self .id_number , individual .id_number ))
197+ next_node .len_blocked_queue += 1
184198 self .simulation .deadlock_detector .action_at_blockage (
185199 individual , next_node )
200+ self .simulation .unchecked_blockage = True
186201
187202 def change_customer_class (self ,individual ):
188203 """
@@ -192,7 +207,7 @@ def change_customer_class(self,individual):
192207 if self .class_change :
193208 individual .previous_class = individual .customer_class
194209 individual .customer_class = random_choice (
195- range (len ( self .class_change ) ),
210+ range (self .simulation . network . number_of_classes ),
196211 self .class_change [individual .previous_class ])
197212 individual .prev_priority_class = individual .priority_class
198213 individual .priority_class = self .simulation .network .priority_class_mapping [individual .customer_class ]
@@ -370,7 +385,7 @@ def release_blocked_individual(self, current_time):
370385 Releases an individual who becomes unblocked
371386 when another individual is released.
372387 """
373- if len ( self .blocked_queue ) > 0 and self .number_of_individuals < self .node_capacity :
388+ if self .len_blocked_queue > 0 and self .number_of_individuals < self .node_capacity :
374389 node_to_receive_from = self .simulation .nodes [
375390 self .blocked_queue [0 ][0 ]]
376391 individual_to_receive_index = [ind .id_number
@@ -379,6 +394,11 @@ def release_blocked_individual(self, current_time):
379394 individual_to_receive = node_to_receive_from .all_individuals [
380395 individual_to_receive_index ]
381396 self .blocked_queue .pop (0 )
397+ self .len_blocked_queue -= 1
398+ if individual_to_receive .interrupted :
399+ individual_to_receive .interrupted = False
400+ node_to_receive_from .interrupted_individuals .remove (individual_to_receive )
401+ node_to_receive_from .number_interrupted_individuals -= 1
382402 node_to_receive_from .release (individual_to_receive_index ,
383403 self , current_time )
384404
@@ -409,13 +429,16 @@ def take_servers_off_duty(self):
409429 s .shift_end = self .next_event_date
410430 if s .cust is not False :
411431 self .interrupted_individuals .append (s .cust )
432+ s .cust .interrupted = True
433+ self .number_interrupted_individuals += 1
412434 self .interrupted_individuals [- 1 ].service_end_date = False
413435 self .interrupted_individuals [- 1 ].service_time = False
414436 self .interrupted_individuals .sort (key = lambda x : (x .priority_class ,
415437 x .arrival_date ))
416438 for obs in to_delete :
417439 self .kill_server (obs )
418440
441+
419442 def update_next_event_date (self , current_time ):
420443 """
421444 Finds the time of the next event at this node
0 commit comments