def cost_path(G, source, target, vehicle_mass, impedance): """ This function calculates the path between source and target nodes, and returns it. Besides, calculates the sum of all edges weight of the path, and returns it. :param G: NetworkX graph. Geographic scenario :param source: :param target: :param vehicle_mass: :return: """ # updates the weight of all edges of the scenario according # to the current weight of the vehicle G = Graph.update_weight(G, vehicle_mass) # finds the shortest path to the destination in the scenario graph path = Heuristics.shortest_path_faster(G, source, target, weight=impedance) # cost to get to the destination: # the sum of the weight of all the edges from the path sum_path_costs = sum_costs(G, path, impedance) # updates the weight of all edges of the scenario according # to the current weight of the vehicle G = Graph.update_weight(G, VEHICLE_MASS) return sum_path_costs, path
def cost_path(G, source, target, vehicle_mass, impedance, heuristic): """ This function calculates the path between source and target nodes, and returns it. Besides, calculates the sum of all edges weight of the path, and returns it. :param G: NetworkX graph. Geographic scenario :param source: :param target: :param vehicle_mass: :return: """ # updates the weight of all edges of the scenario according # to the current weight of the vehicle if impedance == 'weight': G = Graph.update_weight(G, vehicle_mass) # finds the shortest path to the destination in the scenario graph if heuristic == 'SPFA': distance, path = Heuristics.bellman_ford(G, source, target, weight=impedance) #path = Heuristics.shortest_path_faster(G, source, target, impedance) elif heuristic == 'dijkstra': distance, path = Heuristics.bidirectional_dijkstra(G, source, target, weight=impedance) elif heuristic == 'astar': path = nx.astar_path(G, source, target, weight=impedance) else: distance, path = Heuristics.bellman_ford(G, source, target, weight=impedance) # cost to get to the destination: # the sum of the weight of all the edges from the path sum_path_costs = sum_costs(G, path, impedance) # updates the weight of all edges of the scenario according # to the current weight of the vehicle #if impedance == 'weight': # G = Graph.update_weight(G, VEHICLE_MASS) return sum_path_costs, path
def further_insertion(G, H, source, target, impedance, heuristic): current_vehicle_mass = VEHICLE_MASS path = [source] costs_to_source = {} # create a dictionary with the nodes and respective mass increments of the vehicle mass = {} for i in H.nodes: mass.update([(i, H.nodes[i]['mass'])]) # verify the cost of the source to the nodes for u in H.adj[source]: edge_cost, _ = Graph_Collect.cost_path(G, source, u, current_vehicle_mass, impedance, heuristic) costs_to_source.update([(u, edge_cost)]) # sorting the dict according to edge weights costs_to_source = dict( sorted(costs_to_source.items(), key=lambda item: item[1], reverse=True)) # add the closest node of the source path.append(list(costs_to_source.keys())[0]) # updates the vehicle mass according to current path current_vehicle_mass = updates_vehicle_mass(path, mass) nodes = list(H.nodes) nodes.remove(target) possibilities = set(nodes) - set(path) # all nodes must be visited while len(possibilities) > 0: # len(path) < len(nodes): # get the closest node of any node inside the path max_cost = float('-inf') k_node = float('inf') for a in path: for b in possibilities: cost, _ = Graph_Collect.cost_path(G, a, b, current_vehicle_mass, impedance, heuristic) if cost > max_cost: max_cost = cost k_node = b # the k node must be inserted in a position of the path # where the cost (cost_IK + cost_KJ - cost_IJ) is minimum max_cost = float('-inf') position = 0 for i in range(len(path) - 1): current_vehicle_mass = updates_vehicle_mass(path[:i], mass) cost_IK, _ = Graph_Collect.cost_path(G, path[i], k_node, current_vehicle_mass, impedance, heuristic) cost_KJ, _ = Graph_Collect.cost_path(G, k_node, path[i + 1], current_vehicle_mass, impedance, heuristic) cost_IJ, _ = Graph_Collect.cost_path(G, path[i], path[i + 1], current_vehicle_mass, impedance, heuristic) total_cost = cost_IK + cost_KJ - cost_IJ # print('costs', cost_IK, cost_KJ, cost_IJ, total_cost) if total_cost > max_cost: a_1 = path[i] a_2 = path[i + 1] max_cost = total_cost position = i + 1 path.insert(position, k_node) current_vehicle_mass = updates_vehicle_mass(path, mass) # nodes not yet visited possibilities = set(nodes) - set(path) path.append(target) # get all paths cost_total, paths, edges_update = Graph_Collect.sum_costs_route( G, H, path, VEHICLE_MASS, impedance, heuristic) if impedance == 'weight': G = Graph.update_weight(G, VEHICLE_MASS) return cost_total, paths, edges_update
def nearest_neighbor(G, H, source, target, impedance, heuristic): """ :param G: NetworkX graph. input graph :param source: Float Id of the start node :param target: Float Id of the goal node :param weight: Function :return: List List with all nodes of the shortest path """ if source not in H: print("Error") return False open = [source] closed = [] current_vehicle_mass = VEHICLE_MASS nodes_graph = list(H.nodes) nodes_graph.remove(target) route = [] route1 = [] cost_total = 0 edges_update_mass = [] while len(open) > 0: dist = {} node = open.pop(0) closed.append(node) missing = verifying_nodes(closed, nodes_graph) # if current node is the target (objective) and # there is not nodes missing to be visited if node == target and missing is False: if impedance == 'weight': G = Graph.update_weight(G, VEHICLE_MASS) fig, ax = ox.plot_graph_route(G, route1[-1], route_linewidth=6, node_size=0, bgcolor='w') return cost_total, route, edges_update_mass else: # checks nodes that have not yet been added in closed possibilities = set(H.adj[node]) - set(closed) for u in possibilities: # checks the edge weight according to the vehicle's mass + # mass increase at the current vertex edge_cost, path = Graph_Collect.cost_path( G, node, u, current_vehicle_mass, impedance, heuristic) dist.update([(u, [edge_cost, path])]) # sorting the dict according to edge weights dist = dict(sorted(dist.items(), key=lambda item: item[1][0])) # if starting and arrival point is the same node if len(dist) < 1 and source == target: new_node = target else: new_node = list(dist.keys())[0] # if there are more than one not visited node # and the nearest node is the arrival point if len(dist) > 1 and new_node == target: new_node = list(dist.keys())[1] route.extend(list(dist.values())[1][1][:-1]) route1.append(list(dist.values())[1][1][:-1]) cost_total += float(list(dist.values())[1][0]) edges_update_mass.append(list(dist.values())[0][1][:2]) elif new_node == target: route.extend(list(dist.values())[0][1]) route1.append(list(dist.values())[0][1]) cost_total += float(list(dist.values())[0][0]) edges_update_mass.append(list(dist.values())[0][1][:2]) else: route.extend(list(dist.values())[0][1][:-1]) route1.append(list(dist.values())[0][1][:-1]) cost_total += float(list(dist.values())[0][0]) edges_update_mass.append(list(dist.values())[0][1][:2]) open.append(new_node) current_vehicle_mass += H.nodes[new_node]['mass']