Example #1
0
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']