Пример #1
0
    def test_reconstruct_path(self):
        with pytest.raises(KeyError):
            XG = nx.DiGraph()
            XG.add_weighted_edges_from([
                ("s", "u", 10),
                ("s", "x", 5),
                ("u", "v", 1),
                ("u", "x", 2),
                ("v", "y", 1),
                ("x", "u", 3),
                ("x", "v", 5),
                ("x", "y", 2),
                ("y", "s", 7),
                ("y", "v", 6),
            ])
            predecessors, _ = nx.floyd_warshall_predecessor_and_distance(XG)

            path = nx.reconstruct_path("s", "v", predecessors)
            assert path == ["s", "x", "u", "v"]

            path = nx.reconstruct_path("s", "s", predecessors)
            assert path == []

            # this part raises the keyError
            nx.reconstruct_path("1", "2", predecessors)
Пример #2
0
def steiner_find(list_of_locations, list_of_homes, starting_car_location,
                 adjacency_matrix):
    G = nx.Graph(incoming_graph_data=adjacency_matrix, cutoff=1000)
    predecessors, distances = nx.floyd_warshall_predecessor_and_distance(G)
    homeIndices = []
    for h in list_of_homes:
        homeIndices.append(list_of_locations.index(h))
    # homeIndices.append(list_of_locations.index(starting_car_location))
    tree = apxa.steiner_tree(
        G, homeIndices + [list_of_locations.index(starting_car_location)])
    # print(list(tree.nodes))
    # print(homeIndices)
    # print(starting_car_location)
    # treematrix = nx.adjacency_matrix(tree)
    # return greedyAllPairs(list(tree.nodes), homeIndices, int(starting_car_location), treematrix)
    nodelist = list(tree.nodes())
    currIndex = list_of_locations.index(starting_car_location)
    visitedNodes = []
    path = [list_of_locations.index(starting_car_location)]
    dropoff_mapping = {}
    added = False
    # print(currIndex)
    nodelist = nodelist[
        nodelist.index(currIndex):] + nodelist[:nodelist.index(currIndex)]
    # print(nodelist)
    dropped = False
    allHomes = set(homeIndices)
    homeSet = set(homeIndices)
    length = len(nodelist) - 1
    i = 0
    while i in range(0, length):
        dropped = False
        homeNeighbors = list(
            homeSet.intersection(list(tree.neighbors(nodelist[i]))))
        if len(homeNeighbors) >= 3:
            dropped = True
            homeNeighbors = [j for j in homeNeighbors if j in homeSet]
            if (nodelist[i] in homeSet):
                homeNeighbors = homeNeighbors + [nodelist[i]]
            dropoff_mapping[nodelist[i]] = homeNeighbors
            homeSet = set([j for j in homeSet if j not in homeNeighbors])
        n = 1
        while i + n in range(0, length) and nodelist[
                i + n] in allHomes and nodelist[i + n] not in homeSet:
            n = n + 1
        path_to_next = nx.reconstruct_path(nodelist[i], nodelist[i + n],
                                           predecessors)
        path.extend(path_to_next[1:])
        if nodelist[i] in homeSet and not dropped:
            dropoff_mapping[nodelist[i]] = [nodelist[i]]
            homeSet.remove(nodelist[i])
        i = i + n
    if nodelist[-1] in homeSet:
        dropoff_mapping[nodelist[-1]] = [nodelist[-1]]
    path_to_start = nx.reconstruct_path(nodelist[-1], nodelist[0],
                                        predecessors)
    path.extend(path_to_start[1:])
    return path, dropoff_mapping
