def hier_part(graph, pop_col, pop_target, epsilon):



    h=graph.copy()

    clusters = {x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()}
    #removed=[]
    while len(clusters)>2:

        chosen_e = random.choice(list(h.edges()))
        #print(chosen_e)

        cpop = clusters[chosen_e[0]][1] + clusters[chosen_e[1]][1]
        print(cpop)


        if cpop < pop_target + epsilon*pop_target:
            k=h.copy()
            k.remove_node(chosen_e[1])
            if nx.is_connected(k):
                print(True,True)

                #print(clusters[chosen_e[0]])
                #print(clusters[chosen_e[1]])



                clusters[chosen_e[0]][1] = cpop
                clusters[chosen_e[0]][0]=clusters[chosen_e[0]][0].union(clusters[chosen_e[1]][0])
                clusters.pop(chosen_e[1])
                #removed.append(chosen_e[1])

                h = nx.contracted_edge(h,chosen_e,self_loops = False)
            else:
                print(True,False)
                cc=list(nx.connected_components(k))
                tsums=[]
                for l in cc:
                    tsums.append(0)
                    for n in l:
                        #print(removed)
                        tsums[-1]=tsums[-1]+clusters[n][1]

                val, idx = min((val, idx) for (idx, val) in enumerate(tsums))

                l=cc[idx]

                for n in l:
                    #print(n)
                    clusters[chosen_e[1]][1]=clusters[chosen_e[1]][1] + clusters[n][1]
                    clusters[chosen_e[1]][0]=clusters[chosen_e[1]][0].union(clusters[n][0])
                    clusters.pop(n)
                    h.add_edge(chosen_e[1],n)
                    h = nx.contracted_edge(h,(chosen_e[1],n),self_loops = False)
        else:
            print(False)
        print(len(clusters))

    return clusters
예제 #2
0
def kirkoff_inverse_sampler(graph):

    size = len(graph) - 1
    T = []
    edge_list = list(graph.edges())
    edge = edge_list[0]
    shuffle(edge_list)
    while len(T) <= size - 1:
        print("T currently", len(T))
        edge = choice(list(graph.edges()))
        total_inverse = 0
        for edge in list(graph.edges()):
            H = nx.contracted_edge(graph, edge)
            p = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph))
            #Replace this with a computation of effective resistance!
            #You also don't need to compute this so many times!
            total_inverse += 1/p
        edge = choice(list(graph.edges()))
        H = nx.contracted_edge(graph, edge)
        q = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph))
        p = (1 / q) / total_inverse
        print(p, q, total_inverse)
        c = uniform(0,1)
        if c <= p:
            T.append(edge)
            graph = nx.contracted_edge(graph, edge, self_loops=False)
        else:
            if q < .999999:
                graph.remove_edge(edge[0], edge[1])
    tree = nx.Graph()
    tree.add_edges_from(T)
    edge = T[0]
    return (tree, edge)
예제 #3
0
    def test_nonexistent_edge(self):
        """Tests that attempting to contract a non-existent edge raises an
        exception.

        """
        G = nx.cycle_graph(4)
        nx.contracted_edge(G, (0, 2))
예제 #4
0
    def test_nonexistent_edge(self):
        """TestData that attempting to contract a non-existent edge raises an
        exception.

        """
        with pytest.raises(ValueError):
            G = nx.cycle_graph(4)
            nx.contracted_edge(G, (0, 2))
예제 #5
0
def simplify_network(network):
    """Simplify all linear sections of network by removing nodes
    containing 2 degrees"""

    new_network = network.copy()
    edge_list = get_edge_list(new_network, max_degree=2)

    while edge_list.size > 0:
        for edge in edge_list:
            try:
                new_network = nx.contracted_edge(
                    new_network, edge, self_loops=False)
            except (ValueError, KeyError):
                pass

        edge_list = get_edge_list(new_network, max_degree=2)

    new_network = nx.convert_node_labels_to_integers(new_network)
    node_coord = get_node_coord_array(new_network)

    d_coord, r2_coord = distance_matrix(node_coord)
    r_coord = np.sqrt(r2_coord)

    for edge in new_network.edges:
        new_network[edge[0]][edge[1]]['r'] = r_coord[edge[0]][edge[1]]

    return new_network
