def local_search(graph,
                 part_init=None,
                 weight='weight',
                 resolution=1.,
                 randomize=None):

    if type(graph) != nx.Graph:
        raise TypeError("Bad graph type, use only non directed graph")

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in graph.nodes():
            part[node] = node
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    __one_level(current_graph, status, weight, resolution, randomize)
    partition = __renumber(status.node2com)
    return partition
def contribution_nodeneighbor(partition, graph, weight='weight'):

    contribution = dict([])
    participation = dict([])
    node_neighbor = dict([])
    newstatus = Status()
    newstatus.init(graph, weight, partition)
    links = newstatus.total_weight
    if links == 0:
        raise ValueError("A graph without link has an undefined modularity")

    for node in graph:
        com_node = newstatus.node2com[node]
        deg_node = newstatus.gdegrees.get(node, 0.)
        deg_com = newstatus.degrees.get(com_node, 0.)

        neigh_communities = __neighcom(node,
                                       graph,
                                       newstatus,
                                       weight_key=weight)
        if neigh_communities:
            contribution[node] = round(
                neigh_communities.get(com_node, 0) -
                (0.5 * deg_node * deg_com) / links, 4)
            for com, dnc in neigh_communities.items():
                participation[node] = participation.get(
                    node, 1) - (dnc / deg_node)**2
                if com != com_node:
                    if node_neighbor.has_key(node):
                        node_neighbor[node].append(com)
                    else:
                        node_neighbor[node] = [com]
            if node_neighbor.has_key(node):
                pass
            else:
                node_neighbor[node] = [com_node]
    return contribution, participation, node_neighbor
def node_contribution(partition, graph, weight='weight'):
    indegree = dict([])
    contribution = dict([])
    links = graph.size(weight=weight)
    newstatus = Status()
    newstatus.init(graph, weight, partition)
    if links == 0:
        raise ValueError("A graph without link has an undefined modularity")

    for node in graph:
        com = partition[node]

        for neighbor, datas in graph[node].items():
            edge_weight = datas.get(weight, 1)
            if partition[neighbor] == com:
                if neighbor != node:
                    indegree[node] = indegree.get(node,
                                                  0.) + float(edge_weight)
        contribution[node] = round(
            indegree[node] -
            (0.5 * newstatus.gdegrees[node] * newstatus.degrees[com]) / links,
            4)

    return contribution
Exemple #4
0
def generate_dendrogram(graph,
                        inc_fnc,
                        part_init=None,
                        weight='weight',
                        randomize=False):
    """Find communities in the graph and return the associated dendrogram
	A dendrogram is a tree and each level is a partition of the graph nodes.
	Level 0 is the first partition, which contains the smallest communities,
	and the best is len(dendrogram) - 1. The higher the level is, the bigger
	are the communities
	"""

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in list(graph.nodes()):
            part[node] = node
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()

    changed = one_level(current_graph, inc_fnc, status, weight, randomize)
    partition = renumber(status.node2com)

    status_list.append(partition)
    current_graph = induced_graph(partition, current_graph, weight)
    status.init(current_graph, weight)

    while False:
        changed = one_level(current_graph, inc_fnc, status, weight, randomize)
        if not changed:
            break
        partition = renumber(status.node2com)
        status_list.append(partition)

        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)

    return status_list[:]