Пример #3
0
 def path_generate_for_truck_tsp(self, truck: Truck):
     """
     生成一个车辆的回路
     数学模型:d[i][status]表示从编号i城市出发,经过status中为1的顶点并回到配送中心的最小花费。其中状态status用二进制数来表示
     右起第i位表示第i个城市的状态,0为未拜访,1为已拜访。设i, j为顶点映射到整数的编号,u, v为对应的真实的顶点编号,则状态转移方程为:
     ```d[i][status] = min(dists[u][v] + d[j][status^(1<<j)]) for j=0 to n-1```
     其中v是u的所有邻接顶点,依次取值来得到最小值。dists[u][v]表示城市到城市u到v的最短路程。
     时间复杂度:Floyd预处理为O(n^3),枚举各种状态的时间复杂度为O(2^n*n^2),总的时间复杂度即为O(2^n*n^2)
     :param truck: 待生成回路的车辆
     :return: None
     """
     # 取子图,求Floyd
     subgraph = truck.subgraph.copy()
     predecessors, dists = nx.floyd_warshall_predecessor_and_distance(subgraph)
     subgraph.remove_node(0)  # 去除原图中的顶点0
     # 初始化动态规划数组及顶点映射
     n = len(subgraph)
     status_max = 1 << n
     d = {u: {} for u in subgraph}  # d[i][status]表示从编号i城市出发,经过status中为1的顶点并回到配送中心的最小花费
     path = {u: {} for u in subgraph}  # path[i][status]表示上述最小花费所走的路径
     mapping = {u: i for i, u in enumerate(subgraph)}  # 顶点到顶点编号的映射(因为子图的顶点并不是从0开始连续增1)
     for u in subgraph:
         d[u][0] = dists[u][0]  # 状态为0说明直接返回配送中心,因此距离即为当前顶点到配送中心的距离
         path[u][0] = nx.reconstruct_path(u, 0, predecessors)  # 并且上述距离对应的路径即为u直接到0
     # 动态规划配送网点
     for status in range(1, status_max - 1):
         for u in subgraph:
             dist_opt = np.inf
             path_opt = []
             for v in subgraph[u]:
                 status_v = 1 << mapping[v]
                 if status_v | status == status:  # 如果v属于当前的状态中
                     dist = dists[u][v] + d[v][status ^ status_v]  # 那么可将v去除
                     if dist < dist_opt:
                         dist_opt = dist
                         path_opt = nx.reconstruct_path(u, v, predecessors)[:-1] + path[v][status ^ status_v]
             if not np.isinf(dist_opt):
                 d[u][status] = dist_opt
                 path[u][status] = path_opt
     # 动态规划配送中心
     status = status_max - 1
     dist_opt = np.inf
     path_opt = []
     for v in truck.subgraph[0]:
         status_v = 1 << mapping[v]
         dist = dists[0][v] + d[v][status ^ status_v]
         if dist < dist_opt:
             dist_opt = dist
             path_opt = nx.reconstruct_path(0, v, predecessors)[:-1] + path[v][status ^ status_v]
     # 更新车辆路径
     truck.d = dist_opt
     truck.path = path_opt
 def get_next_step(self, currPos, destPos, router_type, weight):
     if str.lower(router_type) == 'dijkstra' and weight == 'delay':
         return nx.dijkstra_path(self.dynetwork._network, currPos, destPos, weight='edge_delay')[1]
     elif str.lower(router_type) == 'dijkstra':
         return nx.dijkstra_path(self.dynetwork._network, currPos, destPos)[1]
     else:
         return nx.reconstruct_path(currPos, destPos, self.preds)[1]
Пример #5
0
 def path_generate_for_truck_greedy(self, truck: Truck):
     """
     通过贪心算法,生成一个车辆的次优回路,时间复杂度为O(n^2)
     :param truck: 待生成回路的车辆
     :return: None
     """
     # Floyd预处理
     subgraph = truck.subgraph
     predecessors, dists = nx.floyd_warshall_predecessor_and_distance(subgraph)
     d = 0
     path = []
     visited = {u: False for u in subgraph}
     visited[0] = True
     # 从配送中心出发开始贪心
     u = 0
     for i in range(len(subgraph) - 1):
         v_opt = 0
         dist_opt = np.inf
         for v in subgraph:
             if not visited[v] and dists[u][v] < dist_opt:
                 v_opt = v
                 dist_opt = dists[u][v]
         visited[v_opt] = True
         d += dists[u][v_opt]
         path += nx.reconstruct_path(u, v_opt, predecessors)[:-1]
         u = v_opt
     # 更新车辆路径
     truck.d = d + dists[u][0]
     truck.path = path + [u, 0]