예제 #6
0
 def test_undirected_edge_contraction(self):
     """Tests for edge contraction in an undirected graph."""
     G = nx.cycle_graph(4)
     actual = nx.contracted_edge(G, (0, 1))
     expected = nx.complete_graph(3)
     expected.add_edge(0, 0)
     assert nx.is_isomorphic(actual, expected)
def contract_edge_once(graph, edge, reg_param=0):
    """
    Function to contract a given edge `edge` in the graph `graph`. Covariates of the node resulting from the contraction
    is given by the sum of covariates at the nodes composing `edge`. The edge weight is recalculated after this re-assignment.

    Arguments:
    - graph: networkx.Graph object
    - edge: edge in `graph` to be contracted
    - reg_param: parameter for variance based regularization
    """
    node1, node2 = edge
    new_node = generate_node_after_contraction(node1, node2)

    # Contract nodes, and relabel the contracted node with a tuple indicating the cluster
    new_graph = nx.relabel_nodes(
        nx.contracted_edge(graph, (node1, node2), self_loops=False), {node1: new_node}
    )

    new_graph.nodes[new_node]["cov"] = (
        new_graph.nodes[new_node].pop("cov")
        + new_graph.nodes[new_node].pop("contraction")[node2]["cov"]
    )

    # Re-compute the edge weights
    setattr(new_graph, "complete_target", graph.complete_target)
    for edge in new_graph.edges(new_node):  # Just for the edges which originate at new_node
        new_graph.edges[edge]["weight"] = multiple_regression_error_weight(
            new_graph, edge[0], edge[1], reg_param
        )
    return new_graph
예제 #8
0
 def test_undirected_edge_contraction(self):
     """Tests for edge contraction in an undirected graph."""
     G = nx.cycle_graph(4)
     actual = nx.contracted_edge(G, (0, 1))
     expected = nx.complete_graph(3)
     expected.add_edge(0, 0)
     assert_true(nx.is_isomorphic(actual, expected))
예제 #9
0
def contract_edge(graph, edge, edge_weight_assign):
    """
    Function to contract an edge in the graph. Attributes of the nodes of edge being contracted
    are appended to form one longer array and is assigned to the new node resulting from the
    contraction. The edge weight is recalculated after this re-assignment.

    Arguments:
    - graph: networkx.Graph object
    - edge: edge in `graph` to be contracted
    - edge_weight_assign: string representing the weighting function.
    """
    node1, node2 = edge
    new_node = generate_node_after_contraction(node1, node2)

    # Contract nodes, and relabel the contracted node with a tuple indicating the cluster
    new_graph = nx.relabel_nodes(
        nx.contracted_edge(graph, (node1, node2), self_loops=False), {node1: new_node}
    )

    # Re-assign the anomaly attribute; this is simply a concatenation of existing anomalies
    new_graph.nodes[new_node]["cov"] = (
        new_graph.nodes[new_node].pop("cov")
        + new_graph.nodes[new_node].pop("contraction")[node2]["cov"]
    )

    # Re-compute the edge weights
    edge_weight_func = get_edge_weight_func(edge_weight_assign)
    for edge in new_graph.edges(new_node):
        new_graph.edges[edge]["weight"] = edge_weight_func(new_graph, edge[0], edge[1])
    return new_graph
def part2path3(graph, pop_col, pop_target, epsilon):

    h = graph.copy()

    start = random.choice(list(h.nodes()))
    clusters = {x: [{x}, graph.nodes[x][pop_col]] for x in graph.nodes()}

    while clusters[start][1] < pop_target - epsilon * pop_target:

        print(clusters[start][1] / pop_target)

        end = start
        while end == start:
            end = random.choice(list(h.nodes()))

        path = nx.shortest_path(graph, source=start, target=end)

        psum = 0
        for p in path:
            if p not in clusters[start][0]:
                psum += clusters[p][1]

        if psum + clusters[start][0] < pop_target + epsilon * pop_target:
            print(True)

            cpop = psum

            if cpop < pop_target + epsilon * pop_target:
                k = h.copy()
                k.remove_nodes_from(path)

                print(len(k.nodes()))
                if nx.is_connected(k):
                    path.remove(start)
                    print(True, True)
                    for p in path:
                        h.add_edge(start, p)
                        h = nx.contracted_edge(h, (start, p), self_loops=False)
                        if p not in clusters[start][0]:
                            clusters[start][0] = clusters[start][0].union(
                                clusters[p][0])
                            clusters[start][1] += clusters[p][1]
                        #clusters.pop(p)
                else:
                    print(True, False)

            #else:
        #     print(False,False)
        #    h.remove_edge(start,neighbor)

    cd2 = {}
    cd2[start] = clusters[start][0]
    cd2[-1] = []
    for node in graph.nodes():
        if node not in cd2[start]:
            cd2[-1].append(node)

    cd2[-1] = set(cd2[-1])
    return cd2
