def acs_vehicle(new_graph, vehicle_num, ants_num, q0, beta, global_path_queue, path_found_queue, stop_event): # vehicle_num is set to one less than the current best_path print('[acs_vehicle]: start, vehicle_num %d' % vehicle_num) global_best_path = None global_best_distance = None # Initialize path and distance using nearest_neighbor_heuristic algorithm current_path, current_path_distance, _ = new_graph.nearest_neighbor(max_vehicle_num=vehicle_num) # Find the unvisited nodes in the current path current_index_to_visit = list(range(new_graph.node_num)) for ind in set(current_path): current_index_to_visit.remove(ind) ants_pool = ThreadPoolExecutor(ants_num) ants_thread = [] ants = [] IN = np.zeros(new_graph.node_num) while True: print('[acs_vehicle]: new iteration') if stop_event.is_set(): print('[acs_vehicle]: receive stop event') return for k in range(ants_num): ant = Ant(new_graph, 0) thread = ants_pool.submit(MultipleAntColonySystem.new_active_ant, ant, vehicle_num, False, IN, q0, beta, stop_event) ants_thread.append(thread) ants.append(ant) # Here you can use the result method and wait for the thread to finish for thread in ants_thread: thread.result() for ant in ants: if stop_event.is_set(): print('[acs_vehicle]: receive stop event') return IN[ant.index_to_visit] = IN[ant.index_to_visit] + 1 # The path found by the ant is compared with the current_path, can you use the vehicle_num # vehicles to access more nodes if len(ant.index_to_visit) < len(current_index_to_visit): current_path = copy.deepcopy(ant.travel_path) current_index_to_visit = copy.deepcopy(ant.index_to_visit) current_path_distance = ant.total_travel_distance # And set IN to 0 IN = np.zeros(new_graph.node_num) # If this path is easy, it will be sent to macs_vrptw if ant.index_to_visit_empty(): print('[acs_vehicle]: found a feasible path, send path info to macs') path_found_queue.put(Path(ant.travel_path, ant.total_travel_distance)) # Update the pheromone in new_graph, global new_graph.global_update_pheromone(current_path, current_path_distance) if not global_path_queue.empty(): info = global_path_queue.get() while not global_path_queue.empty(): info = global_path_queue.get() print('[acs_vehicle]: receive global path info') global_best_path, global_best_distance, global_used_vehicle_num = info.get_path_info() new_graph.global_update_pheromone(global_best_path, global_best_distance) ants_thread.clear() for ant in ants: ant.clear() del ant ants.clear()
def acs_time(new_graph, vehicle_num, ants_num, q0, beta, global_path_queue, path_found_queue, stop_event): # You can use vehicle_num vehicles at most, that is, the path contains the most vehicle_num + 1 # depots to find the shortest path, vehicle_num is set to be consistent with the current best_path print('[acs_time]: start, vehicle_num %d' % vehicle_num) # initialize the pheromone matrix global_best_path = None global_best_distance = None ants_pool = ThreadPoolExecutor(ants_num) ants_thread = [] ants = [] while True: print('[acs_time]: new iteration') if stop_event.is_set(): print('[acs_time]: receive stop event') return for k in range(ants_num): ant = Ant(new_graph, 0) thread = ants_pool.submit(MultipleAntColonySystem.new_active_ant, ant, vehicle_num, True, np.zeros(new_graph.node_num), q0, beta, stop_event) ants_thread.append(thread) ants.append(ant) # Here you can use the result method and wait for the thread to finish for thread in ants_thread: thread.result() ant_best_travel_distance = None ant_best_path = None # Determine whether the path found by the ant is feasible and better than the global path for ant in ants: if stop_event.is_set(): print('[acs_time]: receive stop event') return # Get the current best path if not global_path_queue.empty(): info = global_path_queue.get() while not global_path_queue.empty(): info = global_path_queue.get() print('[acs_time]: receive global path info') global_best_path, global_best_distance, global_used_vehicle_num = info.get_path_info() # The shortest path calculated by the ant if ant.index_to_visit_empty() and ( ant_best_travel_distance is None or ant.total_travel_distance < ant_best_travel_distance): ant_best_travel_distance = ant.total_travel_distance ant_best_path = ant.travel_path # Perform global update of pheromone here new_graph.global_update_pheromone(global_best_path, global_best_distance) # Send the calculated current best path to macs if ant_best_travel_distance is not None and ant_best_travel_distance < global_best_distance: print('[acs_time]: ants\' local search found a improved feasible path, send path info to macs') path_found_queue.put(Path(ant_best_path, ant_best_travel_distance)) ants_thread.clear() for ant in ants: ant.clear() del ant ants.clear()