Пример #6
0
def findPath(graph, src, dest):
    # finds node predecessors using a function imported from networkx
    predecessors, _ = nx.floyd_warshall_predecessor_and_distance(graph)

    try:
        # finds the shortest path through the Floyd-Warshall algorithm by using a function imported from networkx
        path = nx.reconstruct_path(src, dest, predecessors)
        dpath = nx.dijkstra_path(graph, src, dest)
        bfpath = nx.bellman_ford_path(graph, src, dest)

        # prints the shortest path
        print("Path:", path)
        # print("Dijkstra's Path:", dpath)
        # print("Bellman-Ford Path:", bfpath)

        # prints the number of hops from source to destination
        print("Number of Hops:", len(path) - 1)
        # print("Dijkstra's Number of Hops:", len(dpath)-1)
        # print("Bellman-Ford Number of Hops:", len(bfpath)-1)

        # gets the total cost
        edge = 0
        for i in range(1, len(path)):
            edge += graph.edges[path[i - 1], path[i]]['weight']
        dpathcost = nx.dijkstra_path_length(graph, src, dest)
        bfpathcost = nx.bellman_ford_path_length(graph, src, dest)
        print("Total Cost:", edge)
        # print("Dijkstra's Total Cost:", dpathcost)
        # print("Bellman-Ford Total Cost:", bfpathcost)
        print()

    except:
        # Print to the terminal if no path exists.
        print("ERROR: No available path from source: node", src,
              "to destination: node", dest)
Пример #7
0
def greedyAllPairs(list_of_locations, list_of_homes, starting_car_location,
                   adjacency_matrix):
    #print(adjacency_matrix)
    G = nx.Graph(incoming_graph_data=adjacency_matrix, cutoff=1000)
    predecessors, distances = nx.floyd_warshall_predecessor_and_distance(G)
    list_of_homes = list_of_homes[:]

    def find_closest_home_to_location(location):
        distance = float('inf')
        closest_home = list_of_homes[0]
        for h in list_of_homes:
            home_idx = list_of_locations.index(h)
            location_idx = list_of_locations.index(location)
            new_dist = list(distances.items())[home_idx][1][location_idx]

            if new_dist < distance:
                distance = new_dist
                closest_home = h

        return closest_home, distance

    current = starting_car_location
    # print(list_of_locations)
    # print(list_of_homes)
    # print(starting_car_location)
    total_path = [list_of_locations.index(starting_car_location)]
    dropoff_mapping = {}

    for _ in range(len(list_of_homes)):
        closest, distance = find_closest_home_to_location(current)

        curr_idx = list_of_locations.index(current)
        next_idx = list_of_locations.index(closest)
        path_to_closest = nx.reconstruct_path(curr_idx, next_idx, predecessors)
        dropoff_mapping[next_idx] = [next_idx]
        total_path.extend(path_to_closest[1:])

        list_of_homes.remove(closest)
        current = closest

    start_idx = list_of_locations.index(starting_car_location)
    path_to_start = nx.reconstruct_path(next_idx, start_idx, predecessors)
    total_path.extend(path_to_start[1:])
    # print(dropoff_mapping)
    # print(total_path)

    return total_path, dropoff_mapping
Пример #8
0
    def test_reconstruct_path(self):
        XG = nx.DiGraph()
        XG.add_weighted_edges_from([('s', 'u', 10), ('s', 'x', 5),
                                    ('u', 'v', 1), ('u', 'x', 2),
                                    ('v', 'y', 1), ('x', 'u', 3),
                                    ('x', 'v', 5), ('x', 'y', 2),
                                    ('y', 's', 7), ('y', 'v', 6)])
        predecessors, _ = nx.floyd_warshall_predecessor_and_distance(XG)

        path = nx.reconstruct_path('s', 'v', predecessors)
        assert_equal(path, ['s', 'x', 'u', 'v'])

        path = nx.reconstruct_path('s', 's', predecessors)
        assert_equal(path, [])

        # this part raises the keyError
        nx.reconstruct_path('1', '2', predecessors)