예제 #11
0
def contract_dag(input_spec, latency_spec):
    G = ScheduleDAG()
    G.create_dag(input_spec.nodes, input_spec.edges, latency_spec)

    action_nodes = G.nodes(select='action')
    match_nodes = G.nodes(select='match')

    tables = []
    found_table = dict()

    for m in match_nodes:
        for a in action_nodes:
            if (a.startswith("_condition")):
                continue
            assert (m.endswith('MATCH'))
            assert (a.endswith('ACTION'))
            m_table = m.strip('MATCH')
            a_table = a.strip('ACTION')
            if (m_table == a_table):
                tables.append((m, a))
                found_table[m] = True
                found_table[a] = True

    for m in match_nodes:
        if m not in found_table:
            print("Unpaired match, ERROR!!!")
            exit(1)

    for a in action_nodes:
        if a not in found_table:
            pass
    #    print ("Unpaired action or condition: ", a, file=sys.stderr)

    # Contract table edges
    for table in tables:
        match = table[0]
        action = table[1]
        table_name = match.strip('MATCH') + 'TABLE'
        key_width = G.node[match]['key_width']
        num_fields = G.node[action]['num_fields']
        G = nx.contracted_edge(G, table, self_loops=False)
        nx.relabel_nodes(G, {match: table_name}, False)
        G.node[table_name]['type'] = 'table'
        G.node[table_name]['key_width'] = key_width
        G.node[table_name]['num_fields'] = num_fields

    # Create dummy tables for the rest
    for v in G.nodes():
        if (G.node[v]['type'] != 'table'):
            G.node[v]['type'] = 'table'
            G.node[v]['key_width'] = 0
            assert (G.node[v]['num_fields'] >= 0)
            # leave num_fields unchanged

    return G
예제 #12
0
def kirkoff_sampler(graph):
    size = len(graph) - 1
    T = []
    edge_list = list(graph.edges())
    edge = edge_list[0]
    shuffle(edge_list)
    while len(T) <= size - 1:
        edge = choice(list(graph.edges()))
        H = nx.contracted_edge(graph, edge)
        p = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph))
        print(p)
        c = uniform(0,1)
        if c <= p:
            T.append(edge)
            graph = nx.contracted_edge(graph, edge, self_loops=False)
        else:
            graph.remove_edge(edge[0], edge[1])
    tree = nx.Graph()
    tree.add_edges_from(T)
    return tree
예제 #13
0
    def edge_contract(self, u, v, self_loop=False):
        """
		Contract the edge (u,v) and relabel u using the concatenation of the labels at u and v
		"""
        try:
            ulabel = self.g.node[u]['label']
            vlabel = self.g.node[v]['label']
            self.g = nx.contracted_edge(self.g, (u, v), self_loop)
            self.g.node[u]['label'] = ulabel + vlabel
        except ValueError as err:
            print(err)
예제 #14
0
def minor(graph):
    g = nx.Graph(graph)
    while True:
        has_contracted = False
        for u, v in g.edges():
            if g.nodes[u]['label'] == g.nodes[v]['label']:
                g = nx.contracted_edge(g, (u, v), self_loops=False)
                has_contracted = True
                break
        if has_contracted is False:
            break
    return g
예제 #15
0
 def contract(self, G, c):
     # Contract edges uv as long as d(u)+d(v)\leq c.
     while True:
         try:
             u, v = next(
                 ifilter(
                     lambda x: x[0] != x[1] and G.degree(x[0]) + G.degree(x[
                         1]) <= c, G.edges_iter()))
             G = nx.contracted_edge(G, (u, v), self_loops=False)
         except StopIteration:
             break
     return G
