Skip to content
Snippets Groups Projects
dsalgo.py 1.32 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
    """
    Goldberg's exact max flow algorithm.
    
    Parameters
    ----------
    G: undirected, graph (networkx).
    
    Returns
    -------
    subg: list, subset of nodes corresponding to densest subgraph.
    opt: float, density of subg induced subgraph.
    
    """
    
    import networkx as nx
    import copy
    
    
    def exact_densest(G: nx.Graph):
    
        m = G.number_of_edges()
        n = G.number_of_nodes()
        
        low = 0
        up = (n - 1) / 2
    
        opt = 0
        subg = G.nodes()
        
        if low == up:
            return subg, up
        
        # binary search
        while up - low > 1 / (n *(n -1)): 
            guess = (up + low) / 2
            H = create_flow_network(G, guess)
            
            solution = nx.minimum_cut(H, 's', 't', capacity='capacity')  
            cut = solution[1][0]
    
            if cut == {'s'}:
                up = guess  
            else:            
                low = guess
                subg = cut
                opt = guess
                
        subg = list(set(subg)&set(G.nodes()))
        
        return subg, opt
    
    def create_flow_network(G, guess):
        m = G.number_of_edges()
        G = nx.DiGraph(G)
        
        H = G.copy()
        H.add_node('s')
        H.add_node('t')
        
        for e in G.edges():
            H.add_edge(e[0], e[1], capacity=G.edges[e[0], e[1]]['weight'])
    
        for v in G.nodes():
            H.add_edge('s', v, capacity=m)
            H.add_edge(v, 't', capacity=m + 2 * guess - G.in_degree(v, 'weight'))
        return H