def random_walk_weighted_no_visited(apf, start, distance_target, pre_matrix, genome, K): """ Generate the trajectory using the random walk weighted with no visited checks on From the starting point it finds the neighbour nodes it checks if they are road it checks if they are already visited if no point are available -> end get the precomputed attraction for all the nodes remaining normalise attraction value to be probabilities compute the random next node move to the chosen node repeat :param apf: artificial potential field, needed to check the neighbour node :param start: starting point :param distance_target: how many timestep max to generate :param pre_matrix: preloaded attraction values :param genome: multiplier for the attraction :param K: constant for the coulomb equation :return: list of nodes -> final trajectory """ already_visited = {} # start from the first point final_trajectory = [start] already_visited["{}-{}".format(start.x, start.y)] = 1 current_node = start # generate distance_target steps for step in range(distance_target): # Generate children points = list_neighbours(x_value=current_node.x, y_value=current_node.y, apf=apf) points_on_the_street = pre_matrix.keep_only_points_on_street(points=points) # check if nodes are already visited real_points_on_the_street = [node for node in points_on_the_street if "{}-{}".format(node.x, node.y) not in already_visited] if len(real_points_on_the_street) == 0: break total_charges = [pre_matrix.return_charge_from_point(current_position=node, genome=genome, K=K) for node in real_points_on_the_street] total_charges = np.array([el / sum(total_charges) for el in total_charges]) # random walk, select randomly where to go current_node = np.random.choice(a=real_points_on_the_street, size=1, p=total_charges)[0] final_trajectory.append(current_node) already_visited["{}-{}".format(current_node.x, current_node.y)] = 1 return final_trajectory
def random_walk_no_visited(apf, start, distance_target, pre_matrix): """ Generate the trajectory using the random walk From the starting point it finds the neighbour nodes it checks if they are road it checks if they are already visited if no nodes available generation stops compute the random next node move to the chosen node repeat :param apf: artificial potential field, needed to check the neighbour node :param start: starting point :param distance_target: how many timestep max to generate :param pre_matrix: preloaded attraction values :return: list of nodes -> final trajectory """ already_visited = {} # start from the first point final_trajectory = [start] already_visited["{}-{}".format(start.x, start.y)] = 1 current_node = start # generate distance_target steps for step in range(distance_target): # Generate children points = list_neighbours(x_value=current_node.x, y_value=current_node.y, apf=apf) points_on_the_street = pre_matrix.keep_only_points_on_street( points=points) # check if nodes are already visited real_points_on_the_street = [ node for node in points_on_the_street if "{}-{}".format(node.x, node.y) not in already_visited ] if len(real_points_on_the_street) == 0: break # random walk, select randomly where to go index_max = np.random.random_integers( low=0, high=len(real_points_on_the_street) - 1) current_node = real_points_on_the_street[index_max] final_trajectory.append(current_node) already_visited["{}-{}".format(current_node.x, current_node.y)] = 1 return final_trajectory
def random_walk_standard(apf, start, distance_target, pre_matrix): """ Generate the trajectory using the random walk From the starting point it finds the neighbour nodes it checks if they are road compute the random next node move to the chosen node repeat :param apf: artificial potential field, needed to check the neighbour node :param start: starting point :param distance_target: how many timestep max to generate :param pre_matrix: preloaded attraction values :return: list of nodes -> final trajectory """ # start from the first point final_trajectory = [start] current_node = start # generate distance_target steps for step in range(distance_target): # Generate children points = list_neighbours(x_value=current_node.x, y_value=current_node.y, apf=apf) points_on_the_street = pre_matrix.keep_only_points_on_street( points=points) # random walk, select randomly where to go index_max = np.random.random_integers(low=0, high=len(points_on_the_street) - 1) current_node = points_on_the_street[index_max] final_trajectory.append(current_node) return final_trajectory
def chain_of_neighbours(total_distance, genome, genome_meaning, values_matrix, K, distances, current_node, apf, pre_matrix): """ From current position check the neighbours for the most attractive one and move there. Loop till reach maximum length -> check neighbours nodes in order to find the one with the strongest attraction -> check only neighbours that have charge != 0 (in order to stay on routes) -> compute attraction points using coulomb law: |E| = k(|q|/r^2). r is computed using haversine measure -> move to the location with strongest attraction -> save the point as next point of the path -> increase counter of distance travelled -> repeat until I reach distance expressed by gene of genome :param total_distance: total distance to travel :param genome: genome :param genome_meaning: meaning if every pos of the genome :param values_matrix: values to translate cells to coordinates :param K: constant for the computation of the charge :param distances: vector with distances positions :param current_node: current node :param apf: apf :param pre_matrix: pre computation of distance from the cell to the objects :return: path """ path = [] distance_travelled = 0 while distance_travelled < total_distance: # return neighbours of current node points = list_neighbours(x_value=current_node.x, y_value=current_node.y, apf=apf) points_on_the_street = keep_only_points_on_street(apf=apf, points=points) if len(points_on_the_street) == 0: # I cannot move in a street around me path.append(current_node) break # compute charge close points charges = [ compute_charge_points(genome=genome, current_position=current_position, K=K, pre_matrix=pre_matrix) for current_position in points_on_the_street ] # find most attractive point most_attractive_point = points_on_the_street[charges.index( max(charges))] # adding point to path path.append(most_attractive_point) # compute distance dis = haversine( (values_matrix[0][current_node.x], values_matrix[1][current_node.y]), (values_matrix[0][most_attractive_point.x], values_matrix[1][most_attractive_point.y])) * 1000 # in metres distances.append(dis) distance_travelled += dis current_node = most_attractive_point return path
def astar(apf, start, distance_target, genome, values_matrix, K, pre_matrix, x_value, type_astar): """ Returns a list of tuples as a path from the given start to the given end in the given maze This is a normal a star algorithm is supposed to work The current version does not know the destination point It only knows the distance from the destination point :param apf: matrix representing the routing system of the area :param start: starting point :param distance_target: distance from the target (total length trip) :param genome: genome :param values_matrix: values to translate cells to coordinates :param K: constant for computing charge :param pre_matrix: pre computation of distance from the cell to the objects :param type_astar: typology of the astar wanted """ # make x_value a percentege of the total distance target x_value = (distance_target * x_value) / 100 # end_node = Node(parent=None, position=end_point) # if it takes too long, going to stop it # start_time = time.time() # Create start and end node start_node = Node(parent=None, position=start) start_node.g = start_node.h = start_node.f = 0 # Initialize both open and closed list # open_list = [] open_queue = [] second_open_queue = {} closed_list = {} # Add the start node # open_list.append(start_node) heapq.heappush(open_queue, (start_node.f, start_node)) second_open_queue.update({start_node.id: 0}) # Loop until you find the end while len(open_queue) > 0: # Get the current node # current_node = open_list[0] # current_index = 0 # for index, item in enumerate(open_list): # if item.f < current_node.f: # current_node = item # current_index = index current_node = heapq.heappop(open_queue)[1] del second_open_queue[current_node.id] # with open("a_star_{}.txt".format(LoadConfigs.configurations["name_exp"]), "a") as myfile: # myfile.write("current node -> {} \n".format(current_node)) # Pop current off open list, add to closed list # open_list.pop(current_index) # closed_list.add(current_node) closed_list[current_node.id] = "" # current_time = time.time() # time_from_start = current_time - start_time # time in seconds # block execution astar after 10 minutes -> hardcoded function # end = False # if time_from_start >= 300: # end = True # find the bigger node.g # max_id = max(second_open_queue.items(), key=operator.itemgetter(1))[0] # # for el in open_queue: # if el[1].id == max_id: # current_node = el[1] # break # distance_target = current_node.g - 10 # Found the goal # on the cuxrrent node, the distance from the start is saved as g # so if the distance from the start is equals to distance_target then I found the goal # if current_node.id == end_node.id: # or end: if current_node.g >= distance_target: # with open("a_star_{}.txt".format(LoadConfigs.configurations["name_exp"]), "a") as myfile: # myfile.write("closed list {}, open list {} \n".format(len(closed_list), len(second_open_queue))) # myfile.write("------------------ \n") # myfile.write("------------------ \n") # myfile.write("------------------ \n") return return_best_path_so_far(current_node=current_node) # Generate children points = list_neighbours(x_value=current_node.position.x, y_value=current_node.position.y, apf=apf) # points_on_the_street = keep_only_points_on_street(apf=pre_matrix.get_apf(), points=points) points_on_the_street = pre_matrix.keep_only_points_on_street(points=points) children = [Node(parent=current_node, position=node_position) for node_position in points_on_the_street] # for node_position in points_on_the_street: # Adjacent squares # # # Create new node # new_node = Node(current_node, node_position) # # # Append # children.append(new_node) # Loop through children for child in children: # Child is on the closed list if closed_list.get(child.id, None) is not None: # if child in closed_list: continue # Child already computed if second_open_queue.get(child.id, None) is not None: # result = list(filter(lambda x: x[1] == child, open_queue)) # if len(result) > 0: continue # Create the f, g, and h values r = haversine((values_matrix[0][child.position.x], values_matrix[1][child.position.y]), (values_matrix[0][current_node.position.x], values_matrix[1][current_node.position.y])) * 1000 # in metres child.g = current_node.g + r # distance to end is total distance - distance from start distance_to_end = distance_target - child.g # distance_to_end = haversine((values_matrix[0][child.position.x], values_matrix[1][child.position.y]), # (values_matrix[0][end_node.position.x], # values_matrix[1][end_node.position.y])) * 1000 # in metres child.h = abs(_compute_h(distance_to_end=distance_to_end, genome=genome, type_astar=type_astar, current_position=child.position, K=K, pre_matrix=pre_matrix, x_value=x_value, tra_moved_so_far=return_best_path_so_far(current_node=current_node) if type_astar == 1 else None)) total_g_normalised = _standard_normalisation(old_value=child.g, old_min=0, old_max=distance_target + 100, new_min=0, new_max=10) # now higher is the most attractive child.f = -(total_g_normalised + child.h) # child.f = -child.h # Child is already in the open list # result = list(filter(lambda x: x[1] == child, open_queue)) # if len(result) > 0 and child.g > result[0].g: # continue res = second_open_queue.get(child.id, None) # if res is not None: # print("S") if res is not None and child.g > res: continue # print(child) # Add the child to the open list # open_list.append(child) heapq.heappush(open_queue, (child.f, child)) second_open_queue.update({child.id: child.g})
def random_walk_weighted_fitness(apf, start, distance_target, pre_matrix, genome, K): """ Generate the trajectory using the random walk weighted (fitness attraction based) From the starting point it finds the neighbour nodes it checks if they are road compute fitness the trajectory would have if moving in that location get the precomputed attraction for all the nodes remaining combine fitness and attraction normalise values to be probabilities compute the random next node move to the chosen node repeat :param apf: artificial potential field, needed to check the neighbour node :param start: starting point :param distance_target: how many timestep max to generate :param pre_matrix: preloaded attraction values :param genome: multiplier for the attraction :param K: constant for the coulomb equation :return: list of nodes -> final trajectory """ # start from the first point final_trajectory = [start] current_node = start # generate distance_target steps for step in range(distance_target): time_start = time.time() # Generate children points = list_neighbours(x_value=current_node.x, y_value=current_node.y, apf=apf) points_on_the_street = pre_matrix.keep_only_points_on_street( points=points) total_charges = [] for node in points_on_the_street: tra_moved_so_far = copy.deepcopy(final_trajectory) tra_moved_so_far.append(node) total_charge, _ = compute_fintess_trajectory( tra_moved_so_far=tra_moved_so_far) total_charges.append(total_charge) total_charges_attraction = [ pre_matrix.return_charge_from_point(current_position=node, genome=genome, K=K) for node in points_on_the_street ] total_charges = np.array([ convert(old_max=700, old_min=-750, new_max=10, new_min=1, old_value=el) for el in total_charges ]) total_charges_attraction = np.array([ convert(old_max=10000, old_min=0, new_max=10, new_min=1, old_value=el) for el in total_charges_attraction ]) real_total_charge = (total_charges * total_charges_attraction).tolist() real_total_charge_normalised = [ convert(old_value=el, old_min=0, old_max=100, new_min=0, new_max=10) for el in real_total_charge ] total_charges = np.array([ el / sum(real_total_charge_normalised) for el in real_total_charge_normalised ]) # random walk, select randomly where to go current_node = np.random.choice(a=points_on_the_street, size=1, p=total_charges)[0] final_trajectory.append(current_node) return final_trajectory