예제 #16
0
def merge(G,edge):
    """Returns a new graph with edge merged, and the new node containing the
            information lost in the merge. The weights from common neighbors
            are added together, a la Stoer-Wagner algorithm."""            
    if G.node[edge[1]]['type'] == 'login' or G.node[edge[1]]['type'] == 'email':
        edge = edge[::-1] # If login/email is on the right, flip the order, so it's always on the left
    
    nx.set_node_attributes(G,'list',{edge[0]:G.node[edge[0]]['list']+[edge[1]]})

    J = nx.contracted_edge(G,(edge[0],edge[1]),self_loops = False)  #Contract edge without self-loop
    # Weight stuff
    N = nx.common_neighbors(G,edge[0],edge[1]) #find common nodes
    for i in N:
        J[i][edge[0]]['weight'] = G[edge[0]][i]['weight'] + G[edge[1]][i]['weight'] #modify the weight after contraction
    return J
예제 #17
0
def contract_tree(tree):
    G_tree = nx.from_edgelist(get_edge_list(tree))
    for u in G_tree:
        if u not in G_tree:
            continue
        G = list(G_tree[u])
        while len(G) == 2:
            mx = max(G)
            G_temp = nx.contracted_edge(G_tree, (u, mx))
            G_temp.remove_edges_from(G_temp.selfloop_edges())
            G = list(G_temp[u])
            '''if len(G) >= 3:
        break'''
            G_tree = G_temp
    return G_tree
예제 #18
0
    def minor_lbound_num(self, k, timeout, l=1):
        for u, v in self.G.edges_iter():
            G1 = nx.convert_node_labels_to_integers(
                nx.contracted_edge(self.G, (u, v), self_loops=False))
            # sanity check
            # G1 = self.hypergraph.copy()
            lbound_solver = GraphSatTw(G1, timeout=timeout)

            print('u = %s, v = %s' % (u, v))
            ret = lbound_solver.solve(k)
            print('ret = %s' % ret)
            if not ret:
                return False

        return True
예제 #19
0
    def contract(self):
        to_contract = {"id", "connect"}
        graph = self.graph.copy()

#         none_nodes = [n for n in graph.nodes() if str(n) == "none"]
#         graph.remove_nodes_from(none_nodes)

        def left_to_contract(graph):
            node_names = set([str(n) for n in graph.nodes()])
            return len(node_names.intersection(to_contract)) > 0

        while left_to_contract(graph):
            for e_1, e_2 in graph.edges():
                if str(e_2) in to_contract:
                    graph = nx.contracted_edge(graph, (e_1, e_2), self_loops=False)
                    break
        return graph
예제 #20
0
파일: treewidth.py 프로젝트: yqu1/PSHRG
def lower_bound(graph):
    """Minor-min-width"""
    graph = graph.copy()
    dmax = 0
    while len(graph) > 0:
        # pick node of minimum degree
        d, u = min((len(graph[u]), u) for u in graph)
        dmax = max(dmax, d)

        # Gogate and Dechter: minor-min-width
        nb = set(graph[u]) - {u}
        if len(nb) > 0:
            _, v = min((len(set(graph[v]) & nb), v) for v in nb)
            graph = networkx.contracted_edge(graph, (u, v), self_loops=False)
        else:
            graph.remove_node(u)
    return dmax
예제 #21
0
    def __contracted_edges(self, G, node_from, node_to):
        '''
        contract edges (u,v) in a Graph G
        :param G: NetworkX Graph
        :param node_from: node u of an edge (u,v)
        :param node_to: node v of an edge (u,v)

        :return: A network graph where node v will be merge into u
        '''
        u = self.__get_node(node_from)
        v = self.__get_node(node_to)
        M = nx.contracted_edge(G, (u, v))

        # since the node v is merged with u, we save the reference in case that there an edges that needs to be
        # contracted which includes node v.
        self.__set_node(v, u)
        return M
예제 #22
0
def contract_edges_matching(G, num_iters=2):
    """Given a graph G and a desired number of edges to be contracted, contracts edges
    uniformly at random (non-mutating of the original graph). Edges are contracted such
    that the two endpoints are now "identified" with one another. This mapping is returned
    as a dictionary If more edges are provided than can be contracted, an error is thrown. 

    Returns (1) contracted graph (NetworkX Graph); 
    (2) identified nodes dictionary (NetworkX node -> NetworkX node)
    """
    identified_nodes = {}
    for _ in range(num_iters):
        edges = list(G.edges)
        matching = nx.maximal_matching(G)
        for vertex_pair in matching:
            identified_nodes[vertex_pair[0]] = vertex_pair[
                0]  # right gets contracted into left
            G = nx.contracted_edge(G, vertex_pair, self_loops=False)
    return G, identified_nodes