def generate_dendrogram(graph,
                        part_init=None,
                        weight='weight',
                        resolution=1.,
                        randomize=None):
    """Find communities in the graph and return the associated dendrogram

    A dendrogram is a tree and each level is a partition of the graph nodes.
    Level 0 is the first partition, which contains the smallest communities,
    and the best is len(dendrogram) - 1. The higher the level is, the bigger
    are the communities


    Parameters
    ----------
    graph : networkx.Graph
        the networkx graph which will be decomposed
    part_init : dict, optional
        the algorithm will start using this partition of the nodes. It's a
        dictionary where keys are their nodes and values the communities
    weight : str, optional
        the key in graph to use as weight. Default to 'weight'
    resolution :  double, optional
        Will change the size of the communities, default to 1.
        represents the time described in
        "Laplacian Dynamics and Multiscale Modular Structure in Networks",
        R. Lambiotte, J.-C. Delvenne, M. Barahona

    Returns
    -------
    dendrogram : list of dictionaries
        a list of partitions, ie dictionnaries where keys of the i+1 are the
        values of the i. and where keys of the first are the nodes of graph

    Raises
    ------
    TypeError
        If the graph is not a networkx.Graph

    See Also
    --------
    best_partition

    Notes
    -----
    Uses Louvain algorithm

    References
    ----------
    .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
    networks. J. Stat. Mech 10008, 1-12(2008).

    Examples
    --------
    >>> G=nx.erdos_renyi_graph(100, 0.01)
    >>> dendo = generate_dendrogram(G)
    >>> for level in range(len(dendo) - 1) :
    >>>     print("partition at level", level,
    >>>           "is", partition_at_level(dendo, level))
    :param weight:
    :type weight:
    """
    if type(graph) != nx.Graph:
        raise TypeError("Bad graph type, use only non directed graph")

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in graph.nodes():
            part[node] = node
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()
    __one_level(current_graph, status, weight, resolution, randomize)
    new_mod = __modularity(status)
    partition = __renumber(status.node2com)
    status_list.append(partition)
    mod = new_mod
    current_graph = induced_graph(partition, current_graph, weight)
    status.init(current_graph, weight)

    while True:
        __one_level(current_graph, status, weight, resolution)
        new_mod = __modularity(status)
        if new_mod - mod < __MIN:
            break
        partition = __renumber(status.node2com)
        status_list.append(partition)
        mod = new_mod
        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)
    return status_list[:]
def generate_dendrogram(graph, part_init=None, weight='weight', resolution=1.):
    """Find communities in the graph and return the associated dendrogram

    A dendrogram is a tree and each level is a partition of the graph nodes.
    Level 0 is the first partition, which contains the smallest communities,
    and the best is len(dendrogram) - 1. The higher the level is, the bigger
    are the communities


    Parameters
    ----------
    graph : networkx.Graph
        the networkx graph which will be decomposed
    part_init : dict, optional
        the algorithm will start using this partition of the nodes. It's a
        dictionary where keys are their nodes and values the communities
    weight : str, optional
        the key in graph to use as weight. Default to 'weight'
    resolution :  double, optional
        Will change the size of the communities, default to 1.
        represents the time described in
        "Laplacian Dynamics and Multiscale Modular Structure in Networks",
        R. Lambiotte, J.-C. Delvenne, M. Barahona

    Returns
    -------
    dendrogram : list of dictionaries
        a list of partitions, ie dictionnaries where keys of the i+1 are the
        values of the i. and where keys of the first are the nodes of graph

    Raises
    ------
    TypeError
        If the graph is not a networkx.Graph

    See Also
    --------
    best_partition

    Notes
    -----
    Uses Louvain algorithm

    References
    ----------
    .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
    networks. J. Stat. Mech 10008, 1-12(2008).

    Examples
    --------
    >>> G=nx.erdos_renyi_graph(100, 0.01)
    >>> dendo = generate_dendrogram(G)
    >>> for level in range(len(dendo) - 1) :
    >>>     print("partition at level", level,
    >>>           "is", partition_at_level(dendo, level))
    :param weight:
    :type weight:
    """
    if type(graph) != nx.Graph:
        raise TypeError("Bad graph type, use only non directed graph")

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in graph.nodes():
            part[node] = node
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()
    __one_level(current_graph, status, weight, resolution)
    new_mod = __modularity(status)
    partition = __renumber(status.node2com)
    status_list.append(partition)
    mod = new_mod
    current_graph = induced_graph(partition, current_graph, weight)
    status.init(current_graph, weight)

    while True:
        __one_level(current_graph, status, weight, resolution)
        new_mod = __modularity(status)
        if new_mod - mod < __MIN:
            break
        partition = __renumber(status.node2com)
        status_list.append(partition)
        mod = new_mod
        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)
    return status_list[:]
