def generate(num_nodes, num_edges, directed=False, weight_range=(1, 1)):
    """
    Create a random graph.
    
    @type  num_nodes: number
    @param num_nodes: Number of nodes.
    
    @type  num_edges: number
    @param num_edges: Number of edges.
    
    @type  directed: bool
    @param directed: Whether the generated graph should be directed or not.  

    @type  weight_range: tuple
    @param weight_range: tuple of two integers as lower and upper limits on randomly generated
    weights (uniform distribution).
    """
    # Graph creation
    if directed:
        random_graph = digraph()
    else:
        random_graph = graph()

    # Nodes
    nodes = range(num_nodes)
    random_graph.add_nodes(nodes)
    
    # Build a list of all possible edges
    edges = []
    edges_append = edges.append
    for x in nodes:
        for y in nodes:
            if ((directed and x != y) or (x > y)):
                edges_append((x, y))
    
    # Randomize the list
    shuffle(edges)
    
    # Add edges to the graph
    min_wt = min(weight_range)
    max_wt = max(weight_range)
    for i in range(num_edges):
        each = edges[i]
        random_graph.add_edge((each[0], each[1]), wt = randint(min_wt, max_wt))

    return random_graph
Beispiel #2
0
def cut_tree(igraph, caps = None):
    """
    Construct a Gomory-Hu cut tree by applying the algorithm of Gusfield.

    @type igraph: graph
    @param igraph: Graph

    @type caps: dictionary
    @param caps: Dictionary specifying a maximum capacity for each edge. If not given, the weight of the edge
    will be used as its capacity. Otherwise, for each edge (a,b), caps[(a,b)] should be given.
    
    @rtype: dictionary
    @return: Gomory-Hu cut tree as a dictionary, where each edge is associated with its weight
    """

    #maximum flow needs a digraph, we get a graph
    #I think this conversion relies on implementation details outside the api and may break in the future
    graph = digraph()
    graph.add_graph(igraph)

    #handle optional argument
    if not caps:
        caps = {}
        for edge in graph.edges():
            caps[edge] = igraph.edge_weight(edge)

    #temporary flow variable
    f = {}

    #we use a numbering of the nodes for easier handling
    n = {}
    N = 0
    for node in graph.nodes():
        n[N] = node
        N = N + 1

    #predecessor function
    p = {}.fromkeys(range(N),0)
    p[0] = None

    for s in range(1,N):
        t = p[s]
        S = []
        #max flow calculation
        (flow,cut) = maximum_flow(graph,n[s],n[t],caps)
        for i in range(N):
            if cut[n[i]] == 0:
                S.append(i)
        
        value = cut_value(graph,flow,cut)

        f[s] = value

        for i in range(N):
            if i == s:
                continue
            if i in S and p[i] == t:
                p[i] = s
        if p[t] in S:
            p[s] = p[t]
            p[t] = s
            f[s] = f[t]
            f[t] = value

    #cut tree is a dictionary, where each edge is associated with its weight
    b = {}
    for i in range(1,N):
        b[(n[i],n[p[i]])] = f[i]
    return b