Finding cycle of 3 nodes ( or triangles) in a graph

后端 未结 11 2196
南旧
南旧 2020-12-31 15:42

I am working with complex networks. I want to find group of nodes which forms a cycle of 3 nodes (or triangles) in a given graph. As my graph contains about million edges, u

11条回答
  •  余生分开走
    2020-12-31 16:45

    A million edges is quite small. Unless you are doing it thousands of times, just use a naive implementation.

    I'll assume that you have a dictionary of node_ids, which point to a sequence of their neighbors, and that the graph is directed.

    For example:

    nodes = {}
    nodes[0] = 1,2
    nodes[1] = tuple() # empty tuple
    nodes[2] = 1
    

    My solution:

    def generate_triangles(nodes):
        """Generate triangles. Weed out duplicates."""
        visited_ids = set() # remember the nodes that we have tested already
        for node_a_id in nodes:
            for node_b_id in nodes[node_a_id]:
                if nod_b_id == node_a_id:
                    raise ValueError # nodes shouldn't point to themselves
                if node_b_id in visited_ids:
                    continue # we should have already found b->a->??->b
                for node_c_id in nodes[node_b_id]:
                    if node_c_id in visited_ids:
                        continue # we should have already found c->a->b->c
                    if node_a_id in nodes[node_c_id]:
                        yield(node_a_id, node_b_id, node_c_id)
            visited_ids.add(node_a_id) # don't search a - we already have all those cycles
    

    Checking performance:

    from random import randint
    n = 1000000
    node_list = range(n)
    nodes = {}
    for node_id in node_list:
        node = tuple()
        for i in range(randint(0,10)): # add up to 10 neighbors
            try:
                neighbor_id = node_list[node_id+randint(-5,5)] # pick a nearby node
            except:
                continue 
            if not neighbor_id in node:
                node = node + (neighbor_id,)
        nodes[node_id] = node
    
    cycles = list(generate_triangles(nodes))
    print len(cycles)
    

    When I tried it, it took longer to build the random graph than to count the cycles.

    You might want to test it though ;) I won't guarantee that it's correct.

    You could also look into networkx, which is the big python graph library.

提交回复
热议问题