def generate_dendrogram(graph,
                        part_init=None,
                        weight='weight',
                        resolution=1.,
                        randomize=None,
                        random_state=None):
    """Find communities in the graph and return the associated dendrogram

    A dendrogram is a tree and each level is a partition of the graph nodes.
    Level 0 is the first partition, which contains the smallest communities,
    and the best is len(dendrogram) - 1. The higher the level is, the bigger
    are the communities


    Parameters
    ----------
    graph : networkx.Graph
        the networkx graph which will be decomposed
    part_init : dict, optional
        the algorithm will start using this partition of the nodes. It's a
        dictionary where keys are their nodes and values the communities
    weight : str, optional
        the key in graph to use as weight. Default to 'weight'
    resolution :  double, optional
        Will change the size of the communities, default to 1.
        represents the time described in
        "Laplacian Dynamics and Multiscale Modular Structure in Networks",
        R. Lambiotte, J.-C. Delvenne, M. Barahona

    Returns
    -------
    dendrogram : list of dictionaries
        a list of partitions, ie dictionnaries where keys of the i+1 are the
        values of the i. and where keys of the first are the nodes of graph

    Raises
    ------
    TypeError
        If the graph is not a networkx.Graph

    See Also
    --------
    best_partition

    Notes
    -----
    Uses Louvain algorithm

    References
    ----------
    .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
    networks. J. Stat. Mech 10008, 1-12(2008).

    Examples
    --------
    >>> G=nx.erdos_renyi_graph(100, 0.01)
    >>> dendo = generate_dendrogram(G)
    >>> for level in range(len(dendo) - 1) :
    >>>     print("partition at level", level,
    >>>           "is", partition_at_level(dendo, level))
    :param weight:
    :type weight:
    """
    if graph.is_directed():
        raise TypeError("Bad graph type, use only non directed graph")

    # Properly handle random state, eventually remove old `randomize` parameter
    # NOTE: when `randomize` is removed, delete code up to random_state = ...
    if randomize is not None:
        warnings.warn(
            "The `randomize` parameter will be deprecated in future "
            "versions. Use `random_state` instead.", DeprecationWarning)
        # If shouldn't randomize, we set a fixed seed to get determinisitc results
        if randomize is False:
            random_state = 0

    # We don't know what to do if both `randomize` and `random_state` are defined
    if randomize and random_state is not None:
        raise ValueError(
            "`randomize` and `random_state` cannot be used at the "
            "same time")

    random_state = check_random_state(random_state)

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for i, node in enumerate(graph.nodes()):
            part[node] = i
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()
    __one_level(current_graph, status, weight, resolution, random_state)
    new_mod = __modularity(status)
    partition = __renumber(status.node2com)
    status_list.append(partition)
    mod = new_mod
    current_graph = induced_graph(partition, current_graph, weight)
    status.init(current_graph, weight)

    while True:
        __one_level(current_graph, status, weight, resolution, random_state)
        new_mod = __modularity(status)
        if new_mod - mod < __MIN:
            break
        partition = __renumber(status.node2com)
        status_list.append(partition)
        mod = new_mod
        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)
    return status_list[:]
def generate_dendrogram(graph,
                        part_init=None,
                        weight='weight',
                        resolution=1.,
                        randomize=None,
                        random_state=None):
    """Finds communities in the graph and return the associated dendrogram
	A dendrogram is a tree and each level is a partition of the graph nodes.
	Level 0 is the first partition, which contains the smallest communities,
	and the best is len(dendrogram) - 1. The higher the level is, the bigger
	are the communities.
	"""

    random_state = check_random_state(random_state)

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for i, node in enumerate(graph.nodes()):
            part[node] = i
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()

    __one_level(current_graph, status, weight, resolution, random_state)
    # runs the investigation multiple times until the improvement is smaller than the predefined threshold

    new_mod = __modularity(status)
    # computes the modularity of the graph, based on discovered communities

    partition = __renumber(status.node2com)
    # resets the community indices such that they start with 0 and goes up one by one (instead of random list of numbers between 1 and n that we had)

    status_list.append(partition)
    # appends a set of assigned communities at a certain level of detection to $status_list

    mod = new_mod
    # computes the modularity after the first change in community assignment but on the same graph (not induced graph)

    current_graph = induced_graph(partition, current_graph, weight)
    # createsa new graph based on the former one such that each community becomes a node in this new one.

    status.init(current_graph, weight)
    # updates the $status such that obliterates the former one.

    while True:
        __one_level(current_graph, status, weight, resolution, random_state)
        # runs the investigation multiple times until the improvement is smaller than the predefined threshold

        new_mod = __modularity(status)
        if new_mod - mod < __MIN:
            # check if the new modularity after creating a new graph and assign new communities is improved more than threshold in comparison with the former graph or not
            # this if statement checks the modularity value for two different graphs but the stop condition for $__one_level is for one graph with new community assignment
            break

        partition = __renumber(status.node2com)
        status_list.append(partition)
        mod = new_mod

        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)
    # while loop ends when the new induced graph (with more convoluted and merged communities) is no better than the former step.

    return status_list[:]