Пример #9
0
def give_edges_weights(new_graph, old_graph, old_list_locations):
    # output: shortest_paths_between_homes
    predecessor, shortest = nx.floyd_warshall_predecessor_and_distance(old_graph)
    shortest_paths_between_homes = {}
    for (u, v) in new_graph.edges():
        # print("u,v : " + str(u) + " , " + str(v))
        left = old_list_locations.index(new_graph.nodes[u]['name'])
        right = old_list_locations.index(new_graph.nodes[v]['name'])
        #  print("(left,right): " + str(left) + " ," + str(right))
        new_graph[u][v]['weight'] = shortest[left][right]
        #  print(new_graph[u][v]['weight'])
        # u,v here is the index of newly created complete graph
        # left,right here is the index of old graph.
        # u <-> left, v <-> right
        shortest_paths_between_homes[(u, v)] = nx.reconstruct_path(left, right, predecessor)
        shortest_paths_between_homes[(v, u)] = nx.reconstruct_path(right, left, predecessor)
    return shortest_paths_between_homes
Пример #10
0
    def test_reconstruct_path(self):
        XG = nx.DiGraph()
        XG.add_weighted_edges_from([
            ('s', 'u', 10), ('s', 'x', 5), ('u', 'v', 1), ('u', 'x', 2),
            ('v', 'y', 1), ('x', 'u', 3), ('x', 'v', 5), ('x', 'y', 2),
            ('y', 's', 7), ('y', 'v', 6)
        ])
        predecessors, _ = nx.floyd_warshall_predecessor_and_distance(XG)

        path = nx.reconstruct_path('s', 'v', predecessors)
        assert_equal(path, ['s', 'x', 'u', 'v'])

        path = nx.reconstruct_path('s', 's', predecessors)
        assert_equal(path, [])

        # this part raises the keyError
        nx.reconstruct_path('1', '2', predecessors)
Пример #11
0
def all_pairs_shortest_paths(graph):
    """Returns a dictionary of dictionaries. Each inner dictionary is indexed by a node
	and value is distance between outer key and inner key."""
    predecessors, lengths = nx.floyd_warshall_predecessor_and_distance(graph)
    paths = dict()
    for i in range(len(graph.nodes)):
        paths[i] = dict()
        for j in range(len(graph.nodes)):
            paths[i][j] = nx.reconstruct_path(i, j, predecessors)
    return lengths, paths
Пример #12
0
def RutaCorta(ciudad1,ciudad2,g):
    dist=0
    predecessors, _ = nx.floyd_warshall_predecessor_and_distance(g)
    ruta=nx.reconstruct_path(ciudad1, ciudad2, predecessors)
    for i in ruta:
        if i==ciudad1:
            j=i
        elif i==ciudad2:
            dist=g.get_edge_data(j,i)['weight']+dist
            return(ruta,dist)
        else:
            dist=g.get_edge_data(j,i)['weight']+dist
            j=i
Пример #13
0
def floyd_warshall(adj):
    try:
        import networkx as nx
    except ImportError:
        print("please install networkx first")
    else:
        # consider disconnected nodes as connected with np.inf weight, or disconnected graph causing error
        G = nx.convert_matrix.from_numpy_matrix(A = adj, create_using = nx.DiGraph)
        predecessors, distance = nx.floyd_warshall_predecessor_and_distance(G)
        N = adj.shape[0]
        paths = {}
        for i in range(N):
            for j in range(N):
                paths[str(i)+"_"+str(j)] = nx.reconstruct_path(i, j, predecessors)
        return paths, distance
