예제 #1
0
def test(adj_mat, elapsed_time, i):
    G = ntx.Graph(adj_mat)
    ntx.draw_networkx(G, pos=ntx.kamada_kawai_layout(G), node_size=50, with_labels=True, font_size=4, width=0.5)
    plt.savefig("graph"+i+".png", dpi=1000, quality=95)
    plt.show()
    t0 = time.perf_counter()
    ntx.floyd_warshall(G)
    elapsed_time[0].append(time.perf_counter() - t0)
    t0 = time.perf_counter()
    ntx.johnson(G)
    elapsed_time[1].append(time.perf_counter() - t0)
    print("finished_test")
    return elapsed_time
예제 #2
0
 def test_negative_weights(self):
     G = nx.DiGraph()
     G.add_weighted_edges_from([('0', '3', 3), ('0', '1', -5),
                                ('0', '2', 2), ('1', '2', 4),
                                ('2', '3', 1)])
     paths = nx.johnson(G)
     assert_equal(
         paths, {
             '1': {
                 '1': ['1'],
                 '3': ['1', '2', '3'],
                 '2': ['1', '2']
             },
             '0': {
                 '1': ['0', '1'],
                 '0': ['0'],
                 '3': ['0', '1', '2', '3'],
                 '2': ['0', '1', '2']
             },
             '3': {
                 '3': ['3']
             },
             '2': {
                 '3': ['2', '3'],
                 '2': ['2']
             }
         })
     paths = nx.johnson(G, new_weight='new_weight')
     assert_equal(
         paths, {
             '1': {
                 '1': ['1'],
                 '3': ['1', '2', '3'],
                 '2': ['1', '2']
             },
             '0': {
                 '1': ['0', '1'],
                 '0': ['0'],
                 '3': ['0', '1', '2', '3'],
                 '2': ['0', '1', '2']
             },
             '3': {
                 '3': ['3']
             },
             '2': {
                 '3': ['2', '3'],
                 '2': ['2']
             }
         })
     for u, v, w in G.edges(data=True):
         assert_true('new_weight' in w)
예제 #3
0
 def test_negative_weights(self):
     G = nx.DiGraph()
     G.add_weighted_edges_from([("0", "3", 3), ("0", "1", -5),
                                ("0", "2", 2), ("1", "2", 4),
                                ("2", "3", 1)])
     paths = nx.johnson(G)
     assert paths == {
         "1": {
             "1": ["1"],
             "3": ["1", "2", "3"],
             "2": ["1", "2"]
         },
         "0": {
             "1": ["0", "1"],
             "0": ["0"],
             "3": ["0", "1", "2", "3"],
             "2": ["0", "1", "2"],
         },
         "3": {
             "3": ["3"]
         },
         "2": {
             "3": ["2", "3"],
             "2": ["2"]
         },
     }
예제 #4
0
def shortest_paths(networkx_network):
    """
    finds the all pairs shortest paths using Johnson Algo
    sets a dictionary, keyed by source and target, of all pairs shortest paths with path_delays in the network as an
    attr.
    key: (src, dest) , value: ([nodes_on_the_shortest_path], path_delay)
    path delays are the sum of individual edge_delays of the edges in the shortest path from source to destination
    """
    # in-built implementation of Johnson Algo, just returns a list of shortest paths
    # returns a dict with : key: source, value: dict with key: dest and value: shortest path as list of nodes
    all_pair_shortest_paths = dict(
        nx.johnson(networkx_network, weight='weight'))
    # contains shortest paths with path_delays
    # key: (src, dest) , value: ([nodes_on_the_shortest_path], path_delay)
    shortest_paths_with_delays = {}
    for source, v in all_pair_shortest_paths.items():
        for destination, shortest_path_list in v.items():
            path_delay = 0
            # only if the source and destination are different, path_delays need to be calculated, otherwise 0
            if source != destination:
                # shortest_path_list only contains ordered nodes [node1,node2,node3....] in the shortest path
                # here we take ordered pair of nodes (src, dest) to cal. the path_delay of the edge between them
                for i in range(len(shortest_path_list) - 1):
                    path_delay += networkx_network[shortest_path_list[i]][
                        shortest_path_list[i + 1]]['delay']
            shortest_paths_with_delays[(source,
                                        destination)] = (shortest_path_list,
                                                         path_delay)
    networkx_network.graph['shortest_paths'] = shortest_paths_with_delays
예제 #5
0
 def test_negative_weights(self):
     G = nx.DiGraph()
     G.add_weighted_edges_from([('0', '3', 3), ('0', '1', -5),
                                ('0', '2', 2), ('1', '2', 4),
                                ('2', '3', 1)])
     paths = nx.johnson(G)
     assert_equal(
         paths, {
             '1': {
                 '1': ['1'],
                 '3': ['1', '2', '3'],
                 '2': ['1', '2']
             },
             '0': {
                 '1': ['0', '1'],
                 '0': ['0'],
                 '3': ['0', '1', '2', '3'],
                 '2': ['0', '1', '2']
             },
             '3': {
                 '3': ['3']
             },
             '2': {
                 '3': ['2', '3'],
                 '2': ['2']
             }
         })
예제 #6
0
def constraint_correct(G, C, P, w0):
    path = nx.johnson(
        G, weight='weight')  # or nx.all_pairs_dijkstra_path_length(G)
    C_max_dist = 0
    for i in range(1, len(P) + 1):
        if (i in C): continue
        else:
            min_dist = 1000 * 1000
            min_idx = 0
            for j in C:
                cur_dist = 0
                for k in range(len(path[i][j]) - 1):
                    cur_dist += G[path[i][j][k]][path[i][j][k + 1]]['weight']
                if (cur_dist < min_dist):
                    min_dist = cur_dist
                    min_idx = j
            if (C_max_dist < min_dist):
                C_max_dist = min_dist
                C_max_v = (i, min_idx)

    max_path = path[C_max_v[0]][C_max_v[1]]
    max_edges = []
    for i in range(len(max_path) - 1):
        max_edges.append([max_path[i], max_path[i + 1]])

    if C_max_dist > w0:
        return False, max_edges
    else:
        return True, max_edges