def generate_dendrogram(graph, IncFnc, part_init=None, weight='weight'):
    """Find communities in the graph and return the associated dendrogram

    A dendrogram is a tree and each level is a partition of the graph nodes.
    Level 0 is the first partition, which contains the smallest communities,
    and the best is len(dendrogram) - 1. The higher the level is, the bigger
    are the communities


    Parameters
    ----------
    graph : networkx.Graph
        the networkx graph which will be decomposed
    part_init : dict, optional
        the algorithm will start using this partition of the nodes. It's a
        dictionary where keys are their nodes and values the communities
    weight : str, optional
        the key in graph to use as weight. Default to 'weight'


    Returns
    -------
    dendrogram : list of dictionaries
        a list of partitions, ie dictionnaries where keys of the i+1 are the
        values of the i. and where keys of the first are the nodes of graph

    Raises
    ------
    TypeError
        If the graph is not a networkx.Graph

    See Also
    --------
    best_partition

    Notes
    -----
    Uses Louvain's optimization algorithm

    References
    ----------
    .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
    networks. J. Stat. Mech 10008, 1-12(2008).
    .. 2. reference to SIWO paper TODO
    
    Examples
    --------
    >>> G=nx.erdos_renyi_graph(100, 0.01)
    >>> dendo = generate_dendrogram(G)
    >>> for level in range(len(dendo) - 1) :
    >>>     print("partition at level", level,
    >>>           "is", partition_at_level(dendo, level))
    :param weight:
    :type weight:
    """

    if type(graph) != nx.Graph:
        raise TypeError("Bad graph type, use only non directed graph")

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in graph.nodes():
            part[node] = node
        return [part]

    current_graph = graph.copy()
    status = Status()
    status.init(current_graph, weight, part_init)
    status_list = list()

    changed = __one_level(current_graph, IncFnc, status, weight)
    partition = __renumber(status.node2com)

    status_list.append(partition)
    current_graph = induced_graph(partition, current_graph, weight)
    status.init(current_graph, weight)

    while True:
        changed = __one_level(current_graph, IncFnc, status, weight)
        if not changed:
            break
        partition = __renumber(status.node2com)
        status_list.append(partition)

        current_graph = induced_graph(partition, current_graph, weight)
        status.init(current_graph, weight)

    return status_list[:]