Пример #14
0
    def find_path(self, graph, src, dest):
        # finds node predecessors using a function imported from networkx
        predecessors, _ = nx.floyd_warshall_predecessor_and_distance(graph)

        try:
            # finds the shortest path through the Floyd-Warshall algorithm by using a function imported from networkx
            self.path = nx.reconstruct_path(src, dest, predecessors)
            self.dpath = nx.dijkstra_path(graph, src, dest)
            self.bfpath = nx.bellman_ford_path(graph, src, dest)

        except:
            # Print to the terminal if no path exists.
            self.path = []
            self.dpath = []
            self.bfpath = []
Пример #15
0
 def find_main_routes(self):
     if self.v:
         print('Searching for main routes in graph')
     routes, lens = nx.floyd_warshall_predecessor_and_distance(self.graph)
     for src in sorted(self.nodes):
         for dst in sorted(self.nodes):
             if dst <= src or math.isinf(lens[src][dst]):
                 continue
             route = nx.reconstruct_path(src, dst, routes)
             self.main_routes[(src, dst)] = {
                 'route': route.copy(),
                 'len': lens[src][dst],
                 'delay': lens[src][dst] * self.delay_mks
             }
     if self.v:
         print(f'Found {len(self.main_routes)} main routes')
Пример #16
0
 def path(u, v):
     return nx.reconstruct_path(u, v, predecessors)
Пример #17
0
def get_route(source, target):
    predecessors = get_value('predecessors')
    route = nx.reconstruct_path(source, target, predecessors)
    return route
Пример #18
0
    def path_generate(self, truck: Truck):
        """
        生成一个卡车的回路
        :param truck: 待生成回路的卡车
        :return: None

        数学模型:dp[i][v]表示在状态v下,到达城市i所用的最小花费。其中状态v用二进制数来表示
        右起第i位表示第i个城市的状态,0为未拜访,1为已拜访。则状态转移方程为:
            dp[i][v]=min(dp[i][v],dp[k][v^(1<<(i-1)]+dist[k][i])
        其中k从1到n依次取值来得到最小值,dist[k][i]表示城市k到城市i的路程,^为异或运算,v^(1<<i-1)将v中第i位置0
        即dp[k][v^(1<<(i-1)]表示未访问城市i的状态下,到达城市k的花费。
        时间复杂度:Floyd预处理为O(n^3),枚举各种状态的时间复杂度为O(2^n*n^2),总的时间复杂度即为O(2^n*n^2)
        """

        predecessors, dists = nx.floyd_warshall_predecessor_and_distance(
            truck.subgraph)
        n = len(truck.subgraph)
        mapping = np.zeros(n)

        for i, u in enumerate(truck.subgraph):
            mapping[i] = u
        dp = np.zeros((n, 1 << (n - 1)))
        path = dict()
        for i in range(1, n):
            u = int(mapping[i])
            dp[i, 0] = dists[u][0]
            path[u] = {0: u}
        path[0] = dict()

        for status in range(1 << (n - 1) - 1):
            for i in range(1, n):
                u = int(mapping[i])
                dist_opt = np.inf
                path_opt = []
                for v in truck.subgraph[u]:
                    if v != 0 and (1 << (v - 1)) | status == status:
                        dist = dp[v, status ^ (1 << (v - 1))] + dists[u][v]
                        if dist < dist_opt:
                            dist_opt = dist
                            path_opt = nx.reconstruct_path(
                                u, v,
                                predecessors).pop() + path[v][status
                                                              ^ (1 << (v - 1))]
                if not np.isinf(dist_opt):
                    dp[i, status] = dist_opt
                    path[u][status] = path_opt

        i = 0
        status = 1 << (n - 1) - 1
        u = int(mapping[i])
        dist_opt = np.inf
        path_opt = []
        for v in truck.subgraph[u]:
            if v != 0 and (1 << (v - 1)) | status == status:
                dist = dp[v, status ^ (1 << (v - 1))] + dists[u][v]
                if dist < dist_opt:
                    dist_opt = dist
                    path_opt = nx.reconstruct_path(
                        u, v, predecessors) + path[v][status ^ (1 << (v - 1))]
        if not np.isinf(dist_opt):
            dp[i, status] = dist_opt
            path[u][status] = path_opt
        else:
            raise nx.NetworkXError
        print(dp[i, 0])
        print(path[u][0])