예제 #7
0
    def get_makespan(self):
        import networkx as nx
        G = nx.DiGraph()
        edg = tuple(set(unfold(self.A)) | set(unfold(self.E)))
        edg_weighted = [(x[0], x[1], -self.getD(x[0])) for x in edg]
        G.add_weighted_edges_from(edg_weighted)

        s = nx.johnson(G, weight='weight')[-1][self.N - 2]
        return sum([self.getD(x) for x in s])
예제 #8
0
 def test_negative_weights(self):
     G = nx.DiGraph()
     G.add_weighted_edges_from([('0', '3', 3), ('0', '1', -5),
                                  ('0', '2', 2), ('1', '2', 4),
                                  ('2', '3', 1)])
     paths = nx.johnson(G)
     assert_equal(paths, {'1': {'1': ['1'], '3': ['1', '2', '3'],
                          '2': ['1', '2']}, '0': {'1': ['0', '1'],
                          '0': ['0'], '3': ['0', '1', '2', '3'],
                          '2': ['0', '1', '2']}, '3': {'3': ['3']},
                          '2': {'3': ['2', '3'], '2': ['2']}})
     paths = nx.johnson(G, new_weight='new_weight')
     assert_equal(paths, {'1': {'1': ['1'], '3': ['1', '2', '3'],
                          '2': ['1', '2']}, '0': {'1': ['0', '1'],
                          '0': ['0'], '3': ['0', '1', '2', '3'],
                          '2': ['0', '1', '2']}, '3': {'3': ['3']},
                          '2': {'3': ['2', '3'], '2': ['2']}})
     for u, v, w in G.edges(data=True):
         assert_true('new_weight' in w)
예제 #9
0
 def test_negative_weights(self):
     G = nx.DiGraph()
     G.add_weighted_edges_from([('0', '3', 3), ('0', '1', -5),
                                ('0', '2', 2), ('1', '2', 4),
                                ('2', '3', 1)])
     paths = nx.johnson(G)
     assert_equal(paths, {'1': {'1': ['1'], '3': ['1', '2', '3'],
                                '2': ['1', '2']}, '0': {'1': ['0', '1'],
                                                        '0': ['0'], '3': ['0', '1', '2', '3'],
                                                        '2': ['0', '1', '2']}, '3': {'3': ['3']},
                          '2': {'3': ['2', '3'], '2': ['2']}})
예제 #10
0
 def test_graphs(self):
     validate_path(self.XG, 's', 'v', 9, nx.johnson(self.XG)['s']['v'])
     validate_path(self.MXG, 's', 'v', 9, nx.johnson(self.MXG)['s']['v'])
     validate_path(self.XG2, 1, 3, 4, nx.johnson(self.XG2)[1][3])
     validate_path(self.XG3, 0, 3, 15, nx.johnson(self.XG3)[0][3])
     validate_path(self.XG4, 0, 2, 4, nx.johnson(self.XG4)[0][2])
     validate_path(self.MXG4, 0, 2, 4, nx.johnson(self.MXG4)[0][2])
예제 #11
0
 def test_graphs(self):
     validate_path(self.XG, 's', 'v', 9, nx.johnson(self.XG)['s']['v'])
     validate_path(self.MXG, 's', 'v', 9, nx.johnson(self.MXG)['s']['v'])
     validate_path(self.XG2, 1, 3, 4, nx.johnson(self.XG2)[1][3])
     validate_path(self.XG3, 0, 3, 15, nx.johnson(self.XG3)[0][3])
     validate_path(self.XG4, 0, 2, 4, nx.johnson(self.XG4)[0][2])
     validate_path(self.MXG4, 0, 2, 4, nx.johnson(self.MXG4)[0][2])
예제 #12
0
 def test_graphs(self):
     validate_path(self.XG, "s", "v", 9, nx.johnson(self.XG)["s"]["v"])
     validate_path(self.MXG, "s", "v", 9, nx.johnson(self.MXG)["s"]["v"])
     validate_path(self.XG2, 1, 3, 4, nx.johnson(self.XG2)[1][3])
     validate_path(self.XG3, 0, 3, 15, nx.johnson(self.XG3)[0][3])
     validate_path(self.XG4, 0, 2, 4, nx.johnson(self.XG4)[0][2])
     validate_path(self.MXG4, 0, 2, 4, nx.johnson(self.MXG4)[0][2])
예제 #13
0
 def test_unweighted_graph(self):
     with pytest.raises(nx.NetworkXError):
         G = nx.path_graph(5)
         nx.johnson(G)
예제 #14
0
 def test_single_node_graph(self):
     with pytest.raises(nx.NetworkXError):
         G = nx.DiGraph()
         G.add_node(0)
         nx.johnson(G)