예제 #23
0
def contract_edges(G, num_edges):
    """Given a graph G and a desired number of edges to be contracted, contracts edges
    uniformly at random (non-mutating of the original graph). Edges are contracted such
    that the two endpoints are now "identified" with one another. This mapping is returned
    as a dictionary If more edges are provided than can be contracted, an error is thrown. 

    Returns (1) contracted graph (NetworkX Graph); 
    (2) identified nodes dictionary (NetworkX node -> NetworkX node)
    """
    identified_nodes = {}
    for _ in range(num_edges):
        edges = list(G.edges)
        random_edge = edges[random.randint(0, len(edges) - 1)]
        node_to_contract = random_edge[1]
        identified_nodes[node_to_contract] = random_edge[
            0]  # right gets contracted into left
        G = nx.contracted_edge(G, random_edge, self_loops=False)
    return G, identified_nodes
예제 #24
0
파일: t1.py 프로젝트: satemochi/saaaaah
def draw_contraction(T):
    t = T.copy()
    stack = [v for v in t.nodes() if len(eval(v)) == 1]
    pos = nx.spring_layout(t)
    draw_snapshot(t, stack, pos)

    i = 1
    while stack:
        v = stack.pop()
        for w in t[v]:
            if len(eval(w)) > 1:
                t = nx.contracted_edge(t, (v, w), self_loops=False)
                #                stack.append(v)
                stack = [v] + stack
                draw_snapshot(t, stack, pos, i)
                i += 1
                break
    for u, v in t.edges():
        t[u][v]['weight'] *= 4
    draw_snapshot(t, stack, pos, i)
    return t
예제 #25
0
파일: main.py 프로젝트: qbit-/FastBB
def mmw(g):
    lb = 0
    iter = 0
    while True:
        iter += 1
        nodes = list(g.nodes())
        if len(nodes) < 2:
            return lb
        # todo: huge room for optimization here
        #---- Find min degree vertex
        vertex, degree = min_degreeV(g, nodes)
        #---- Find min degree v from his neighbors
        neig = list(g.neighbors(vertex))
        neig = [v for v in neig if v != vertex]
        vertex2, _ = min_degreeV(g, neig)
        #print(lb,iter,vertex,vertex2)
        # Self loops=False costed me 1.5 hours!
        g = nx.contracted_edge(g, (vertex, vertex2), self_loops=False)
        #data._save_graph(g,'gt%i.png'%iter)
        nodes = list(g.nodes())
        lb = max(lb, degree)
예제 #26
0
def mincut(g):
    # check that g is a graph with > 2 vertices
    assert isinstance(g, nx.MultiGraph) and nx.is_connected(g)

    # check base cases of vertices
    if g.number_of_nodes() < 2:
        return 0
    elif g.number_of_nodes() == 2:
        return g.size()

    # while more than two nodes remain remove an edge
    while (g.number_of_nodes() > 2):
        # pick and edge at random
        idx = np.random.choice(len(g.edges()))
        random_edge = g.edges()[idx]

        # contract the edge in the graph
        #nx.draw(g)
        g = nx.contracted_edge(g, random_edge, self_loops=False)

    # return the number of edges remaining in g
    print(g)
    return g.size()
예제 #27
0
def expand_graph(G, n):

    print "G has:", len(G.nodes()), "nodes"

    # number of times to expand
    for expand in range(n):

        nextEdges = G.edges(1)

        print "Root Neighbors:", nextEdges

        # print G.edges()

        print "expanding"

        # merges with all neighboring nodes
        for edge in nextEdges:
            G = nx.contracted_edge(G, edge, self_loops=False)

        print "G has:", len(G.nodes()), "nodes"
        # print G.edges()

    return G
예제 #28
0
def make_random_homomorphism(G):
    H = nx.Graph(G)
    r = randint(1, int(max(5, len(list(G.nodes())) / 5)))
    phi = list(range(len(G.nodes())))
    for i in range(randint(1, r)):
        u = choice(list(G.nodes()))
        v = [
            v for v in list(G.nodes())
            if v != u and (u, v) not in list(G.edges())
        ]
        v = choice(v)
        H.add_edge(v, u)
        edge = (v, u)
        H = nx.contracted_edge(H, edge, self_loops=False)
        phi[u] = v
    for i in range(randint(1, r)):
        u = choice(list(G.nodes()))
        v = [
            v for v in list(G.nodes())
            if v != u and (u, v) not in list(G.edges())
        ]
        v = choice(v)
        H.add_edge(u, v)
    return H, phi