Пример #19
0
    'B': (1.25, 1.75),
    'C': (2.5, 1),
    'D': (2, 0),
    'E': (.75, 0),
}

predecessores, distancias = nx.floyd_warshall_predecessor_and_distance(G)
predecessores_od = collections.OrderedDict(sorted(predecessores.items()))
distancias_od = collections.OrderedDict(sorted(distancias.items()))

resultados_np = nx.floyd_warshall_numpy(G)
print(resultados_np)

print('\nDistâncias:')
for chave, valor in distancias_od.items():
    od = collections.OrderedDict(sorted(valor.items()))
    print(f'Distâncias a partir de {chave}:', json.dumps(od))

print("\nCamihos:")
for source, valor in predecessores_od.items():
    valor_od = collections.OrderedDict(sorted(valor.items()))
    for target, caminho in valor_od.items():
        print(f'Caminhos a partir de {source} até {target}')

nx.reconstruct_path(source, target, predecessores_od)

print("")

rotulos = nx.get_edge_attributes(G, 'weight')
nx.draw(G, posicoes, with_labels=True, connectionstyle='arc3, rad=0.1')
nx.draw_networkx_edge_labels(G, posicoes, edge_labels=rotulos, label_pos=0.3)
Пример #20
0
continuar = True
while (continuar):
    print("""
		MENU
	1. Ruta mas corta
	2. Centro de grafo
	3. Modificar grafo
	4. Ver grafo
	5. Salir""")
    opcion = input("Que opcion desea?: ")

    if (opcion == "1"):
        ciudad = input("Cual es la ciudad de origen?: ")
        destino = input("Cual es la ciudad de destino?: ")
        predecessors, _ = nx.floyd_warshall_predecessor_and_distance(DG)
        print(nx.reconstruct_path(ciudad, destino, predecessors))

    elif (opcion == "2"):
        centro = nx.center(DG)
        print("El centro del grafo esta en:" + centro[0])

    elif (opcion == "3"):
        print("""
	1. Reportar trafico
	2. Crear nueva conexion""")
        option = input("Que desea hacer?: ")
        if (option == "1"):
            ciudad1 = input("Indique la ciudad de origen: ")
            ciudad2 = input("Indique la ciudad de destino: ")
            trafico = int(
                input("Simule con un numero que tanto trafico hay: "))
Пример #21
0
def floyd_warshall_explored(G, source, destination):
    predecessors, distance = nx.floyd_warshall_predecessor_and_distance(G)
    visited = {}
    for key in predecessors.keys():
        visited[key] = nx.reconstruct_path(source, key, predecessors)
    return " -> ".join(visited)
Пример #22
0
def floyd_warshall(G, source, destination):
    predecessors, distance = nx.floyd_warshall_predecessor_and_distance(G)
    return " -> ".join(nx.reconstruct_path(source, destination, predecessors))