예제 #15
0
def fast_price_function(g, e, proportional, algorithm='johnson'):
    """

	Fast function to find the optimal price for a given edge e.

	1. Calculate the shortest path from all-to-all vertices without going through $C$ with either Floyd-Warshall or
		Johnson. Default is Johnson
	2. Calculate shortest path from $C$ source to all explicitly going through $C$ with Dijkstra.
	3. Compare difference between all-to-all cost with all-to-$V$-to-all, producing a cumulative summation over the
		difference.
	4. Maximizing fee * cumulative difference.

	Plots the given fee * cumulative difference over fee curve.
	"""

    e_data = g.get_edge_data(e[0][0], e[0][1])

    # Remove edge e
    g.remove_edge(e[0][0], e[0][1])

    # Floyd or Johnson
    if algorithm == 'johnson':
        all_pair_shortest_path = nx.floyd_warshall(g, weight="price")
    else:
        all_pair_shortest_path = nx.johnson(g, weight="price")

    # remove all edges from e source, Add edge e
    edges = list(g.out_edges(e[0][0]))  # get all edges of source
    edges_data = []

    for rm in edges:
        edges_data.append(g.get_edge_data(rm[0], rm[1]))
        g.remove_edge(rm[0], rm[1])

    temp_price = e_data["price"]
    e_data["price"] = proportional
    g.add_edge(e[0][0], e[0][1], **e_data)

    # Compute single source dijkstras from e source over e.
    edge_to_all = nx.single_source_dijkstra_path_length(g,
                                                        e[0][0],
                                                        weight="price")

    path_price_difference = []
    for source in all_pair_shortest_path:
        for destination in all_pair_shortest_path[source]:
            # SOURCE TO V TO DESTINATION
            if source != destination != e[0][0]:
                #print("-----")
                #print(source)
                #print(destination)
                #print(all_pair_shortest_path[source][destination])
                diff = (all_pair_shortest_path[source][e[0][0]] +
                        edge_to_all[destination]
                        ) - all_pair_shortest_path[source][destination]
                if diff < 0:  # TODO: WHAT TO DO WITH TIES?
                    path_price_difference.append(-diff)

    fee_range = range(10, 1350, 10)
    plot_list = []

    e_data["price"] = temp_price
    for i, add in enumerate(edges):
        g.add_edge(add[0], add[1], **edges_data[i])

    for r in fee_range:
        plot_list.append(
            len([p for p in path_price_difference if p >= r]) * r *
            proportional / 1000)
    #plot.plot_fee_curve(fee_range, plot_list)

    return plot_list
예제 #16
0
 def test_unweighted_graph(self):
     G = nx.path_graph(5)
     nx.johnson(G)
예제 #17
0
def johnson(G, source, destination):
    return " -> ".join(nx.johnson(G)[source][destination])
예제 #18
0
 def test_unweighted_graph(self):
     G = nx.path_graph(5)
     nx.johnson(G)
