def new_active_ant(ant: Ant, vehicle_num: int, local_search: bool, IN: np.numarray, q0: float, beta: int, stop_event: Event): """ :param ant: :param vehicle_num: :param local_search: :param IN: :param q0: :param beta: :param stop_event: :return: """ # print('[new_active_ant]: start, start_index %d' % ant.travel_path[0]) unused_depot_count = vehicle_num while not ant.index_to_visit_empty() and unused_depot_count > 0: if stop_event.is_set(): # print('[new_active_ant]: receive stop event') return next_index_meet_constrains = ant.cal_next_index_meet_constrains() if len(next_index_meet_constrains) == 0: ant.move_to_next_index(0) unused_depot_count -= 1 continue length = len(next_index_meet_constrains) ready_time = np.zeros(length) due_time = np.zeros(length) for i in range(length): ready_time[i] = ant.graph.nodes[ next_index_meet_constrains[i]].ready_time due_time[i] = ant.graph.nodes[ next_index_meet_constrains[i]].due_time delivery_time = np.maximum( ant.vehicle_travel_time + ant.graph.node_dist_mat[ ant.current_index][next_index_meet_constrains], ready_time) delta_time = delivery_time - ant.vehicle_travel_time distance = delta_time * (due_time - ant.vehicle_travel_time) distance = np.maximum(1.0, distance - IN[next_index_meet_constrains]) closeness = 1 / distance transition_prob = ant.graph.pheromone_mat[ant.current_index][next_index_meet_constrains] * \ np.power(closeness, beta) transition_prob = transition_prob / np.sum(transition_prob) if np.random.rand() < q0: max_prob_index = np.argmax(transition_prob) next_index = next_index_meet_constrains[max_prob_index] else: next_index = MultipleAntColonySystem.stochastic_accept( next_index_meet_constrains, transition_prob) ant.graph.local_update_pheromone(ant.current_index, next_index) ant.move_to_next_index(next_index) if ant.index_to_visit_empty(): ant.graph.local_update_pheromone(ant.current_index, 0) ant.move_to_next_index(0) ant.insertion_procedure(stop_event) if local_search is True and ant.index_to_visit_empty(): ant.local_search_procedure(stop_event)
def new_active_ant(ant: Ant, vehicle_num: int, local_search: bool, IN: np.numarray, q0: float, beta: int, stop_event: Event): """ 按照指定的vehicle_num在地图上进行探索,所使用的vehicle num不能多于指定的数量,acs_time和acs_vehicle都会使用到这个方法 对于acs_time来说,需要访问完所有的结点(路径是可行的),尽量找到travel distance更短的路径 对于acs_vehicle来说,所使用的vehicle num会比当前所找到的best path所使用的车辆数少一辆,要使用更少的车辆,尽量去访问结点,如果访问完了所有的结点(路径是可行的),就将通知macs :param ant: :param vehicle_num: :param local_search: :param IN: :param q0: :param beta: :param stop_event: :return: """ # print('[new_active_ant]: start, start_index %d' % ant.travel_path[0]) # 在new_active_ant中,最多可以使用vehicle_num个车,即最多可以包含vehicle_num+1个depot结点,由于出发结点用掉了一个,所以只剩下vehicle个depot unused_depot_count = vehicle_num # 如果还有未访问的结点,并且还可以回到depot中 while not ant.index_to_visit_empty() and unused_depot_count > 0: if stop_event.is_set(): # print('[new_active_ant]: receive stop event') return # 计算所有满足载重等限制的下一个结点 next_index_meet_constrains = ant.cal_next_index_meet_constrains() # 如果没有满足限制的下一个结点,则回到depot中 if len(next_index_meet_constrains) == 0: ant.move_to_next_index(0) unused_depot_count -= 1 continue # 开始计算满足限制的下一个结点,选择各个结点的概率 length = len(next_index_meet_constrains) ready_time = np.zeros(length) due_time = np.zeros(length) for i in range(length): ready_time[i] = ant.graph.nodes[next_index_meet_constrains[i]].ready_time due_time[i] = ant.graph.nodes[next_index_meet_constrains[i]].due_time delivery_time = np.maximum(ant.vehicle_travel_time + ant.graph.node_dist_mat[ant.current_index][next_index_meet_constrains], ready_time) delta_time = delivery_time - ant.vehicle_travel_time distance = delta_time * (due_time - ant.vehicle_travel_time) distance = np.maximum(1.0, distance-IN[next_index_meet_constrains]) closeness = 1/distance transition_prob = ant.graph.pheromone_mat[ant.current_index][next_index_meet_constrains] * \ np.power(closeness, beta) transition_prob = transition_prob / np.sum(transition_prob) # 按照概率直接选择closeness最大的结点 if np.random.rand() < q0: max_prob_index = np.argmax(transition_prob) next_index = next_index_meet_constrains[max_prob_index] else: # 使用轮盘赌算法 next_index = MultipleAntColonySystem.stochastic_accept(next_index_meet_constrains, transition_prob) # 更新信息素矩阵 ant.graph.local_update_pheromone(ant.current_index, next_index) ant.move_to_next_index(next_index) # 如果走完所有的点了,需要回到depot if ant.index_to_visit_empty(): ant.graph.local_update_pheromone(ant.current_index, 0) ant.move_to_next_index(0) # 对未访问的点进行插入,保证path是可行的 ant.insertion_procedure(stop_event) # ant.index_to_visit_empty()==True就是feasible的意思 if local_search is True and ant.index_to_visit_empty(): ant.local_search_procedure(stop_event)