Пример #23
0
def greedyAllPairs2(list_of_locations, list_of_homes, starting_car_location,
                    adjacency_matrix):
    #print(adjacency_matrix)
    G = nx.Graph(incoming_graph_data=adjacency_matrix, cutoff=1000)
    predecessors, distances = nx.floyd_warshall_predecessor_and_distance(G)
    homeIndices = []
    for h in list_of_homes:
        homeIndices.append(list_of_locations.index(h))
    homeSet = set(homeIndices)
    homeList = list_of_homes[:]

    def get_distance(a, b):
        return list(distances.items())[a][1][b]

    def find_closest_home_to_location(location, homeList=homeList):
        distance = float('inf')
        closest_home = homeList[0]
        for h in homeList:
            if h in list_of_locations:
                home_idx = list_of_locations.index(h)
            else:
                home_idx = h
            if location in list_of_locations:
                location_idx = list_of_locations.index(location)
            else:
                location_idx = location
            #new_dist = list(distances.items())[home_idx][1][location_idx]
            new_dist = get_distance(home_idx, location_idx)

            if new_dist < distance:
                distance = new_dist
                closest_home = h

        return closest_home, distance

    current = starting_car_location
    # print(list_of_locations)
    # print(list_of_homes)
    # print(starting_car_location)
    path = [list_of_locations.index(starting_car_location)]
    dropoff_mapping = {}
    length = len(homeSet) + 1
    i = 0
    closest, distance = find_closest_home_to_location(current)
    while i in range(length):
        dropped = False
        node = list_of_locations.index(current)
        homeNeighbors = set(homeSet.intersection(list(G.neighbors(node))))
        shlong = 0
        for node2 in list(G.neighbors(node)):
            for node3 in list(G.neighbors(node2)):
                if node3 != node and node3 in homeSet:
                    homeNeighbors.add(node2)
                    shlong += get_distance(node, node3)

        dong = 0
        curr = current

        dong_dropoffs = []
        homeNeighbors = [j for j in homeNeighbors if j in homeSet]
        n = 1
        homeNeighborsCopy = list(homeNeighbors)
        for _ in range(len(homeNeighbors)):

            closest, distance = find_closest_home_to_location(
                curr, homeNeighborsCopy)

            # curr_idx = list_of_locations.index(curr)
            # next_idx = list_of_locations.index(closest)

            homeNeighborsCopy.remove(closest)
            dong_dropoffs.append(closest)
            curr = closest

            dong += distance

        if shlong < dong:
            if node not in dropoff_mapping:
                dropoff_mapping[node] = []
            if node in homeSet:
                dong_dropoffs.append(node)
            for d in dong_dropoffs:
                dropoff_mapping[node].append(d)
            n = len(dong_dropoffs)
            dropped = True
            homeSet = set([j for j in homeSet if j not in dong_dropoffs])
            homeList = [
                j for j in homeList if list_of_locations.index(j) in homeSet
            ]

            #drop it like its hot

        # print(homeNeighbors)
    #    if len(homeNeighbors) >= 3 :
    #        dropped = True
    #        node = list_of_locations.index(current)
    #        homeNeighbors = [j for j in homeNeighbors if j in homeSet]
    #        if (node in homeSet):
    #            homeNeighbors = homeNeighbors + [node]
    #        dropoff_mapping[node]= homeNeighbors
    #        homeSet = set([j for j in homeSet if j not in homeNeighbors])
    #        homeList = [j for j in homeList if list_of_locations.index(j) in homeSet]
    #        n = len(homeNeighbors)
        if node in homeSet and not dropped:
            dropoff_mapping[node] = [node]
            homeSet.remove(node)
            homeList.remove(current)
        if len(homeList) != 0:
            closest, distance = find_closest_home_to_location(
                current, homeList)
            path_to_next = nx.reconstruct_path(
                node, list_of_locations.index(closest), predecessors)
            path.extend(path_to_next[1:])
            current = closest
        i = i + n
    start_idx = list_of_locations.index(starting_car_location)
    path_to_start = nx.reconstruct_path(list_of_locations.index(current),
                                        start_idx, predecessors)
    path.extend(path_to_start[1:])
    return path, dropoff_mapping