예제 #19
0
    def optimize(self):

        start_time = time.time()

        try:
            for s_idx, s_session in enumerate(self.sessions):
                session_start_time = time.time()
                tree = self._solution.get_tree(s_session)
                print "curr", s_idx
                ####################################################################################
                #
                # Algorithm 1 The construction of multilevel overlay directed network
                #
                ####################################################################################

                copy_graph = self.graph.copy()

                # Remove edge with insufficient residual capacity
                for link_id in set(self.app.links.items()) & set(
                        copy_graph.edges()):
                    if self.links[link_id].cap - (
                            self.links[link_id].used_cap +
                            self.sessions[s_idx].bw) < 0:
                        copy_graph.remove_edge(link_id[0], link_id[1])

                # Calculate all shortest paths between each pair nodes in G
                apsp_length = dict(
                    nx.all_pairs_dijkstra_path_length(copy_graph,
                                                      weight='BandwidthCost'))
                apsp_path = nx.johnson(copy_graph, weight='BandwidthCost')

                # check if dst is reachable
                # Remove session which cannot reach to every destination
                try:
                    if set(self.sessions[s_idx].dsts) - set(
                            apsp_path[self.sessions[s_idx].src]):
                        raise ResourceOverloaded
                except ResourceOverloaded:
                    print "ResourceOverloaded!!!!!!!!!!!!!!"
                    continue

                # Replicate all |V|=n nodes k times and place n*k nodes in a n x k grid, Each node can be denoted by v_n_k
                # Connect all nodes in i-th column to all nodes in i+1-th column with directed arrows
                # Set the edge cost between two nodes as the corresponding shortest path cost in G
                multilevel_graph = nx.DiGraph()
                for i, service in enumerate(self.service_chains[s_idx][:-1]):
                    for head in self.service_nodes[service]:
                        for tail in self.service_nodes[
                                self.service_chains[s_idx][i + 1]]:
                            cost = apsp_length[head][tail]
                            multilevel_graph.add_edge(
                                str(service) + "_" + str(head),
                                str(self.service_chains[s_idx][i + 1]) + "_" +
                                str(tail),
                                weight=cost)

                ####################################################################################
                #
                # Algorithm 2 The Modified Shortest-Path Algorithm (MSA)
                #
                ####################################################################################

                if len(self.service_chains[s_idx]) == 0:
                    st = steiner_tree(copy_graph, [self.sessions[s_idx].src] +
                                      list(self.sessions[s_idx].dsts),
                                      weight='BandwidthCost')
                    # Convert steiner_tree into directed graph
                    s_tree = nx.DiGraph()

                    for dst in self.sessions[s_idx].dsts:
                        s_tree.add_edge(dst, "sink", weight=0)
                    for h, t in st:
                        s_tree.add_edge(
                            t,
                            h,
                            weight=copy_graph[t][h]['BandwidthCost'] *
                            self.sessions[s_idx].bw)

                    st_edges = set()
                    for path in nx.all_simple_paths(
                            s_tree.to_undirected(),
                            source=self.sessions[s_idx].src,
                            target="sink"):
                        for idx in range(len(path) - 2):
                            st_edges.add((path[idx], path[idx + 1]))
                        self._solution.add_path(self.sessions[s_idx],
                                                path[:-1], None)

                    memo = defaultdict(float)
                    # Update link usage
                    try:
                        for h, t in st_edges:
                            self.links[(h, t)].used_cap += self.sessions[
                                s_idx].bw * self.links[(h, t)].bw_cost
                            memo[(h,
                                  t)] += self.sessions[s_idx].bw * self.links[
                                      (h, t)].bw_cost
                            self.total_routing_cost += self.sessions[
                                s_idx].bw * self.links[(h, t)].bw_cost
                            if self.links[(h, t)].used_cap > self.links[(
                                    h, t)].cap:
                                raise ResourceOverloaded
                    except ResourceOverloaded:
                        print "ResourceOverloaded!!!!!!!!!!!!!!"
                        for link_id, v in memo.items():
                            self.links[link_id].used_cap -= v
                        continue

                    curr_time = time.time() - session_start_time
                    self.update_session_cost(solution=self._solution,
                                             session=self.sessions[s_idx],
                                             links=st_edges,
                                             time=curr_time)

                    self.solution_tree[s_idx] = s_tree

                    self.session_completed += 1
                    continue

                # Divide each nodes in G' into two parts, and connect theses two parts with cost y_l_k_u
                for service in self.service_chains[s_idx]:
                    for node in self.service_nodes[service]:
                        fst_half, snd_half = str(service) + "_" + str(
                            node), '_' + str(service) + "_" + str(node)
                        for h, t in list(multilevel_graph.out_edges(fst_half)):
                            multilevel_graph.add_edge(
                                snd_half,
                                t,
                                weight=multilevel_graph[h][t]['weight'])
                            multilevel_graph.remove_edge(h, t)
                        multilevel_graph.add_edge(
                            fst_half,
                            snd_half,
                            weight=self.sessions[s_idx].res[service]['cpu'])

                # Add the source node S into G'
                # Connect S to all nodes of the first column in G' and set the cost as corresponding shortest path
                first_service = self.service_chains[s_idx][0]
                for tail in self.service_nodes[first_service]:
                    multilevel_graph.add_edge(
                        self.sessions[s_idx].src,
                        str(first_service) + "_" + str(tail),
                        weight=apsp_length[self.sessions[s_idx].src][tail])

                feasible_solution = (float('inf'), [], [])
                last_service = self.service_chains[s_idx][-1]
                for v in self.service_nodes[last_service]:
                    if self.nodes[v].services[last_service].resources_cap['cpu'] - \
                            (self.nodes[v].services[last_service].used_cap['cpu'] +
                                self.sessions[s_idx].res[last_service]['cpu']) < 0:
                        continue

                    # Find the shortest path y from S to v in G' and get [w_l_n_u]
                    last_node_v = "_" + str(last_service) + "_" + str(v)

                    # Build a Steiner tree to cover v and all destinations
                    st = steiner_tree(copy_graph,
                                      [v] + list(self.sessions[s_idx].dsts),
                                      weight='BandwidthCost')
                    # Convert steiner_tree into directed graph
                    s_tree = nx.DiGraph()
                    s_tree_path = set()
                    for dst in self.sessions[s_idx].dsts:
                        s_tree.add_edge(dst, "sink", weight=0)
                    for h, t in st:

                        s_tree.add_edge(
                            h,
                            t,
                            weight=copy_graph[h][t]['BandwidthCost'] *
                            self.sessions[s_idx].bw)
                        s_tree.add_edge(
                            t,
                            h,
                            weight=copy_graph[t][h]['BandwidthCost'] *
                            self.sessions[s_idx].bw)
                    for path in nx.all_simple_paths(s_tree,
                                                    source=v,
                                                    target="sink"):
                        for i, n in enumerate(path[:-2]):
                            s_tree_path.add((n, path[i + 1]))

                    # steiner_tree cost
                    accum_cost = 0
                    for h, t in s_tree_path:
                        accum_cost += copy_graph[h][t][
                            'BandwidthCost'] * self.sessions[s_idx].bw

                    shortest_path = nx.dijkstra_path(multilevel_graph,
                                                     self.sessions[s_idx].src,
                                                     last_node_v,
                                                     weight='weight')[1:]
                    candidate_solution = [self.sessions[s_idx].src]
                    for i, service in enumerate(
                            self.service_chains[s_idx][:-1]):
                        # Check where l_j is deployed in an overloaded node, if so,
                        # find a new node with the minimum sum of setup cost and connection cost to deploy l_j
                        node = int(shortest_path[i * 2][len(str(service)) +
                                                        1:])
                        if self.nodes[node].services[service].resources_cap['cpu'] - \
                                (self.nodes[node].services[service].used_cap['cpu'] +
                                    self.sessions[s_idx].res[service]['cpu']) < 0:

                            other_nodes_cost = []
                            for other_node in set(
                                    self.service_nodes[service]) - {node}:
                                if self.nodes[other_node].services[service].resources_cap['cpu'] - \
                                        (self.nodes[other_node].services[service].used_cap['cpu'] +
                                            self.sessions[s_idx].res[service]['cpu']) < 0:
                                    continue

                                prev_service = "_" + self.service_chains[s_idx][i - 1] + "_" + str(candidate_solution[-1]) \
                                    if i != 0 else candidate_solution[-1]
                                next_service = self.service_chains[s_idx][
                                    i + 1] + "_" + shortest_path[
                                        (i + 1) * 2][len(str(service)) + 1:]
                                vk = multilevel_graph[prev_service][
                                    str(service) + "_" +
                                    str(other_node)]['weight']
                                vm = multilevel_graph[
                                    "_" + str(service) + "_" +
                                    str(other_node)][next_service]['weight']

                                other_nodes_cost.append(
                                    (self.sessions[s_idx].res[service]['cpu'] +
                                     vk + vm, other_node))

                            if not other_nodes_cost:
                                # print ">>>>>Cannot find solution!solution!!!!"
                                break

                            _, best_candidate = max(other_nodes_cost)
                            candidate_solution.append(best_candidate)

                        else:
                            candidate_solution.append(node)
                    candidate_solution.append(v)  # add last node

                    # Cannot find solution with v!!!!!
                    if len(candidate_solution) < 1 + len(
                            self.service_chains[s_idx]):
                        continue

                    # source to last VNF cost
                    for i, node in enumerate(candidate_solution[:-1]):
                        accum_cost += apsp_length[node][candidate_solution[i +
                                                                           1]]

                    if accum_cost < feasible_solution[0]:
                        feasible_solution = (accum_cost, candidate_solution,
                                             s_tree_path)

                # Cannot find solution!!!!!
                try:
                    if len(feasible_solution[1]) < 1 + len(
                            self.service_chains[s_idx]):
                        raise ResourceOverloaded
                except ResourceOverloaded:
                    print "ResourceOverloaded!!!!!!!!!!!!!!"
                    continue

                traversed_edges = defaultdict(int)
                # Build tree from feasible solution
                feasible_solution_tree = nx.DiGraph()
                for node_id, node in enumerate(feasible_solution[1][:-1]):
                    path = nx.shortest_path(
                        copy_graph,
                        source=node,
                        target=feasible_solution[1][node_id + 1],
                        weight='BandwidthCost')
                    for i, h in enumerate(path[:-1]):
                        traversed_edges[(h, path[i + 1])] += 1

                        feasible_solution_tree.add_edge(
                            h,
                            path[i + 1],
                            weight=copy_graph[h][path[i + 1]]['BandwidthCost']
                            * self.sessions[s_idx].bw)
                for h, t in feasible_solution[2]:
                    traversed_edges[(h, t)] += 1
                    feasible_solution_tree.add_edge(
                        h,
                        t,
                        weight=copy_graph[h][t]['BandwidthCost'] *
                        self.sessions[s_idx].bw)

                ####################################################################################
                #
                # Algorithm 3 The Optimize Phase Algorithm (OPA)
                #
                ####################################################################################

                _, candidate_solution, s_tree_path = feasible_solution

                # print "self.sessions[s_idx]", self.sessions[s_idx]

                curr_service_node = []
                for s_id, service_node in enumerate(candidate_solution[1:]):
                    curr_service_node.append(
                        (self.service_chains[s_idx][s_id], service_node))

                # Find all connection nodes in X_0
                connection_nodes = set(self.sessions[s_idx].dsts)
                for dst in self.sessions[s_idx].dsts:
                    connection_nodes -= set(
                        nx.descendants(feasible_solution_tree, dst))

                for j, service in reversed(
                        list(enumerate(self.service_chains[s_idx]))):
                    for connection_node in list(connection_nodes):
                        connection_nodes.remove(connection_node)
                        for other_node in set(self.service_nodes[service]) - {
                                connection_node
                        }:
                            # if l_j can be deployed in other nodes according to the rule in Section IV-C then
                            if self.nodes[other_node].services[service].resources_cap['cpu'] - \
                                    (self.nodes[other_node].services[service].used_cap['cpu'] +
                                        self.sessions[s_idx].res[service]['cpu']) < 0:
                                continue

                            old_cost = apsp_length[candidate_solution[
                                j + 1]][connection_node]
                            new_cost = apsp_length[candidate_solution[j]][other_node] + \
                                    apsp_length[other_node][connection_node] + 0

                            if new_cost < old_cost:
                                curr_service_node.append((service, other_node))
                                # Old link from VNF to connection node
                                old_path = apsp_path[candidate_solution[
                                    j + 1]][connection_node]
                                for i, t in reversed(
                                        list(enumerate(old_path[1:]))):
                                    if feasible_solution_tree.has_edge(
                                            old_path[i], t
                                    ) and feasible_solution_tree.edges(
                                            old_path[i]
                                    ) <= 1 and feasible_solution_tree.edges(
                                            t) <= 1:
                                        feasible_solution_tree.remove_edge(
                                            old_path[i], t)
                                        traversed_edges[(old_path[i], t)] -= 1
                                    if feasible_solution_tree.has_node(
                                            old_path[i]) and len(
                                                feasible_solution_tree.edges(
                                                    old_path[i])) > 1:
                                        break

                                # New link from new VNF to connection node
                                new_path = apsp_path[other_node][
                                    connection_node]
                                for i, h in enumerate(new_path[:-1]):
                                    try:
                                        feasible_solution_tree.add_edge(
                                            h,
                                            new_path[i + 1],
                                            weight=copy_graph[h][new_path[
                                                i + 1]]['BandwidthCost'] *
                                            self.sessions[s_idx].bw)
                                    except:
                                        print "i, h", i, h
                                        for hh, tt in copy_graph.edges():
                                            print hh, tt
                                    traversed_edges[(h, new_path[i + 1])] += 1

                                # New link from previous VNF to new VNF
                                new_path = apsp_path[
                                    candidate_solution[j]][other_node]
                                for i, h in enumerate(new_path[:-1]):
                                    feasible_solution_tree.add_edge(
                                        h,
                                        new_path[i + 1],
                                        weight=copy_graph[h][new_path[
                                            i + 1]]['BandwidthCost'] *
                                        self.sessions[s_idx].bw)
                                    traversed_edges[(h, new_path[i + 1])] += 1

                                connection_nodes.add(other_node)
                                break

                # Add link from source to connection nodes
                for connection_node in connection_nodes:
                    new_path = apsp_path[
                        self.sessions[s_idx].src][connection_node]
                    for i, h in enumerate(new_path[:-1]):
                        feasible_solution_tree.add_edge(
                            h,
                            new_path[i + 1],
                            weight=copy_graph[h][new_path[i +
                                                          1]]['BandwidthCost']
                            * self.sessions[s_idx].bw)
                        traversed_edges[(h, new_path[i + 1])] += 1

                print "self.sessions[s_idx]", self.sessions[s_idx].addr

                memo = defaultdict(float)
                try:
                    # Update service used_cap
                    for service, node in curr_service_node:
                        print "service, node", service, node
                        self.nodes[node].services[service].used_cap[
                            'cpu'] += self.sessions[s_idx].res[service]['cpu']
                        memo[service] += self.sessions[s_idx].res[service][
                            'cpu']
                        if self.nodes[node].services[service].used_cap[
                                'cpu'] > self.nodes[node].services[
                                    service].resources_cap['cpu']:
                            raise ResourceOverloaded
                except ResourceOverloaded:
                    print "ResourceOverloaded!!!!!!!!!!!!!!"
                    for service, v in memo.items():
                        node = curr_service_node[service]
                        self.nodes[node].services[service].used_cap['cpu'] -= v
                    continue

                memo = defaultdict(float)
                # Update link usage
                try:
                    print traversed_edges.items()
                    curr_cost = 0
                    sess_links = []
                    for l, count_link in traversed_edges.items():
                        for _ in range(count_link):
                            h, t = l
                            print h, t
                            sess_links.append((h, t))
                            self.links[(h, t)].used_cap += self.sessions[
                                s_idx].bw * self.links[(h, t)].bw_cost
                            memo[(h,
                                  t)] += self.sessions[s_idx].bw * self.links[
                                      (h, t)].bw_cost
                            if self.links[(h, t)].used_cap > self.links[(
                                    h, t)].cap:
                                raise ResourceOverloaded
                            curr_cost += self.sessions[s_idx].bw * self.links[
                                (h, t)].bw_cost
                            self.total_routing_cost += self.sessions[
                                s_idx].bw * self.links[(h, t)].bw_cost
                    print self.sessions[s_idx].addr, "curr_cost", curr_cost
                except ResourceOverloaded:
                    print "ResourceOverloaded!!!!!!!!!!!!!!"
                    for link_id, v in memo.items():
                        self.links[link_id].used_cap -= v
                    continue

                # # Update the flow tcam
                # for node, num_traverse in traversed_edges.items():
                #     h, t = node
                #     self.nodes[h].services['sdn_router'].used_cap['tcam'] = self.sessions[s_idx].res[service]['tcam'] * num_traverse
                #     self.nodes[t].services['sdn_router'].used_cap['tcam'] = self.sessions[s_idx].res[service]['tcam'] * num_traverse

                # num_undirected_traversed_edges = defaultdict(int)
                # for h, t in traversed_edges.keys():
                #     # h, t = key
                #     if (h, t) in num_undirected_traversed_edges or (t, h) in num_undirected_traversed_edges:
                #         continue
                #     num_undirected_traversed_edges[(h, t)] = traversed_edges[(h, t)] + traversed_edges[(t, h)]

                curr_time = time.time() - session_start_time
                self.update_session_cost(solution=self._solution,
                                         session=self.sessions[s_idx],
                                         links=sess_links,
                                         time=curr_time)

                self.session_completed += 1

        except Exception as e:
            raise e

        finally:
            print 'All DONE:', str(self.session_completed / len(self.sessions))
            total_time = time.time() - start_time
            print "Optimization time       = ", str(total_time), " sec"
            self._solution.total_time = total_time
            return self._solution