Exemple #10
0
def generate_dendrogram(graph,
                        part_init=None,
                        weight='weight',
                        resolution=1.,
                        randomize=False):
    """Find communities in the graph and return the associated dendrogram

    A dendrogram is a tree and each level is a partition of the graph nodes.
    Level 0 is the first partition, which contains the smallest communities,
    and the best is len(dendrogram) - 1. The higher the level is, the bigger
    are the communities


    Parameters
    ----------
    graph : networkx.Graph
        the networkx graph which will be decomposed
    part_init : dict, optional
        the algorithm will start using this partition of the nodes. It's a
        dictionary where keys are their nodes and values the communities
    weight : str, optional
        the key in graph to use as weight. Default to 'weight'
    resolution :  double, optional
        Will change the size of the communities, default to 1.
        represents the time described in
        "Laplacian Dynamics and Multiscale Modular Structure in Networks",
        R. Lambiotte, J.-C. Delvenne, M. Barahona

    Returns
    -------
    dendrogram : list of dictionaries
        a list of partitions, ie dictionnaries where keys of the i+1 are the
        values of the i. and where keys of the first are the nodes of graph

    Raises
    ------
    TypeError
        If the graph is not a networkx.Graph

    See Also
    --------
    best_partition

    Notes
    -----
    Uses Louvain algorithm

    References
    ----------
    .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
    networks. J. Stat. Mech 10008, 1-12(2008).

    Examples
    --------
    >>> G=nx.erdos_renyi_graph(100, 0.01)
    >>> dendo = generate_dendrogram(G)
    >>> for level in range(len(dendo) - 1) :
    >>>     print("partition at level", level,
    >>>           "is", partition_at_level(dendo, level))
    :param weight:
    :type weight:
    """
    if graph.is_directed():
        raise TypeError("Bad graph type, use only non directed graph")

    # special case, when there is no link
    # the best partition is everyone in its community
    if graph.number_of_edges() == 0:
        part = dict([])
        for node in graph.nodes():
            part[node] = node
        return [part]

    current_graph = graph.copy()
    #status = Status()
    #status.init(current_graph, weight, part_init)

    status_list = list()

    posStatus = Status()
    posGraph = nx.Graph()
    posGraph.add_nodes_from(current_graph.nodes)
    posGraph.add_edges_from([(a, b, {
        'weight': c
    }) for (a, b, c) in current_graph.edges.data('weight', default=1)
                             if c > 0])
    posStatus.init(posGraph, weight, part_init)
    #posStatus.list=list()

    negStatus = Status()
    negGraph = nx.Graph()
    negGraph.add_nodes_from(current_graph.nodes)
    negGraph.add_edges_from([(a, b, {
        'weight': -c
    }) for (a, b, c) in current_graph.edges.data('weight', default=-1)
                             if c < 0])
    negStatus.init(negGraph, weight, part_init)
    #negStatus.list = list()
    print(posStatus.total_weight)
    print(negStatus.total_weight)
    print(len(negGraph.nodes()), len(posGraph.nodes()))
    print(len(negGraph.edges()), len(posGraph.edges()))
    #print(negGraph.nodes(),negGraph.edges())
    #print(current_graph.edges.data('weight', default=-1))
    #print(current_graph.edges.data('weight', default=0))

    __one_level(posGraph, negGraph, posStatus, negStatus, weight, resolution,
                randomize)
    #TODO  Edit one_levl function
    posMul = float(posStatus.total_weight /
                   (posStatus.total_weight +
                    negStatus.total_weight))  #Multip by 2 is impactless
    negMul = float(negStatus.total_weight /
                   (posStatus.total_weight +
                    negStatus.total_weight))  #Multip by 2 is impactless
    new_mod = posMul * __modularity(posStatus) - negMul * __modularity(
        negStatus)
    #TODO check modularity works correct

    partition = __renumber(posStatus.node2com)
    status_list.append(partition)
    mod = new_mod
    #current_graph = induced_graph(partition, current_graph, weight)
    #status.init(current_graph, weight)
    posGraph = induced_graph(partition, posGraph, weight)
    posStatus.init(posGraph, weight, part_init)

    negGraph = induced_graph(partition, negGraph, weight)
    negStatus.init(negGraph, weight, part_init)
    print(" WHile ")

    while True:
        print(" WHile ")

        __one_level(posGraph, negGraph, posStatus, negStatus, weight,
                    resolution, randomize)
        #__one_level(current_graph, status, weight, resolution, randomize)
        #new_mod = __modularity(status)
        pos_mod = __modularity(posStatus)
        neg_mod = __modularity(negStatus)
        new_mod = posMul * pos_mod - negMul * neg_mod

        #TODO Sth is not double
        if new_mod - mod < __MIN:
            break
        partition = __renumber(posStatus.node2com)
        status_list.append(partition)
        mod = new_mod
        posGraph = induced_graph(partition, posGraph, weight)
        negGraph = induced_graph(partition, negGraph, weight)
        posStatus.init(posGraph, weight)
        negStatus.init(negGraph, weight)
        print("\n\n\n our modularity: ", mod)
    print("eow WHile ")

    return status_list[:]