예제 #29
0
def _recursive(G):
	# If the graph is not connected, then it has a rel poly of 0
	if not nx.is_connected(G):
		return sympy.Poly(0, p)
	
	# Check if the graph is multigraph complete
	#  and has no parallel edges
	if is_multigraph_complete_no_parallel(G):
		return _complete(G)

	# if # edges > 0, then we perform the two subcases of the 
	# 	Factoring theorem.
	if len(G.edges()) > 0:
		e = random.choice(G.edges())
		contracted = nx.contracted_edge(G, e, self_loops=False)
		G.remove_edge(*e)
		rec_deleted = _recursive(G)
		rec_contracted = _recursive(contracted)
		s = sympy.Poly(p)*(rec_contracted) + sympy.Poly(1-p)*(rec_deleted)
		return s

	# Otherwise, we only have 0 edges and 1 vertex, which is connected,
	# 	so we return 1.
	return sympy.Poly(1, p)
def part2blob(graph, pop_col, pop_target, epsilon):
    

    h=graph.copy()
    
    start = random.choice(list(h.nodes()))
    clusters={x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()}
    
    neighbors = list(h.neighbors(start))

    while clusters[start][1] < pop_target - epsilon*pop_target:
        
        print(clusters[start][1]/pop_target)
        
        if neighbors==[]:
            neighbors=list(h.neighbors(start))
            
        for neighbor in neighbors:

    
            
            cpop = clusters[start][1] + clusters[neighbor][1]
            
            if  cpop < pop_target + epsilon*pop_target:
                k=h.copy()
                k.remove_node(start)
                k.remove_node(neighbor)
                print(len(k.nodes()))
                if nx.is_connected(k):
                    print(True,True)
                    h = nx.contracted_edge(h,(start,neighbor),self_loops = False)
                    clusters[start][0] = clusters[start][0].union(clusters[neighbor][0])
                    clusters[start][1] = cpop
                    clusters.pop(neighbor)
                else:
                    print(True,False)
                
                    cc=list(nx.connected_components(k))
                    tsums=[]
                    for l in cc:
                        tsums.append(0)
                        for n in l:
                            #print(removed)
                            tsums[-1]=tsums[-1]+graph.nodes[n][pop_col]
                    
                    val, idx = min((val, idx) for (idx, val) in enumerate(tsums))
                    
                    l=cc[idx]
                        
                    for n in l:
                        #print(n)
                        h.add_edge(neighbor,n)
                        #h.nodes[neighbor][pop_col]+=h.nodes[n][pop_col]
                        clusters[neighbor][1] = clusters[neighbor][1]+ clusters[n][1]
                        h = nx.contracted_edge(h,(neighbor,n),self_loops = False)
                        clusters[neighbor][0]=clusters[neighbor][0].union(clusters[n][0])
                        clusters.pop(n)
                        if n in neighbors:
                            neighbors.remove(n)
                        
            else:
                print(False,False)
                h.remove_edge(start,neighbor)
            neighbors.remove(neighbor)
                

    
    cd2={}
    cd2[start]=clusters[start][0] 
    cd2[-1]=[]
    for node in graph.nodes():
        if node not in cd2[start]:
            cd2[-1].append(node)    
            
    cd2[-1]=set(cd2[-1])
    cs=dict()
    cs[1]=cd2[start]
    print(cs)
    print(cs[1])
    return cs
            k=h.copy()
            k.remove_node(chosen_e[1])
            if nx.is_connected(k):
                print(True,True)
h
                #print(clusters[chosen_e[0]])
                #print(clusters[chosen_e[1]])

            
            
                clusters[chosen_e[0]][1] = cpop
                clusters[chosen_e[0]][0]=clusters[chosen_e[0]][0].union(clusters[chosen_e[1]][0])
                clusters.pop(chosen_e[1])
                #removed.append(chosen_e[1])
                
                h = nx.contracted_edge(h,chosen_e,self_loops = False)
            else:
                print(True,False)
                cc=list(nx.connected_components(k))
                tsums=[]
                for l in cc:
                    tsums.append(0)
                    for n in l:
                        #print(removed)
                        tsums[-1]=tsums[-1]+clusters[n][1]
                
                val, idx = min((val, idx) for (idx, val) in enumerate(tsums))
                
                l=cc[idx]
                    
                for n in l:
예제 #32
0
def populate_graph(data):  # noqa: C901

    Graph = namedtuple('Graph', 'G source regions')

    G = nx.Graph(
    )  # We can't trust directions of edges, so graph should be not-directional
    # MG = nx.Graph()  # converted graph to modules.tf schema

    # @todo: convert from graph (G) to modules.tf graph (MG), which can be dumped to json and passed to generator function

    regions = []
    connectors = []

    # We don't care about these keys in json: images, icons
    data_id = data["id"]
    data = data.get("data", {})

    data_nodes = data.get("nodes", [])
    data_edges = data.get("edges", [])
    data_groups = data.get("groups", [])
    data_connectors = data.get("connectors", [])
    data_text = data.get("text", [])
    data_name = data.get("name", "unnamed")

    ########
    # NODES
    ########
    for node in data_nodes:
        G.add_node(node["id"], data=node)

    ########
    # EDGES
    ########
    for edge in data_edges:
        if "from" in edge and "to" in edge:
            G.add_edge(edge["from"], edge["to"])

    #####################
    # AUTOSCALING GROUPS, SECURITY GROUPS AND VPCS
    #####################
    for group in data_groups:
        group_type = group.get("type")

        if group_type in ["asg", "sg", "vpc"]:
            group_id = group.get("id")
            group_nodes = group.get("nodes")
            group_region = group.get("region")
            group_name = group.get("name")

            regions.append(group_region)

            G.add_node(group_id,
                       data={
                           "type": group_type,
                           "group_nodes": group_nodes,
                           "group_region": group_region,
                           "group_name": group_name,
                       })

            if group_type == "sg":
                G.nodes[group_id]["data"]["inbound_rules"] = group.get(
                    "inboundRules")
                G.nodes[group_id]["data"]["outbound_rules"] = group.get(
                    "outboundRules")
            elif group_type == "vpc":
                G.nodes[group_id]["data"]["peering_connections"] = group.get(
                    "peeringConnections")

            for group_node in group_nodes:
                # some items (like "text") may belong to groups, but are not in "nodes"
                if group_node not in G.nodes:
                    continue

                # nodes type "icon" does not have "data", so we skip them
                if "data" not in G.nodes[group_node]:
                    continue

                if group_type == "asg":
                    G.nodes[group_node]["data"]["asg_id"] = group_id
                elif group_type == "sg":
                    G.nodes[group_node]["data"]["sg_id"] = group_id
                elif group_type == "vpc":
                    G.nodes[group_node]["data"]["vpc_id"] = group_id

    #############
    # CONNECTORS
    #############
    for connector in data_connectors:
        G.add_node(connector["id"], type="connector")
        connectors.append(connector["id"])

    # Merge connectors by contracting edges
    edge = []
    while True:
        # Find first edge which contains connector
        for edge in G.edges.data():
            edge = list(edge)

            if edge[0] == edge[1]:
                edge = []  # maybe continue
            elif edge[0] in connectors or edge[1] in connectors:
                break
            else:
                edge = []

        # Skip edges without connectors and edges which does not have nodes on one any side
        if len(edge) == 0 or edge[0] not in G or edge[1] not in G:
            break

        G = nx.contracted_edge(G, (edge[0], edge[1]), self_loops=False)

    ########
    # TEXTS
    ########
    for text in data_text:
        mapPos = text.get("mapPos", {})
        if isinstance(mapPos, dict):
            relTo = mapPos.get("relTo")

            if relTo in G.nodes:
                G.nodes[relTo]["text"] = text["text"].strip()

    ###########
    # REGION
    ###########
    regions = list(set(regions))

    ########
    # SOURCE
    ########
    source = {
        "name": data_name,
        "id": data_id,
    }

    # Debug - draw into file
    # import matplotlib.pyplot as plt
    # plt.rcParams["figure.figsize"] = (10, 10)
    # nx.draw(G, pos=nx.spring_layout(G), with_labels=True)
    # plt.savefig("graph.png")

    # pprint(G.edges["0820fb86-ee74-49ce-9fe5-03f610ca5e75"])
    pprint("NODES===")
    pprint(G.nodes.data())
    # print("EDGES===")
    # print(G.edges.data())

    # pprint(regions)

    # pprint(regions.keys())
    # pprint(nodes)
    # pprint(texts)
    # pprint(edges, indent=2)
    # pprint(edges_rev)

    # nx.drawing.nx_agraph.write_dot(G, "graph.dot")

    return Graph(G, source, regions)