예제 #20
0
def compute_all_pair_shortest_path(graphs_single_robot, trees_single_robot):
    all_pairs_shortest_paths_per_robot = []
    all_pairs_shortest_paths_per_robot_b = [
        dict() for i in range(len(graphs_single_robot))
    ]
    subgraph_nodes = [0] * len(graphs_single_robot)
    for i in range(len(graphs_single_robot)):
        all_pairs_shortest_paths_per_robot.append( \
            nx.johnson(graphs_single_robot[i], weight='weight'))
        subgraph_nodes[i] = random.sample(
            graphs_single_robot[i].nodes,
            math.ceil(len(graphs_single_robot[i].nodes) / 10))
        if len(
                subgraph_nodes[i]
        ) == 1:  # single_source_bellman_ford gets stuck on single node graph, so this is an edge case
            all_pairs_shortest_paths_per_robot_b[i][subgraph_nodes[i]
                                                    [0]] = dict()
            all_pairs_shortest_paths_per_robot_b[i][subgraph_nodes[i][0]][
                subgraph_nodes[i][0]] = [subgraph_nodes[i][0]]
        else:
            for j in range(len(subgraph_nodes[i])):
                all_pairs_shortest_paths_per_robot_b[i][
                    subgraph_nodes[i][j]] = nx.single_source_bellman_ford(
                        graphs_single_robot[i],
                        subgraph_nodes[i][j],
                        target=None,
                        weight='weight')[1]
        while len(all_pairs_shortest_paths_per_robot_b[i]) < len(
                graphs_single_robot[i].nodes):
            for node in list(all_pairs_shortest_paths_per_robot_b[i].keys()):
                N = drrt_ao.adj(graphs_single_robot[i], node)
                for neighbor in N:
                    if neighbor in all_pairs_shortest_paths_per_robot_b[i]:
                        continue
                    else:
                        all_pairs_shortest_paths_per_robot_b[i][
                            neighbor] = dict()
                        for key in all_pairs_shortest_paths_per_robot_b[i][
                                node].keys():
                            all_pairs_shortest_paths_per_robot_b[
                                i][neighbor][key] = list(
                                    all_pairs_shortest_paths_per_robot_b[i]
                                    [node][key]
                                )  # attaching copy of the list of the neighbor
                            all_pairs_shortest_paths_per_robot_b[i][neighbor][
                                key].insert(0, neighbor)
                            if key == neighbor:
                                all_pairs_shortest_paths_per_robot_b[i][neighbor][
                                    key] = all_pairs_shortest_paths_per_robot_b[
                                        i][neighbor][key][:1]
    for i in range(
            len(graphs_single_robot)
    ):  # A check to see the johnson and bellman ford dictionaries are equal
        for key in all_pairs_shortest_paths_per_robot[i].keys():
            if key not in all_pairs_shortest_paths_per_robot_b[i]:
                print("check out")
            else:
                for inkey in all_pairs_shortest_paths_per_robot[i][key].keys():
                    if inkey not in all_pairs_shortest_paths_per_robot_b[i][
                            key]:
                        print("check in")
    return all_pairs_shortest_paths_per_robot_b