Пример #24
0
def solve(list_of_locations,
          list_of_homes,
          starting_car_location,
          adjacency_matrix,
          params=[]):
    """
    Write your algorithm here.
    Input:
        list_of_locations: A list of locations such that node i of the graph corresponds to name at index i of the list
        list_of_homes: A list of homes
        starting_car_location: The name of the starting location for the car
        adjacency_matrix: The adjacency matrix from the input file
    Output:
        A list of locations representing the car path
        A dictionary mapping drop-off location to a list of homes of TAs that got off at that particular location
        NOTE: both outputs should be in terms of indices not the names of the locations themselves
    """
    # pass
    home_list = convert_locations_to_indices(list_of_homes, list_of_locations)
    location_list = convert_locations_to_indices(list_of_locations,
                                                 list_of_locations)

    G, message = adjacency_matrix_to_graph(adjacency_matrix)

    #Dropoff mappings dictionary
    dropoff_mappings = {}
    #     for home in home_list:
    #         dropoff_mapping[home] = [home]

    # Create a minimum spanning_tree of G
    #T = nx.minimum_spanning_tree(G)

    #  Predecessors, distances of the minimum spanning tree
    predecessors, distances = nx.floyd_warshall_predecessor_and_distance(G)

    #list_of_edges = sorted(T.edges(data=False))
    starting_location = list_of_locations.index(starting_car_location)
    curr_location = starting_location
    car_path = [curr_location]
    visited_homes = []  ##aka car_path
    closest_home_path = []
    # visited_homes.append(curr_location)
    not_yet_visited_homes = home_list[:]

    while len(not_yet_visited_homes) != 0:
        closest_home, closest_home_path = find_closest_home_to_current_location(
            predecessors, distances, visited_homes, not_yet_visited_homes,
            curr_location)
        visited_homes.append(closest_home)
        not_yet_visited_homes.remove(closest_home)
        curr_location = closest_home
        car_path += closest_home_path

    # Return home
    path_home = nx.reconstruct_path(curr_location, starting_location,
                                    predecessors)
    car_path += path_home

    clean_path = []

    clean_path.append(car_path[0])

    for i in range(1, len(car_path)):
        if car_path[i] != clean_path[-1]:
            clean_path.append(car_path[i])

    car_path = clean_path[:]
    node_list = car_path[:]

    ## Optimization gadget
    palindromic_windows = []

    covered_indices = set()

    for center in range(len(car_path)):
        left_bound = center
        right_bound = center
        dist = 1
        while (center - dist >= 0) and (center + dist < len(car_path)) and (
                car_path[center - dist] == car_path[center + dist]):
            left_bound -= 1
            right_bound += 1
            dist += 1
        contained = True
        for i in range(left_bound, right_bound + 1):
            if i not in covered_indices:
                contained = False
        if not contained:
            palindromic_windows.append((left_bound, right_bound))
            for i in range(left_bound, right_bound + 1):
                covered_indices.add(i)

    clean_windows = []

    for window1 in palindromic_windows:
        contained = False
        for window2 in palindromic_windows:
            if window1 != window2:
                if (window1[0] >= window2[0]) and (window1[1] <= window2[1]):
                    contained = True
                    break
        if not contained:
            clean_windows.append(window1)

    clean_path = [car_path[clean_windows[0][0]]]

    home_set = set(home_list)

    for window in clean_windows:
        if clean_path[-1] != car_path[window[0]]:
            clean_path.append(car_path[window[0]])
        for i in range(window[0] + 1 + ((window[1] - window[0]) // 2),
                       window[1]):
            if car_path[i] in home_set:
                #print(i)
                dropoff_mappings[car_path[i]] = [
                    car_path[window[0] + ((window[1] - window[0]) // 2)]
                ]
                for j in range(window[1] - 1,
                               window[0] + 1 + ((window[1] - window[0]) // 2),
                               -1):
                    clean_path.append(car_path[j])
                for j in range(window[0] + 1 + ((window[1] - window[0]) // 2),
                               window[1]):
                    clean_path.append(car_path[j])
                clean_path.append(car_path[window[0]])
                break

    for home in clean_path:
        if home in home_list:
            if home in dropoff_mappings:
                dropoff_mappings[home].append(home)
                home_list.remove(home)
            else:
                dropoff_mappings[home] = [home]
                home_list.remove(home)

    node_list = clean_path

    return node_list, dropoff_mappings