예제 #21
0
    G.add_edge(t[0] + 1, t[1] + 1, weight=euclidean(t[0], t[1]))
    G.add_edge(t[1] + 1, t[2] + 1, weight=euclidean(t[1], t[2]))
    G.add_edge(t[0] + 1, t[2] + 1, weight=euclidean(t[0], t[2]))

# Cycle check
for i in range(len(C) - 1):
    e = [C[i], C[i + 1]]
    if (e in G.edges()):  # cycle edge on DG
        CE_IN.append(e)
    else:
        CE_OUT.append(e)
    C_length += euclidean(C[i] - 1, C[i + 1] - 1)
if (len(CE_OUT) > 0): C_valid = 0

# Calculate ditance between vertices and cycle
path = nx.johnson(G,
                  weight='weight')  # or nx.all_pairs_dijkstra_path_length(G)
print("1. All Shortest Path (v-->cycle)")
print("vertex -- cycle_vertex ==> distance [path]")
for i in range(1, len(P) + 1):
    if (i in C): continue
    else:
        min_dist = 1000 * 1000
        min_idx = 0
        for j in C:
            cur_dist = 0
            for k in range(len(path[i][j]) - 1):
                cur_dist += G[path[i][j][k]][path[i][j][k + 1]]['weight']
            if cur_dist < min_dist:
                min_dist = cur_dist
                min_idx = j
        print("   ", i, "--", min_idx, "==>", round(min_dist, 3),
예제 #22
0
def all_pairs_paths(G):
    print "Computing all pairs paths..."
    paths = nx.johnson(G, weight="weight")
    return paths
예제 #23
0
def johnson_explored(G, source, destination):
    return " -> ".join(nx.johnson(G)[source])
예제 #24
0
 def test_single_node_graph(self):
     G = nx.DiGraph()
     G.add_node(0)
     nx.johnson(G)
예제 #25
0
 def test_single_node_graph(self):
     G = nx.DiGraph()
     G.add_node(0)
     nx.johnson(G)
예제 #26
0
        if eg[0] in cost_dict:
            if eg[1] in cost_dict[eg[0]]:
                eg[2]['negative_weight'] = -1 * eg[2]['weight']

    idcs = np.random.choice(len(gp.nodes()), int(5 * 5 * 0.2), replace=False)
    # print idcs

    # スタート・ゴール・障害物を設定する
    st, gl, obs = (0, 0), (30, 60), [list(gp.nodes())[i] for i in idcs[2:]]
    # st, gl, obs = (0,0), (np.random.randint(g_dim[0]),np.random.randint(g_dim[1])), [list(gp.nodes())[i] for i in idcs[2:]]
    obs = [list(gp.nodes())[i] for i in idcs[2:]]

    path = nx.astar_path(gp, st, gl, cost)
    length = nx.astar_path_length(gp, st, gl, cost)

    path2 = nx.johnson(gp, weight='negative_weight')
    print('johnson: {0}'.format(path2[st][gl]))

    for p in path2[st][gl]:
        if gp.node[p].get('color', '') == 'black':
            print('Invalid path')
            continue
        gp.node[p]['color'] = 'orange'

    previous_nd = st
    longest_length = 0
    for nd in path2[st][gl][:]:
        if not (previous_nd == st and nd == st):
            # longest_length += cost_dict[previous_nd][nd]
            longest_length += gp[previous_nd][nd]['weight']
            # print ('{0}-[{1}]→{2}'.format(previous_nd,cost_dict[previous_nd][nd],nd))
예제 #27
0
    def optimize(self):

        start_time = time.time()

        ############################
        # Multi-Tree Routing Phase
        ############################

        copy_graph = self.graph.copy()

        # Sort the multicast tress according to their data rates in ascending order
        self.sessions = sorted(self.app.get_sessions(),
                               key=lambda session: session.bw)

        for s_idx, s_session in enumerate(self.sessions):
            for link_id in set(self.app.links.items()) & set(
                    copy_graph.edges()):
                if self.links[link_id].cap - (self.links[link_id].used_cap +
                                              s_session.bw) < 0:
                    copy_graph.remove_edge(link_id[0], link_id[1])

            # All to All node shortest distance
            apsp = nx.johnson(copy_graph, weight='BandwidthCost')

            # Remove session which cannot reach to every destination
            if set(s_session.dsts) - set(apsp[s_session.src]):
                continue

            # Shortest path trees
            session_tree = nx.DiGraph()  # DAG - multicast tree
            counted_link = set()
            for dst in s_session.dsts:
                for i, head_edge in enumerate(
                        apsp[s_session.src][dst][:-1]):  # path
                    tail_edge = apsp[s_session.src][dst][i + 1]
                    session_tree.add_edge(head_edge,
                                          tail_edge,
                                          weight=self.graph[head_edge]
                                          [tail_edge]['BandwidthCost'] *
                                          s_session.bw)
                    # Add link usage
                    if (head_edge, tail_edge) not in counted_link:
                        self.links[(head_edge,
                                    tail_edge)].used_cap += s_session.bw
                        counted_link.add((head_edge, tail_edge))

                    # # Add flow table
                    self.node_capacity[head_edge] |= {s_idx}
                    self.node_capacity[tail_edge] |= {s_idx}

                    # Find branching nodes
                    if len(session_tree.edges(head_edge)) > 1:
                        self.session_branch_nodes[s_idx].add(head_edge)
            self.sessions_tree[s_idx] = session_tree

        # Try to reroute all branch node
        for s_idx, nodes in self.session_branch_nodes.items():
            for node in list(nodes):
                self.reroute(s_idx, node)

            # self.reassess_tcam_cost()

        # max_tcam = 0
        # for node, sessions in self.node_capacity.items():
        #     if len(sessions)>max_tcam:
        #         max_tcam = len(sessions)

        total_c = 0
        for link_id, link in self.links.items():
            total_c += link.used_cap

        # print "max_tcam", max_tcam
        print "self.sessions_tree", len(self.sessions_tree)
        print "self.app.get_sessions()", len(self.app.get_sessions())

        print 'All DONE:', len(self.app.get_sessions()) - len(
            self.sessions_tree) == 0

        # ############################
        # # State-Node Assignment Phase
        # ############################
        #
        # print "State-Node Assignment Phase"
        #
        # # Greedy Assigning Stage
        # self.branch_state_node_sessions = defaultdict(set)  # Reset sessions_branch_state_nodes
        # self.session_branch_state_nodes = defaultdict(set)
        # a = defaultdict(set)
        # curr__a_cost = {s_idx: self.cost_t_a(s_idx, set()) for s_idx, _ in self.sessions_tree.items()}
        # cost_t_a_cache = dict()
        # for s_idx, _ in self.sessions_tree.items():
        #     cost_t_a_cache[s_idx] = defaultdict(float)
        # # Find max x
        # while True:
        #     max_x_cost, max_x_node, max_x_s_idx = -float('inf'), None, None
        #     for s_idx, _ in self.sessions_tree.items():
        #         for branch_node in self.session_branch_nodes[s_idx] - a[s_idx]:
        #             if len(self.branch_state_node_sessions[branch_node]) + 1 <= self.nodes[branch_node].services['sdn_router'].resources_cap['tcam']:
        #                 if tuple({branch_node} | a[s_idx]) not in cost_t_a_cache[s_idx]:
        #                     cost_t_a_cache[s_idx][tuple({branch_node} | a[s_idx])] = \
        #                         self.cost_t_a(s_idx, {branch_node} | a[s_idx])
        #                 reduced_cost = curr__a_cost[s_idx] - cost_t_a_cache[s_idx][tuple({branch_node} | a[s_idx])]
        #                 if reduced_cost > max_x_cost:
        #                     max_x_cost, max_x_node, max_x_s_idx = reduced_cost, branch_node, s_idx
        #
        #     if max_x_cost == -float('inf'):
        #         break
        #     a[max_x_s_idx].add(max_x_node)  # AU{x}
        #     curr__a_cost[max_x_s_idx] -= max_x_cost  # z(A)
        #     self.branch_state_node_sessions[max_x_node].add(max_x_s_idx)
        #     self.session_branch_state_nodes[max_x_s_idx].add(max_x_node)
        #
        # self.reassess_cost()
        #
        # total_c = 0
        # for link_id, link in self.links.items():
        #     total_c += link.used_cap
        #
        # print "total_c", total_c
        #
        #
        # # Local Search Stage
        #
        # print "Local Search Stage"
        #
        # # Identify the overloaded nodes
        # overloaded_branch_state_nodes = defaultdict(set)
        # for s_idx, branch_nodes in self.session_branch_nodes.items():
        #     for branch_node in branch_nodes:
        #         overloaded_branch_state_nodes[branch_node].add(s_idx)
        #         if len(overloaded_branch_state_nodes[branch_node]) > \
        #                 self.nodes[branch_node].services['sdn_router'].resources_cap['tcam']:
        #             self.overloaded_set.add(branch_node)
        #
        # # Choose set of session in branch state node that reduce z_cost
        # for u in self.overloaded_set:
        #     cost_no_overloaded_node = [(self.cost_t_a(s_idx, a[s_idx] - {u}) - self.cost_t_a(s_idx, a[s_idx] | {u}),
        #                                 s_idx) for s_idx in overloaded_branch_state_nodes[u]]
        #     cost_no_overloaded_node.sort()
        #
        #     # Remove overloaded node from branch state
        #     self.branch_state_node_sessions[u] = set()
        #     for s_idx in self.session_branch_state_nodes:
        #         if u in self.session_branch_state_nodes[s_idx]:
        #             self.session_branch_state_nodes[s_idx].remove(u)
        #
        #     for _ in range(self.nodes[u].services['sdn_router'].resources_cap['tcam']):
        #         _, best_t = cost_no_overloaded_node.pop()
        #         self.branch_state_node_sessions[u].add(best_t)
        #         self.session_branch_state_nodes[best_t].add(u)
        #         self.reassess_cost()
        #
        #     for _, s_idx in cost_no_overloaded_node:
        #         # Reroute the rest tree
        #         self.reroute(s_idx, u)
        #
        # # If the amount of multicast flows in any edge exceeds the capacity constraint,
        # # we also reroute its closest upstream state node u in a tree Ti
        # # to w, such that the new path from w to v follows the link
        # # capacity constraint.
        # overloaded_links = {link_id for link_id, link in self.links.items() if link.used_cap > link.cap}
        # for s_idx, s_session in self.sessions_tree.items():
        #     for h, t in list(overloaded_links):
        #         if (h, t) in s_session.edges():
        #             # find downstream
        #             down_streams = [t]
        #             while len(down_streams) > 0:
        #                 v = down_streams.pop(0)
        #                 if v in set(self.session_branch_nodes[s_idx]) | set(self.sessions[s_idx].dsts):
        #                     # find downstream
        #                     if self.reroute_path(s_idx, h, v):
        #                         overloaded_links.remove((h, t))
        #                         break
        #                 else:
        #                     down_streams += list(s_session.neighbors(v))
        #
        # # Remove session until link constraint is meant
        # while len(overloaded_links) > 0:
        #     overloaded_link = overloaded_links.pop()
        #     for s_idx in reversed(list(self.sessions_tree)):
        #         if overloaded_link in self.sessions_tree[s_idx].edges():
        #             del self.sessions_tree[s_idx]
        #             self.reassess_cost()
        #             if self.links[overloaded_link].used_cap <= self.links[overloaded_link].cap:
        #                 break

        # total_c = 0
        # for link_id, link in self.links.items():
        #     total_c += link.used_cap
        #
        # print "total_c", total_c
        # print "total mtrsa session", len(self.sessions_tree)
        # print "total session", len(self.app.get_sessions())
        # print "unicast tunneling", self.max_count_unicast_tunneling()
        #
        # for id, node in self.nodes.items():
        #     print "used cam", id, node.services['sdn_router'].used_cap['tcam']

        # Convert networkx to Solution
        for s_idx, s_session in self.sessions_tree.items():
            self._solution.get_tree(self.sessions[s_idx])
            self.update_session_cost(solution=self._solution,
                                     session=self.sessions[s_idx],
                                     links=self.sessions_tree[s_idx].edges())

        total_time = time.time() - start_time
        self._solution.total_time = total_time
        return self._solution
예제 #28
0
def all_pairs_paths(G):
    print "Computing all pairs paths..."
    paths = nx.johnson(G, weight="weight")
    return paths
예제 #29
0
 def use_johnson(self,s,t):
     path = nx.johnson(self.G, source=s, target=t)
     return path