4544 lines
209 KiB
HTML
4544 lines
209 KiB
HTML
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Chapter 25. Detecting community structure</title>
|
||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||
<link rel="home" href="index.html" title="igraph Reference Manual">
|
||
<link rel="up" href="index.html" title="igraph Reference Manual">
|
||
<link rel="prev" href="igraph-Separators.html" title="Chapter 24. Vertex separators">
|
||
<link rel="next" href="igraph-Graphlets.html" title="Chapter 26. Graphlets">
|
||
<script type="text/javascript" src="toggle.js"></script><link rel="stylesheet" href="style.css" type="text/css">
|
||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css">
|
||
<link rel="chapter" href="igraph-Introduction.html" title="Chapter 1. Introduction">
|
||
<link rel="chapter" href="igraph-Installation.html" title="Chapter 2. Installation">
|
||
<link rel="chapter" href="igraph-Tutorial.html" title="Chapter 3. Tutorial">
|
||
<link rel="chapter" href="igraph-Basic.html" title="Chapter 4. Basic data types and interface">
|
||
<link rel="chapter" href="igraph-Error.html" title="Chapter 5. Error handling">
|
||
<link rel="chapter" href="igraph-Memory.html" title="Chapter 6. Memory (de)allocation">
|
||
<link rel="chapter" href="igraph-Data-structures.html" title="Chapter 7. Data structure library: vector, matrix, other data types">
|
||
<link rel="chapter" href="igraph-Random.html" title="Chapter 8. Random numbers">
|
||
<link rel="chapter" href="igraph-Iterators.html" title="Chapter 9. Vertex and edge selectors and sequences, iterators">
|
||
<link rel="chapter" href="igraph-Attributes.html" title="Chapter 10. Graph, vertex and edge attributes">
|
||
<link rel="chapter" href="igraph-Generators.html" title="Chapter 11. Deterministic graph generators">
|
||
<link rel="chapter" href="igraph-Games.html" title='Chapter 12. Stochastic graph generators ("games")'>
|
||
<link rel="chapter" href="igraph-Bipartite.html" title="Chapter 13. Bipartite, i.e. two-mode graphs">
|
||
<link rel="chapter" href="igraph-Spatial.html" title="Chapter 14. Spatial graphs">
|
||
<link rel="chapter" href="igraph-Operators.html" title="Chapter 15. Graph operators">
|
||
<link rel="chapter" href="igraph-Visitors.html" title="Chapter 16. Graph visitors">
|
||
<link rel="chapter" href="igraph-Structural.html" title="Chapter 17. Structural properties of graphs">
|
||
<link rel="chapter" href="igraph-Cycles.html" title="Chapter 18. Graph cycles">
|
||
<link rel="chapter" href="igraph-Cliques.html" title="Chapter 19. Cliques and independent vertex sets">
|
||
<link rel="chapter" href="igraph-Motifs.html" title="Chapter 20. Graph motifs, dyad census and triad census">
|
||
<link rel="chapter" href="igraph-Isomorphism.html" title="Chapter 21. Graph isomorphism">
|
||
<link rel="chapter" href="igraph-Coloring.html" title="Chapter 22. Graph coloring">
|
||
<link rel="chapter" href="igraph-Flows.html" title="Chapter 23. Maximum flows, minimum cuts and related measures">
|
||
<link rel="chapter" href="igraph-Separators.html" title="Chapter 24. Vertex separators">
|
||
<link rel="chapter" href="igraph-Community.html" title="Chapter 25. Detecting community structure">
|
||
<link rel="chapter" href="igraph-Graphlets.html" title="Chapter 26. Graphlets">
|
||
<link rel="chapter" href="igraph-HRG.html" title="Chapter 27. Hierarchical random graphs">
|
||
<link rel="chapter" href="igraph-Embedding.html" title="Chapter 28. Embedding of graphs">
|
||
<link rel="chapter" href="igraph-Layout.html" title="Chapter 29. Generating layouts for graph drawing">
|
||
<link rel="chapter" href="igraph-Processes.html" title="Chapter 30. Processes on graphs">
|
||
<link rel="chapter" href="igraph-Foreign.html" title="Chapter 31. Reading and writing graphs from and to files">
|
||
<link rel="chapter" href="igraph-Linalg.html" title="Chapter 32. Using BLAS, LAPACK and ARPACK for igraph matrices and graphs">
|
||
<link rel="chapter" href="igraph-Nongraph.html" title="Chapter 33. Non-graph related functions">
|
||
<link rel="chapter" href="igraph-Advanced.html" title="Chapter 34. Advanced igraph programming">
|
||
<link rel="chapter" href="igraph-Glossary.html" title="Chapter 35. Glossary">
|
||
<link rel="chapter" href="igraph-Licenses.html" title="Chapter 36. Licenses for igraph and this manual">
|
||
<link rel="index" href="ix01.html" title="Index">
|
||
</head>
|
||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||
<div class="navigation-header mb-4" width="100%" summary="Navigation header"><div class="btn-group">
|
||
<a accesskey="p" class="btn btn-light" href="igraph-Separators.html"><i class="fa fa-chevron-left"></i>
|
||
Previous
|
||
</a><a accesskey="h" class="btn btn-light" href="index.html"><i class="fa fa-home"></i>
|
||
Home
|
||
</a><a accesskey="n" class="btn btn-light" href="igraph-Graphlets.html"><i class="fa fa-chevron-right"></i>
|
||
Next
|
||
</a>
|
||
</div></div>
|
||
<div class="chapter">
|
||
<div class="titlepage"><div><div><h1 class="title">
|
||
<a name="igraph-Community"></a>Chapter 25. Detecting community structure</h1></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#common-functions-related-to-community-detection">1. Common functions related to community structure</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#community-detection-based-on-statistical-mechanics">2. Community structure based on statistical mechanics</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#community-structure-based-on-eigenvectors-of-matrices">3. Community structure based on eigenvectors of matrices</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#walktrap-community-structure-based-on-random-walks">4. Walktrap: Community structure based on random walks</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#edge-betweenness-based-community-detection">5. Edge betweenness based community detection</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#community-structure-based-on-the-optimization-of-modularity">6. Community structure based on the optimization of modularity</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#fluid-communities">7. Fluid communities</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#label-propagation">8. Label propagation</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#infomap-algorithm">9. The InfoMAP algorithm</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#voronoi-communities">10. Voronoi communities</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
Community detection is concerned with clustering the vertices of networks
|
||
into tightly connected subgraphs called "communities". The following
|
||
references provide a good introduction to the topic of community detection:
|
||
</p>
|
||
<p>
|
||
S. Fortunato:
|
||
"Community Detection in Graphs".
|
||
Physics Reports 486, no. 3–5 (2010): 75–174.
|
||
<a class="ulink" href="https://doi.org/10.1016/j.physrep.2009.11.002" target="_top">https://doi.org/10.1016/j.physrep.2009.11.002</a>.
|
||
</p>
|
||
<p>
|
||
S. Fortunato and D. Hric:
|
||
"Community Detection in Networks: A User Guide".
|
||
Physics Reports 659 (2016): 1–44.
|
||
<a class="ulink" href="https://doi.org/10.1016/j.physrep.2016.09.002" target="_top">https://doi.org/10.1016/j.physrep.2016.09.002</a>.
|
||
</p>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="common-functions-related-to-community-detection"></a>1. Common functions related to community structure</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_modularity">1.1. <code class="function">igraph_modularity</code> — Calculates the modularity of a graph with respect to some clusters or vertex types.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_modularity_matrix">1.2. <code class="function">igraph_modularity_matrix</code> — Calculates the modularity matrix.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_optimal_modularity">1.3. <code class="function">igraph_community_optimal_modularity</code> — Calculate the community structure with the highest modularity value.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_to_membership">1.4. <code class="function">igraph_community_to_membership</code> — Cut a dendrogram after a given number of merges.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_reindex_membership">1.5. <code class="function">igraph_reindex_membership</code> — Makes the IDs in a membership vector contiguous.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_compare_communities">1.6. <code class="function">igraph_compare_communities</code> — Compares community structures using various metrics.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_split_join_distance">1.7. <code class="function">igraph_split_join_distance</code> — Calculates the split-join distance of two community structures.</a></span></dt>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_modularity"></a>1.1. <code class="function">igraph_modularity</code> — Calculates the modularity of a graph with respect to some clusters or vertex types.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_modularity(const igraph_t *graph,
|
||
const igraph_vector_int_t *membership,
|
||
const igraph_vector_t *weights,
|
||
const igraph_real_t resolution,
|
||
const igraph_bool_t directed,
|
||
igraph_real_t *modularity);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
The modularity of a graph with respect to some clustering of the vertices
|
||
(or assignment of vertex types)
|
||
measures how strongly separated the different clusters are from each
|
||
other compared to a random null model. It is defined as
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">Q = 1/(2m) sum_ij (A_ij - γ k_i k_j / (2m)) δ(c_i,c_j)</code>,
|
||
|
||
</p>
|
||
<p>
|
||
where <code class="constant">m</code> is the number of edges, <code class="literal">A_ij</code> is the adjacency matrix,
|
||
<code class="constant">k_i</code> is the degree of vertex <code class="constant">i</code>, <code class="constant">c_i</code> is the cluster that vertex <code class="constant">i</code> belongs to
|
||
(or its vertex type), <code class="literal">δ(i,j)=1</code> if <code class="literal">i=j</code> and 0 otherwise,
|
||
and the sum goes over all <code class="constant">i</code>, <code class="constant">j</code> pairs of vertices. Note that in this formula,
|
||
the diagonal of the adjacency matrix contains twice the number of self-loops.
|
||
|
||
</p>
|
||
<p>
|
||
The resolution parameter <code class="constant">γ</code> allows weighting the random null model, which
|
||
might be useful when finding partitions with a high modularity. Maximizing modularity
|
||
with higher values of the resolution parameter typically results in more, smaller clusters
|
||
when finding partitions with a high modularity. Lower values typically results in
|
||
fewer, larger clusters. The original definition of modularity is retrieved
|
||
when setting <code class="literal">γ = 1</code>.
|
||
|
||
</p>
|
||
<p>
|
||
Modularity can also be calculated on directed graphs. This only requires a relatively
|
||
modest change,
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">Q = 1/m sum_ij (A_ij - γ k^out_i k^in_j / m) δ(c_i,c_j)</code>,
|
||
|
||
</p>
|
||
<p>
|
||
where <code class="constant">k^out_i</code> is the out-degree of node <code class="constant">i</code> and <code class="constant">k^in_j</code> is the in-degree of node <code class="constant">j</code>.
|
||
|
||
</p>
|
||
<p>
|
||
Modularity on weighted graphs is also meaningful. When taking
|
||
edge weights into account, <code class="constant">A_ij</code> equals the weight of the corresponding edge
|
||
(or 0 if there is no edge), <code class="constant">k_i</code> is the strength (i.e. the weighted degree) of
|
||
vertex <code class="constant">i</code>, with similar counterparts for a directed graph, and <code class="constant">m</code> is the total
|
||
weight of all edges.
|
||
|
||
</p>
|
||
<p>
|
||
Note that the modularity is not well-defined for graphs with no edges.
|
||
igraph returns <code class="constant">NaN</code> for graphs with no edges; see
|
||
<a class="ulink" href="https://github.com/igraph/igraph/issues/1539" target="_top">https://github.com/igraph/igraph/issues/1539</a> for
|
||
a detailed discussion.
|
||
|
||
</p>
|
||
<p>
|
||
For the original definition of modularity, see Newman, M. E. J., and Girvan, M.
|
||
(2004). Finding and evaluating community structure in networks.
|
||
Physical Review E 69, 026113. <a class="ulink" href="https://doi.org/10.1103/PhysRevE.69.026113" target="_top">https://doi.org/10.1103/PhysRevE.69.026113</a>
|
||
|
||
</p>
|
||
<p>
|
||
For the directed definition of modularity, see Leicht, E. A., and Newman, M. E.
|
||
J. (2008). Community Structure in Directed Networks. Physical Review Letters 100,
|
||
118703. <a class="ulink" href="https://doi.org/10.1103/PhysRevLett.100.118703" target="_top">https://doi.org/10.1103/PhysRevLett.100.118703</a>
|
||
|
||
</p>
|
||
<p>
|
||
For the introduction of the resolution parameter <code class="constant">γ</code>, see Reichardt, J., and
|
||
Bornholdt, S. (2006). Statistical mechanics of community detection. Physical
|
||
Review E 74, 016110. <a class="ulink" href="https://doi.org/10.1103/PhysRevE.74.016110" target="_top">https://doi.org/10.1103/PhysRevE.74.016110</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector of integer values which gives the type of each
|
||
vertex, i.e. the cluster to which it belongs.
|
||
It does not have to be consecutive, i.e. empty communities
|
||
are allowed. For better performance, ensure that community
|
||
indices are nonnegative and smaller than the vertex count.
|
||
This can be ensured using <a class="link" href="igraph-Community.html#igraph_reindex_membership" title="1.5. igraph_reindex_membership — Makes the IDs in a membership vector contiguous."><code class="function">igraph_reindex_membership()</code></a>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Weight vector or <code class="constant">NULL</code> if no weights are specified.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>resolution</code></em>:</span></p></td>
|
||
<td><p>
|
||
The resolution parameter <code class="constant">γ</code>. Must not be negative.
|
||
Set it to 1 to use the classical definition of modularity.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>directed</code></em>:</span></p></td>
|
||
<td><p>
|
||
Whether to use the directed or undirected version of modularity.
|
||
Ignored for undirected graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real number, the result will be
|
||
stored here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_modularity_matrix" title="1.2. igraph_modularity_matrix — Calculates the modularity matrix."><code class="function">igraph_modularity_matrix()</code></a>
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|V|+|E|), the number of vertices plus the number
|
||
of edges, assuming that community indices are nonnegative and smaller
|
||
than the vertex count. Otherwise, O(|V| log |V| + |E|).
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_modularity_matrix"></a>1.2. <code class="function">igraph_modularity_matrix</code> — Calculates the modularity matrix.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.3.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_modularity_matrix(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
const igraph_real_t resolution,
|
||
igraph_matrix_t *modmat,
|
||
igraph_bool_t directed);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function returns the modularity matrix, which is defined as
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">B_ij = A_ij - γ k_i k_j / (2m)</code>
|
||
|
||
</p>
|
||
<p>
|
||
for undirected graphs, where <code class="constant">A_ij</code> is the adjacency matrix, <code class="constant">γ</code> is the
|
||
resolution parameter, <code class="constant">k_i</code> is the degree of vertex <code class="constant">i</code>, and <code class="constant">m</code> is the
|
||
number of edges in the graph. When there are no edges, or the weights add up
|
||
to zero, the result is undefined.
|
||
|
||
</p>
|
||
<p>
|
||
For directed graphs the modularity matrix is changed to
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">B_ij = A_ij - γ k^out_i k^in_j / m</code>
|
||
|
||
</p>
|
||
<p>
|
||
where <code class="literal">k^out_i</code> is the out-degree of node <code class="constant">i</code> and <code class="literal">k^in_j</code> is the
|
||
in-degree of node <code class="constant">j</code>.
|
||
|
||
</p>
|
||
<p>
|
||
Note that self-loops in undirected graphs are multiplied by 2 in this
|
||
implementation. If weights are specified, the weighted counterparts of the adjacency
|
||
matrix and degrees are used.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Edge weights, pointer to a vector. If this is a null pointer
|
||
then every edge is assumed to have a weight of 1.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>resolution</code></em>:</span></p></td>
|
||
<td><p>
|
||
The resolution parameter <code class="constant">γ</code>. Must not be negative.
|
||
Default is 1. Lower values favor fewer, larger communities;
|
||
higher values favor more, smaller communities.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modmat</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized matrix in which the modularity
|
||
matrix is stored.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>directed</code></em>:</span></p></td>
|
||
<td><p>
|
||
For directed graphs: if the edges should be treated as
|
||
undirected. For undirected graphs this is ignored.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_modularity" title="1.1. igraph_modularity — Calculates the modularity of a graph with respect to some clusters or vertex types."><code class="function">igraph_modularity()</code></a>
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_optimal_modularity"></a>1.3. <code class="function">igraph_community_optimal_modularity</code> — Calculate the community structure with the highest modularity value.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.4.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_optimal_modularity(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
const igraph_real_t resolution,
|
||
igraph_real_t *modularity,
|
||
igraph_vector_int_t *membership);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function calculates the optimal community structure for a graph, in
|
||
terms of maximal modularity score. Both undirected and directed graphs
|
||
are supported.
|
||
|
||
</p>
|
||
<p>
|
||
The calculation is done by transforming the modularity maximization
|
||
into an integer programming problem, and then calling the GLPK
|
||
library to solve that. Please see Ulrik Brandes et al.: On
|
||
Modularity Clustering, IEEE Transactions on Knowledge and Data
|
||
Engineering 20(2):172-188, 2008
|
||
<a class="ulink" href="https://doi.org/10.1109/TKDE.2007.190689" target="_top">https://doi.org/10.1109/TKDE.2007.190689</a>.
|
||
|
||
</p>
|
||
<p>
|
||
Note that exact modularity optimization is an NP-complete problem, and
|
||
all known algorithms for it have exponential time complexity. This
|
||
means that you probably don't want to run this function on larger
|
||
graphs. Graphs with up to fifty vertices should be fine, graphs
|
||
with a couple of hundred vertices might be possible.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. It may be undirected or directed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Vector giving the weights of the edges. If it is
|
||
<code class="constant">NULL</code> then each edge is supposed to have the same weight.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>resolution</code></em>:</span></p></td>
|
||
<td><p>
|
||
Resolution parameter. Must be greater than or equal to 0.
|
||
Lower values favor fewer, larger communities; higher values favor more,
|
||
smaller communities. Set it to 1 to use the classical definition of
|
||
modularity.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real number, or a null pointer.
|
||
If it is not a null pointer, then a optimal modularity value
|
||
is returned here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector, or a null pointer. If not a
|
||
null pointer, then the membership vector of the optimal
|
||
community structure is stored here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
When GLPK is not available, <code class="constant">IGRAPH_UNIMPLEMENTED</code> is returned.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_modularity" title="1.1. igraph_modularity — Calculates the modularity of a graph with respect to some clusters or vertex types."><code class="function">igraph_modularity()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_fastgreedy" title="6.1. igraph_community_fastgreedy — Finding community structure by greedy optimization of modularity."><code class="function">igraph_community_fastgreedy()</code></a>
|
||
for an algorithm that finds a local optimum in a greedy way.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: exponential in the number of vertices.
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.5.4.12.1"></a><p class="title"><b>Example 25.1. File <code class="code">examples/simple/igraph_community_optimal_modularity.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t graph;
|
||
igraph_vector_int_t membership;
|
||
igraph_real_t modularity;
|
||
<a class="link" href="igraph-Error.html#igraph_error_handler_t" title="2.1. igraph_error_handler_t — The type of error handler functions.">igraph_error_handler_t</a> *handler;
|
||
<a class="link" href="igraph-Error.html#igraph_error_t" title="3.1. igraph_error_t — Return type for functions returning an error code.">igraph_error_t</a> errcode;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&graph, 9, IGRAPH_UNDIRECTED,
|
||
0, 3, 0, 4, 0, 1, 0, 2, 0, 5, 0, 6, 1, 3, 3, 5, 4, 7, 7, 8, 2, 4, 1, 2, 6, 8,
|
||
-1);
|
||
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, 0);
|
||
|
||
<span class="emphasis"><em>/* Temporarily ignore errors so we can check if the functionality is available. */</em></span>
|
||
handler = <span class="strong"><strong><a class="link" href="igraph-Error.html#igraph_set_error_handler" title="5.1.1. igraph_set_error_handler — Sets a new error handler.">igraph_set_error_handler</a></strong></span>(&<a class="link" href="igraph-Error.html#igraph_error_handler_printignore" title="2.4. igraph_error_handler_printignore — Print and ignore errors.">igraph_error_handler_printignore</a>);
|
||
|
||
errcode = <span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_optimal_modularity" title="1.3. igraph_community_optimal_modularity — Calculate the community structure with the highest modularity value.">igraph_community_optimal_modularity</a></strong></span>(&graph, NULL, 1, &modularity, &membership);
|
||
<span class="strong"><strong>if</strong></span> (errcode == IGRAPH_UNIMPLEMENTED) {
|
||
<span class="emphasis"><em>/* igraph was not build with GLPK; functionality unavailable, so we quit */</em></span>
|
||
<span class="strong"><strong>return</strong></span> 77;
|
||
}
|
||
|
||
<span class="emphasis"><em>/* Restore the previous error handler. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Error.html#igraph_set_error_handler" title="5.1.1. igraph_set_error_handler — Sets a new error handler.">igraph_set_error_handler</a></strong></span>(handler);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Highest possible modularity: %g\n", modularity);
|
||
<span class="strong"><strong>printf</strong></span>("Membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_to_membership"></a>1.4. <code class="function">igraph_community_to_membership</code> — Cut a dendrogram after a given number of merges.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.5.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_to_membership(const igraph_matrix_int_t *merges,
|
||
igraph_int_t nodes,
|
||
igraph_int_t steps,
|
||
igraph_vector_int_t *membership,
|
||
igraph_vector_int_t *csize);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function creates a membership vector from a dendrogram whose leaves
|
||
are individual vertices by cutting it at the specified level. It produces
|
||
a membership vector that contains for each vertex its cluster ID, numbered
|
||
from zero. This is the same membership vector format that is produced by
|
||
<a class="link" href="igraph-Structural.html#igraph_connected_components" title="8.2. igraph_connected_components — Calculates the (weakly or strongly) connected components in a graph."><code class="function">igraph_connected_components()</code></a>, as well as all community detection
|
||
functions in igraph.
|
||
|
||
</p>
|
||
<p>
|
||
It takes as input the number of vertices <em class="parameter"><code>n</code></em>, and a <em class="parameter"><code>merges</code></em> matrix
|
||
encoding the dendrogram, in the format produced by hierarchical clustering
|
||
functions such as <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>,
|
||
<a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a> or <a class="link" href="igraph-Community.html#igraph_community_fastgreedy" title="6.1. igraph_community_fastgreedy — Finding community structure by greedy optimization of modularity."><code class="function">igraph_community_fastgreedy()</code></a>.
|
||
The matrix must have two columns and up to <code class="literal">n - 1</code> rows.
|
||
Each row represents merging two dendrogram nodes into their parent node.
|
||
The leaf nodes of the dendrogram are indexed from 0 to <code class="literal">n - 1</code>
|
||
and are identical to the vertices of the graph that is being partitioned
|
||
into communities. Row <code class="constant">i</code> contains the children of dendrogram node
|
||
with index <code class="literal">n + i</code>.
|
||
|
||
</p>
|
||
<p>
|
||
This function performs <em class="parameter"><code>steps</code></em> merge operations as prescribed by
|
||
the <em class="parameter"><code>merges</code></em> matrix and returns the resulting partitioning into
|
||
<code class="literal">n - steps</code> communities.
|
||
|
||
</p>
|
||
<p>
|
||
If <em class="parameter"><code>merges</code></em> is not a complete dendrogram, it is possible to
|
||
take <em class="parameter"><code>steps</code></em> steps if <em class="parameter"><code>steps</code></em> is not bigger than the number
|
||
lines in <em class="parameter"><code>merges</code></em>.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
The two-column matrix containing the merge operations.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>nodes</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of leaf nodes in the dendrogram.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>steps</code></em>:</span></p></td>
|
||
<td><p>
|
||
Integer constant, the number of steps to take.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector, the membership
|
||
results will be stored here, if not <code class="constant">NULL</code>. The vector will be
|
||
resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>csize</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector, or <code class="constant">NULL</code>. If not <code class="constant">NULL</code>
|
||
then the sizes of the components will be stored here, the vector
|
||
will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_fastgreedy" title="6.1. igraph_community_fastgreedy — Finding community structure by greedy optimization of modularity."><code class="function">igraph_community_fastgreedy()</code></a> for community structure detection
|
||
algorithms producing merge matrices in this format;
|
||
<a class="link" href="igraph-Community.html#igraph_le_community_to_membership" title="3.3. igraph_le_community_to_membership — Cut an incomplete dendrogram after a given number of merges, starting with an initial cluster assignment."><code class="function">igraph_le_community_to_membership()</code></a> to perform merges
|
||
starting from a given cluster assignment.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|V|), the number of vertices in the graph.
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_reindex_membership"></a>1.5. <code class="function">igraph_reindex_membership</code> — Makes the IDs in a membership vector contiguous.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.6.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_reindex_membership(
|
||
igraph_vector_int_t *membership,
|
||
igraph_vector_int_t *new_to_old,
|
||
igraph_int_t *nb_clusters);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function reindexes component IDs in a membership vector in a way that
|
||
the new IDs start from zero and go up to <code class="literal">C-1</code>, where <code class="constant">C</code> is the
|
||
number of unique component IDs in the original vector.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector which gives the type of each
|
||
vertex, i.e. the component to which it belongs.
|
||
The vector will be altered in-place.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>new_to_old</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector which will contain the
|
||
old component ID for each new one, or <code class="constant">NULL</code>,
|
||
in which case it is not returned. The vector
|
||
will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>nb_clusters</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an integer for the number of
|
||
distinct clusters. If not <code class="constant">NULL</code>, this will be
|
||
updated to reflect the number of distinct
|
||
clusters found in membership.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: Let n be the length of the membership vector.
|
||
O(n) if cluster indices are within 0..n-1, and O(n log(n)) otherwise.
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_compare_communities"></a>1.6. <code class="function">igraph_compare_communities</code> — Compares community structures using various metrics.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.7.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_compare_communities(const igraph_vector_int_t *comm1,
|
||
const igraph_vector_int_t *comm2, igraph_real_t* result,
|
||
igraph_community_comparison_t method);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
This function assesses the distance between two community structures
|
||
using the variation of information (VI) metric of Meila (2003), the
|
||
normalized mutual information (NMI) of Danon et al (2005), the
|
||
split-join distance of van Dongen (2000), the Rand index of Rand (1971)
|
||
or the adjusted Rand index of Hubert and Arabie (1985).
|
||
|
||
</p>
|
||
<p>
|
||
Some of these measures are defined based on the entropy of a discrete
|
||
random variable associated with a given clustering <code class="constant">C</code> of vertices.
|
||
Let <code class="constant">p_i</code> be the probability that a randomly picked vertex would be part
|
||
of cluster <code class="constant">i</code>. Then the entropy of the clustering is
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">H(C) = - sum_i p_i log p_i</code>
|
||
|
||
</p>
|
||
<p>
|
||
Similarly, we can define the joint entropy of two clusterings <code class="constant">C_1</code> and <code class="constant">C_2</code>
|
||
based on the probability <code class="constant">p_ij</code> that a random vertex is part of cluster <code class="constant">i</code>
|
||
in the first clustering and cluster <code class="constant">j</code> in the second one:
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">H(C_1, C_2) = - sum_ii p_ij log p_ij</code>
|
||
|
||
</p>
|
||
<p>
|
||
The mutual information of <code class="constant">C_1</code> and <code class="constant">C_2</code> is then
|
||
<code class="literal">MI(C_1, C_2) = H(C_1) + H(C_2) - H(C_1, C_2) >= 0 </code>.
|
||
A large mutual information indicates a high overlap between the two clusterings.
|
||
The normalized mutual information, as computed by igraph, is
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">NMI(C_1, C_2) = 2 MI(C_1, C_2) / (H(C_1) + H(C_2))</code>.
|
||
|
||
</p>
|
||
<p>
|
||
It takes its value from the interval (0, 1], with 1 achieved when the two clusterings
|
||
coincide.
|
||
|
||
</p>
|
||
<p>
|
||
The variation of information is defined as
|
||
<code class="literal">VI(C_1, C_2) = [H(C_1) - MI(C_1, C_2)] + [H(C_2) - MI(C_1, C_2)]</code>.
|
||
Lower values of the variation of information indicate a smaller difference between
|
||
the two clusterings, with <code class="literal">VI = 0</code> achieved precisely when they coincide.
|
||
igraph uses natural units for the variation of information, i.e. it uses the
|
||
natural logarithm when computing entropies.
|
||
|
||
</p>
|
||
<p>
|
||
The Rand index is defined as the probability that the two clusterings agree
|
||
about the cluster memberships of a randomly chosen vertex <span class="emphasis"><em>pair.</em></span> All vertex
|
||
pairs are considered, and the two clusterings are considered to be in agreement
|
||
about the memberships of a vertex pair if either the two vertices are in the
|
||
same cluster in both clusterings, or they are in different clusters in both
|
||
clusterings. The Rand index is then the number of vertex pairs in agreement,
|
||
divided by the total number of vertex pairs. A Rand index of zero means that
|
||
the two clusterings disagree about the membership of all vertex pairs, while
|
||
1 means that the two clusterings are identical.
|
||
|
||
</p>
|
||
<p>
|
||
The adjusted Rand index is similar to the Rand index, but it takes into
|
||
account that agreement between the two clusterings may also occur by chance
|
||
even if the two clusterings are chosen completely randomly. The adjusted
|
||
Rand index therefore subtracts the expected fraction of agreements from the
|
||
value of the Rand index, and divides the result by one minus the expected
|
||
fraction of agreements. The maximum value of the adjusted Rand index is
|
||
still 1 (similarly to the Rand index), indicating maximum agreement, but
|
||
the value may be less than zero if there is <span class="emphasis"><em>less</em></span> agreement between the
|
||
two clusterings than what would be expected by chance.
|
||
|
||
</p>
|
||
<p>
|
||
For an explanation of the split-join distance, see <a class="link" href="igraph-Community.html#igraph_split_join_distance" title="1.7. igraph_split_join_distance — Calculates the split-join distance of two community structures."><code class="function">igraph_split_join_distance()</code></a>.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
Meilă M: Comparing clusterings by the variation of information.
|
||
In: Schölkopf B, Warmuth MK (eds.). Learning Theory and Kernel Machines:
|
||
16th Annual Conference on Computational Learning Theory and 7th Kernel
|
||
Workshop, COLT/Kernel 2003, Washington, DC, USA. Lecture Notes in Computer
|
||
Science, vol. 2777, Springer, 2003. ISBN: 978-3-540-40720-1.
|
||
<a class="ulink" href="https://doi.org/10.1007/978-3-540-45167-9_14" target="_top">https://doi.org/10.1007/978-3-540-45167-9_14</a>
|
||
|
||
</p>
|
||
<p>
|
||
Danon L, Diaz-Guilera A, Duch J, Arenas A: Comparing community structure
|
||
identification. J Stat Mech P09008, 2005.
|
||
<a class="ulink" href="https://doi.org/10.1088/1742-5468/2005/09/P09008" target="_top">https://doi.org/10.1088/1742-5468/2005/09/P09008</a>
|
||
|
||
</p>
|
||
<p>
|
||
van Dongen S: Performance criteria for graph clustering and Markov cluster
|
||
experiments. Technical Report INS-R0012, National Research Institute for
|
||
Mathematics and Computer Science in the Netherlands, Amsterdam, May 2000.
|
||
<a class="ulink" href="https://ir.cwi.nl/pub/4461" target="_top">https://ir.cwi.nl/pub/4461</a>
|
||
|
||
</p>
|
||
<p>
|
||
Rand WM: Objective criteria for the evaluation of clustering methods.
|
||
J Am Stat Assoc 66(336):846-850, 1971.
|
||
<a class="ulink" href="https://doi.org/10.2307/2284239" target="_top">https://doi.org/10.2307/2284239</a>
|
||
|
||
</p>
|
||
<p>
|
||
Hubert L and Arabie P: Comparing partitions. Journal of Classification
|
||
2:193-218, 1985.
|
||
<a class="ulink" href="https://doi.org/10.1007/BF01908075" target="_top">https://doi.org/10.1007/BF01908075</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>comm1</code></em>:</span></p></td>
|
||
<td><p>
|
||
the membership vector of the first community structure
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>comm2</code></em>:</span></p></td>
|
||
<td><p>
|
||
the membership vector of the second community structure
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>result</code></em>:</span></p></td>
|
||
<td><p>
|
||
the result is stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>method</code></em>:</span></p></td>
|
||
<td><p>
|
||
the comparison method to use. <code class="constant">IGRAPH_COMMCMP_VI</code>
|
||
selects the variation of information (VI) metric of
|
||
Meila (2003), <code class="constant">IGRAPH_COMMCMP_NMI</code> selects the
|
||
normalized mutual information measure proposed by
|
||
Danon et al (2005), <code class="constant">IGRAPH_COMMCMP_SPLIT_JOIN</code>
|
||
selects the split-join distance of van Dongen (2000),
|
||
<code class="constant">IGRAPH_COMMCMP_RAND</code> selects the unadjusted Rand
|
||
index (1971) and <code class="constant">IGRAPH_COMMCMP_ADJUSTED_RAND</code>
|
||
selects the adjusted Rand index.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_split_join_distance" title="1.7. igraph_split_join_distance — Calculates the split-join distance of two community structures."><code class="function">igraph_split_join_distance()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(n log(n)).
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_split_join_distance"></a>1.7. <code class="function">igraph_split_join_distance</code> — Calculates the split-join distance of two community structures.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.5.8.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_split_join_distance(const igraph_vector_int_t *comm1,
|
||
const igraph_vector_int_t *comm2, igraph_int_t *distance12,
|
||
igraph_int_t *distance21);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
The split-join distance between partitions A and B is the sum of the
|
||
projection distance of A from B and the projection distance of B from
|
||
A. The projection distance is an asymmetric measure and it is defined
|
||
as follows:
|
||
|
||
</p>
|
||
<p>
|
||
First, each set in partition A is evaluated against all sets in partition
|
||
B. For each set in partition A, the best matching set in partition B is
|
||
found and the overlap size is calculated. (Matching is quantified by the
|
||
size of the overlap between the two sets). Then, the maximal overlap sizes
|
||
for each set in A are summed together and subtracted from the number of
|
||
elements in A.
|
||
|
||
</p>
|
||
<p>
|
||
The split-join distance will be returned in two arguments, <code class="constant">distance12</code>
|
||
will contain the projection distance of the first partition from the
|
||
second, while <code class="constant">distance21</code> will be the projection distance of the second
|
||
partition from the first. This makes it easier to detect whether a
|
||
partition is a subpartition of the other, since in this case, the
|
||
corresponding distance will be zero.
|
||
|
||
</p>
|
||
<p>
|
||
Reference:
|
||
|
||
</p>
|
||
<p>
|
||
van Dongen S: Performance criteria for graph clustering and Markov cluster
|
||
experiments. Technical Report INS-R0012, National Research Institute for
|
||
Mathematics and Computer Science in the Netherlands, Amsterdam, May 2000.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>comm1</code></em>:</span></p></td>
|
||
<td><p>
|
||
the membership vector of the first community structure
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>comm2</code></em>:</span></p></td>
|
||
<td><p>
|
||
the membership vector of the second community structure
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>distance12</code></em>:</span></p></td>
|
||
<td><p>
|
||
pointer to an <code class="constant">igraph_int_t</code>, the projection distance
|
||
of the first community structure from the second one will be
|
||
returned here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>distance21</code></em>:</span></p></td>
|
||
<td><p>
|
||
pointer to an <code class="constant">igraph_int_t</code>, the projection distance
|
||
of the second community structure from the first one will be
|
||
returned here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_compare_communities" title="1.6. igraph_compare_communities — Compares community structures using various metrics."><code class="function">igraph_compare_communities()</code></a> with the <code class="constant">IGRAPH_COMMCMP_SPLIT_JOIN</code>
|
||
method if you are not interested in the individual distances but only the sum
|
||
of them.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(n log(n)).
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="community-detection-based-on-statistical-mechanics"></a>2. Community structure based on statistical mechanics</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_spinglass">2.1. <code class="function">igraph_community_spinglass</code> — Community detection based on statistical mechanics.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_spinglass_single">2.2. <code class="function">igraph_community_spinglass_single</code> — Community of a single node based on statistical mechanics.</a></span></dt>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_spinglass"></a>2.1. <code class="function">igraph_community_spinglass</code> — Community detection based on statistical mechanics.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.6.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_spinglass(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_real_t *modularity,
|
||
igraph_real_t *temperature,
|
||
igraph_vector_int_t *membership,
|
||
igraph_vector_int_t *csize,
|
||
igraph_int_t spins,
|
||
igraph_bool_t parupdate,
|
||
igraph_real_t starttemp,
|
||
igraph_real_t stoptemp,
|
||
igraph_real_t coolfact,
|
||
igraph_spincomm_update_t update_rule,
|
||
igraph_real_t gamma,
|
||
igraph_spinglass_implementation_t implementation,
|
||
igraph_real_t gamma_minus);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function implements the community structure detection
|
||
algorithm proposed by Joerg Reichardt and Stefan Bornholdt.
|
||
The algorithm is described in their paper: Statistical Mechanics of
|
||
Community Detection, <a class="ulink" href="http://arxiv.org/abs/cond-mat/0603718" target="_top">http://arxiv.org/abs/cond-mat/0603718</a> .
|
||
|
||
</p>
|
||
<p>
|
||
From version 0.6, igraph also supports an extension to
|
||
the algorithm that allows negative edge weights. This is described
|
||
in V. A. Traag and Jeroen Bruggeman: Community detection in networks
|
||
with positive and negative links, <a class="ulink" href="http://arxiv.org/abs/0811.2329" target="_top">http://arxiv.org/abs/0811.2329</a> .
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph, it may be directed but the direction
|
||
of the edges is ignored by the algorithm.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
The vector giving the edge weights, it may be <code class="constant">NULL</code>,
|
||
in which case all edges are weighted equally. The edge weights
|
||
must be positive unless using the <code class="constant">IGRAPH_SPINCOMM_IMP_NEG</code>
|
||
implementation.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real number, if not <code class="constant">NULL</code> then the
|
||
modularity score of the solution will be stored here. This is the
|
||
gereralized modularity, taking into account the resolution parameter
|
||
<em class="parameter"><code>gamma</code></em>. See <a class="link" href="igraph-Community.html#igraph_modularity" title="1.1. igraph_modularity — Calculates the modularity of a graph with respect to some clusters or vertex types."><code class="function">igraph_modularity()</code></a> for details.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>temperature</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real number, if not <code class="constant">NULL</code> then
|
||
the temperature at the end of the algorithm will be stored
|
||
here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector or <code class="constant">NULL</code>. If
|
||
not <code class="constant">NULL</code> then the result of the clustering will be stored
|
||
here. For each vertex, the number of its cluster is given, with the
|
||
first cluster numbered zero. The vector will be resized as
|
||
needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>csize</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector or <code class="constant">NULL</code>. If not <code class="constant">NULL</code> then the sizes of the clusters will stored here in cluster
|
||
number order. The vector will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>spins</code></em>:</span></p></td>
|
||
<td><p>
|
||
Integer giving the number of spins, i.e. the maximum
|
||
number of clusters. Even if the number of spins is high the number of
|
||
clusters in the result might be small.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>parupdate</code></em>:</span></p></td>
|
||
<td><p>
|
||
A Boolean constant, whether to update all spins in
|
||
parallel. It is not implemented in the <code class="constant">IGRAPH_SPINCOMM_INP_NEG</code>
|
||
implementation.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>starttemp</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number, the temperature at the start. A reasonable
|
||
default is 1.0.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>stoptemp</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number, the algorithm stops at this temperature. A
|
||
reasonable default is 0.01.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>coolfact</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number, the cooling factor for the simulated
|
||
annealing. A reasonable default is 0.99.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>update_rule</code></em>:</span></p></td>
|
||
<td><p>
|
||
The type of the update rule. Possible values: <code class="constant">IGRAPH_SPINCOMM_UPDATE_SIMPLE</code> and <code class="constant">IGRAPH_SPINCOMM_UPDATE_CONFIG</code>. Basically this parameter defines
|
||
the null model based on which the actual clustering is done. If
|
||
this is <code class="constant">IGRAPH_SPINCOMM_UPDATE_SIMPLE</code> then the random graph
|
||
(i.e. G(n,p)), if it is <code class="constant">IGRAPH_SPINCOMM_UPDATE</code> then the
|
||
configuration model is used. The configuration means that the
|
||
baseline for the clustering is a random graph with the same
|
||
degree distribution as the input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>gamma</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number. The gamma parameter of the algorithm,
|
||
acting as a resolution parameter. Smaller values typically lead to
|
||
larger clusters, larger values typically lead to smaller clusters.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>implementation</code></em>:</span></p></td>
|
||
<td><p>
|
||
Constant, chooses between the two
|
||
implementations of the spin-glass algorithm that are included
|
||
in igraph. <code class="constant">IGRAPH_SPINCOMM_IMP_ORIG</code> selects the original
|
||
implementation, this is faster, <code class="constant">IGRAPH_SPINCOMM_INP_NEG</code> selects
|
||
an implementation that allows negative edge weights.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>gamma_minus</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number. Parameter for the <code class="constant">IGRAPH_SPINCOMM_IMP_NEG</code>
|
||
implementation. This acts as a resolution parameter for the negative part
|
||
of the network. Smaller values of <em class="parameter"><code>gamma_minus</code></em> leads to fewer negative
|
||
edges within clusters. If this argument is set to zero, the algorithm
|
||
reduces to a graph coloring algorithm when all edges have negative
|
||
weights, using the number of spins as the number of colors.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_spinglass_single" title="2.2. igraph_community_spinglass_single — Community of a single node based on statistical mechanics."><code class="function">igraph_community_spinglass_single()</code></a> for calculating the community
|
||
of a single vertex.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: TODO.
|
||
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_spinglass_single"></a>2.2. <code class="function">igraph_community_spinglass_single</code> — Community of a single node based on statistical mechanics.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.6.3.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_spinglass_single(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_int_t vertex,
|
||
igraph_vector_int_t *community,
|
||
igraph_real_t *cohesion,
|
||
igraph_real_t *adhesion,
|
||
igraph_real_t *inner_links,
|
||
igraph_real_t *outer_links,
|
||
igraph_int_t spins,
|
||
igraph_spincomm_update_t update_rule,
|
||
igraph_real_t gamma);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function implements the community structure detection
|
||
algorithm proposed by Joerg Reichardt and Stefan Bornholdt. It is
|
||
described in their paper: Statistical Mechanics of
|
||
Community Detection, <a class="ulink" href="http://arxiv.org/abs/cond-mat/0603718" target="_top">http://arxiv.org/abs/cond-mat/0603718</a> .
|
||
|
||
</p>
|
||
<p>
|
||
This function calculates the community of a single vertex without
|
||
calculating all the communities in the graph.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph, it may be directed but the direction
|
||
of the edges is not used in the algorithm.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector with the weights of the edges.
|
||
Alternatively <code class="constant">NULL</code> can be supplied to have the same weight
|
||
for every edge.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>vertex</code></em>:</span></p></td>
|
||
<td><p>
|
||
The vertex ID of the vertex of which this community is
|
||
calculated.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>community</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector, the result, the
|
||
IDs of the vertices in the community of the input vertex will be
|
||
stored here. The vector will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>cohesion</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real variable, if not <code class="constant">NULL</code> the
|
||
cohesion index of the community will be stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>adhesion</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real variable, if not <code class="constant">NULL</code> the
|
||
adhesion index of the community will be stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>inner_links</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real, if not <code class="constant">NULL</code> the
|
||
number of edges within the community (or the sum of their weights)
|
||
is stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>outer_links</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real, if not <code class="constant">NULL</code> the
|
||
number of edges between the community and the rest of the graph
|
||
(or the sum of their weights) will be stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>spins</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of spins to use, this can be higher than
|
||
the actual number of clusters in the network, in which case some
|
||
clusters will contain zero vertices.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>update_rule</code></em>:</span></p></td>
|
||
<td><p>
|
||
The type of the update rule. Possible values: <code class="constant">IGRAPH_SPINCOMM_UPDATE_SIMPLE</code> and <code class="constant">IGRAPH_SPINCOMM_UPDATE_CONFIG</code>. Basically this parameter defined
|
||
the null model based on which the actual clustering is done. If
|
||
this is <code class="constant">IGRAPH_SPINCOMM_UPDATE_SIMPLE</code> then the random graph
|
||
(ie. G(n,p)), if it is <code class="constant">IGRAPH_SPINCOMM_UPDATE</code> then the
|
||
configuration model is used. The configuration means that the
|
||
baseline for the clustering is a random graph with the same
|
||
degree distribution as the input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>gamma</code></em>:</span></p></td>
|
||
<td><p>
|
||
Real number. The gamma parameter of the
|
||
algorithm. This defined the weight of the missing and existing
|
||
links in the quality function for the clustering. The default
|
||
value in the original code was 1.0, which is equal weight to
|
||
missing and existing edges. Smaller values make the existing
|
||
links contibute more to the energy function which is minimized
|
||
in the algorithm. Bigger values make the missing links more
|
||
important. (If my understanding is correct.)
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
igraph_community_spinglass() for the traditional version of the
|
||
algorithm.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: TODO.
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="community-structure-based-on-eigenvectors-of-matrices"></a>3. Community structure based on eigenvectors of matrices</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_leading_eigenvector">3.1. <code class="function">igraph_community_leading_eigenvector</code> — Leading eigenvector community finding (proper version).</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_leading_eigenvector_callback_t">3.2. <code class="function">igraph_community_leading_eigenvector_callback_t</code> — Callback for the leading eigenvector community finding method.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_le_community_to_membership">3.3. <code class="function">igraph_le_community_to_membership</code> — Cut an incomplete dendrogram after a given number of merges, starting with an initial cluster assignment.</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
The function documented in these section implements the
|
||
<span class="quote">“<span class="quote">leading eigenvector</span>”</span> method developed by Mark Newman and
|
||
published in MEJ Newman: Finding community structure using the
|
||
eigenvectors of matrices, Phys Rev E 74:036104 (2006).</p>
|
||
<p>
|
||
The heart of the method is the definition of the modularity matrix
|
||
<code class="literal">B = A - P</code>, <code class="constant">A</code> being the adjacency matrix of the (undirected)
|
||
network, and <code class="constant">P</code> contains the probability that certain edges are
|
||
present according to the <span class="quote">“<span class="quote">configuration model</span>”</span>. In
|
||
other words, a <code class="constant">P_ij</code> element of <code class="constant">P</code> is the probability that there is an
|
||
edge between vertices <code class="constant">i</code> and <code class="constant">j</code> in a random network in which the
|
||
degrees of all vertices are the same as in the input graph. See
|
||
<a class="link" href="igraph-Community.html#igraph_modularity_matrix" title="1.2. igraph_modularity_matrix — Calculates the modularity matrix."><code class="function">igraph_modularity_matrix()</code></a> for more details.</p>
|
||
<p>
|
||
The leading eigenvector method works by calculating the eigenvector
|
||
of the modularity matrix for the largest positive eigenvalue and
|
||
then separating vertices into two community based on the sign of
|
||
the corresponding element in the eigenvector. If all elements in
|
||
the eigenvector are of the same sign that means that the network
|
||
has no underlying community structure.
|
||
Check Newman's paper to understand why this is a good method for
|
||
detecting community structure. </p>
|
||
<p>
|
||
The leading eigenvector community structure detection method is
|
||
implemented in <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version)."><code class="function">igraph_community_leading_eigenvector()</code></a>. After
|
||
the initial split, the following splits are done in a way to
|
||
optimize modularity regarding to the original network. Note that
|
||
any further refinement, for example using Kernighan-Lin, as
|
||
proposed in Section V.A of Newman (2006), is not implemented here.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.7.6.1"></a><p class="title"><b>Example 25.2. File <code class="code">examples/simple/igraph_community_leading_eigenvector.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
<span class="strong"><strong>#include</strong></span> <stdio.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
|
||
igraph_t g;
|
||
igraph_matrix_int_t merges;
|
||
igraph_vector_int_t membership;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="emphasis"><em>/* Zachary Karate club */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&g, 0, IGRAPH_UNDIRECTED,
|
||
0, 1, 0, 2, 0, 3, 0, 4, 0, 5,
|
||
0, 6, 0, 7, 0, 8, 0, 10, 0, 11,
|
||
0, 12, 0, 13, 0, 17, 0, 19, 0, 21,
|
||
0, 31, 1, 2, 1, 3, 1, 7, 1, 13,
|
||
1, 17, 1, 19, 1, 21, 1, 30, 2, 3,
|
||
2, 7, 2, 8, 2, 9, 2, 13, 2, 27,
|
||
2, 28, 2, 32, 3, 7, 3, 12, 3, 13,
|
||
4, 6, 4, 10, 5, 6, 5, 10, 5, 16,
|
||
6, 16, 8, 30, 8, 32, 8, 33, 9, 33,
|
||
13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
|
||
18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
|
||
22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
|
||
23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
|
||
25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
|
||
28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
|
||
31, 32, 31, 33, 32, 33,
|
||
-1);
|
||
|
||
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&merges, 0, 0);
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, 0);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version).">igraph_community_leading_eigenvector</a></strong></span>(&g, <span class="emphasis"><em>/*weights=*/</em></span> NULL,
|
||
&merges, &membership,
|
||
<span class="emphasis"><em>/*steps=*/</em></span> 1,
|
||
<span class="emphasis"><em>/*options=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*modularity=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*start=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*eigenvalues=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*eigenvectors=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*history=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*callback=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*callback_extra=*/</em></span> NULL);
|
||
|
||
<span class="strong"><strong>igraph_matrix_int_print</strong></span>(&merges);
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("\n");
|
||
|
||
<span class="emphasis"><em>/* Make all the steps */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version).">igraph_community_leading_eigenvector</a></strong></span>(&g, <span class="emphasis"><em>/*weights=*/</em></span> NULL,
|
||
&merges, &membership,
|
||
<span class="emphasis"><em>/*steps=*/</em></span> <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&g),
|
||
<span class="emphasis"><em>/*options=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*modularity=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*start=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*eigenvalues=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*eigenvectors=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*history=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*callback=*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*callback_extra=*/</em></span> NULL);
|
||
|
||
<span class="strong"><strong>igraph_matrix_int_print</strong></span>(&merges);
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&merges);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&g);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_leading_eigenvector"></a>3.1. <code class="function">igraph_community_leading_eigenvector</code> — Leading eigenvector community finding (proper version).</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.7.7.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_leading_eigenvector(
|
||
const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_matrix_int_t *merges,
|
||
igraph_vector_int_t *membership,
|
||
igraph_int_t steps,
|
||
igraph_arpack_options_t *options,
|
||
igraph_real_t *modularity,
|
||
igraph_bool_t start,
|
||
igraph_vector_t *eigenvalues,
|
||
igraph_vector_list_t *eigenvectors,
|
||
igraph_vector_int_t *history,
|
||
igraph_community_leading_eigenvector_callback_t *callback,
|
||
void *callback_extra);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
Newman's leading eigenvector method for detecting community
|
||
structure. This is the proper implementation of the recursive,
|
||
divisive algorithm: each split is done by maximizing the modularity
|
||
regarding the original network, see MEJ Newman: Finding community
|
||
structure in networks using the eigenvectors of matrices,
|
||
Phys Rev E 74:036104 (2006).
|
||
<a class="ulink" href="https://doi.org/10.1103/PhysRevE.74.036104" target="_top">https://doi.org/10.1103/PhysRevE.74.036104</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. Edge directions will be ignored.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
The weights of the edges, or <code class="constant">NULL</code> for unweighted graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
The result of the algorithm, a matrix containing the
|
||
information about the splits performed. The matrix is built in
|
||
the opposite way however, it is like the result of an
|
||
agglomerative algorithm. Unlike with most other hierarchical
|
||
community detection functions in igraph, the integers in this matrix
|
||
represent community indices, not vertex indices. If at the end of
|
||
the algorithm (after <em class="parameter"><code>steps</code></em> steps was done) there are <span class="quote">“<span class="quote">p</span>”</span>
|
||
communities, then these are numbered from zero to <code class="literal">p-1</code>.
|
||
The first line of the matrix contains the first <span class="quote">“<span class="quote">merge</span>”</span>
|
||
(which is in reality the last split) of two communities into
|
||
community <code class="literal">p</code>, the merge in the second line forms
|
||
community <code class="literal">p+1</code>, etc. The matrix should be
|
||
initialized before calling and will be resized as needed.
|
||
This argument is ignored if it is <code class="constant">NULL</code>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The membership of the vertices after all the
|
||
splits were performed will be stored here. The vector must be
|
||
initialized before calling and will be resized as needed.
|
||
This argument is ignored if it is <code class="constant">NULL</code>. This argument can
|
||
also be used to supply a starting configuration for the community
|
||
finding, in the format of a membership vector. In this case the
|
||
<em class="parameter"><code>start</code></em> argument must be set to <code class="constant">true</code>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>steps</code></em>:</span></p></td>
|
||
<td><p>
|
||
The maximum number of steps to perform. It might
|
||
happen that some component (or the whole network) has no
|
||
underlying community structure and no further steps can be
|
||
done. If you want as many steps as possible then supply the
|
||
number of vertices in the network here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>options</code></em>:</span></p></td>
|
||
<td><p>
|
||
The options for ARPACK. Supply <code class="constant">NULL</code> here to use the
|
||
defaults. <code class="constant">n</code> is always overwritten. <code class="constant">ncv</code> is set to at least 4.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then it must be a pointer
|
||
to a real number and the modularity score of the final division
|
||
is stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>start</code></em>:</span></p></td>
|
||
<td><p>
|
||
Boolean, whether to use the community structure given
|
||
in the <em class="parameter"><code>membership</code></em> argument as a starting point.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>eigenvalues</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector or a null
|
||
pointer. If not a null pointer, then the eigenvalues calculated
|
||
along the community structure detection are stored here. The
|
||
non-positive eigenvalues, that do not result a split, are stored
|
||
as well.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>eigenvectors</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then the eigenvectors
|
||
that are calculated in each step of the algorithm are stored here,
|
||
in a list of vectors. Each eigenvector is stored in an
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects"><code class="function">igraph_vector_t</code></a> object.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>history</code></em>:</span></p></td>
|
||
<td>
|
||
<p>
|
||
Pointer to an initialized vector or a null pointer.
|
||
If not a null pointer, then a trace of the algorithm is stored
|
||
here, encoded numerically. The various operations:
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEVC_HIST_START_FULL</code></span></p></td>
|
||
<td><p>
|
||
|
||
Start the algorithm from an initial state where each connected
|
||
component is a separate community.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEVC_HIST_START_GIVEN</code></span></p></td>
|
||
<td><p>
|
||
|
||
Start the algorithm from a given community structure. The next
|
||
value in the vector contains the initial number of
|
||
communities.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEVC_HIST_SPLIT</code></span></p></td>
|
||
<td><p>
|
||
|
||
Split a community into two communities. The id of the splitted
|
||
community is given in the next element of the history vector.
|
||
The id of the first new community is the same as the id of the
|
||
splitted community. The id of the second community equals to
|
||
the number of communities before the split.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEVC_HIST_FAILED</code></span></p></td>
|
||
<td><p>
|
||
|
||
Tried to split a community, but it was not worth it, as it
|
||
does not result in a bigger modularity value. The id of the
|
||
community is given in the next element of the vector.
|
||
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>callback</code></em>:</span></p></td>
|
||
<td><p>
|
||
A null pointer or a function of type <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector_callback_t" title="3.2. igraph_community_leading_eigenvector_callback_t — Callback for the leading eigenvector community finding method."><code class="function">igraph_community_leading_eigenvector_callback_t</code></a>. If given, this
|
||
callback function is called after each eigenvector/eigenvalue
|
||
calculation. If the callback returns <code class="constant">IGRAPH_STOP</code>, then the
|
||
community finding algorithm stops. If it returns <code class="constant">IGRAPH_SUCCESS</code>,
|
||
the algorithm continues normally. Any other return value is considered
|
||
an igraph error code and will terminete the algorithm with the same
|
||
error code. See the arguments passed to the callback at the documentation
|
||
of <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector_callback_t" title="3.2. igraph_community_leading_eigenvector_callback_t — Callback for the leading eigenvector community finding method."><code class="function">igraph_community_leading_eigenvector_callback_t</code></a>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>callback_extra</code></em>:</span></p></td>
|
||
<td><p>
|
||
Extra argument to pass to the callback
|
||
function.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a> and <a class="link" href="igraph-Community.html#igraph_community_spinglass" title="2.1. igraph_community_spinglass — Community detection based on statistical mechanics."><code class="function">igraph_community_spinglass()</code></a> for other community structure
|
||
detection methods.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|E|+|V|^2*steps), |V| is the number of vertices,
|
||
|E| the number of edges, <span class="quote">“<span class="quote">steps</span>”</span> the number of splits
|
||
performed.
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_leading_eigenvector_callback_t"></a>3.2. <code class="function">igraph_community_leading_eigenvector_callback_t</code> — Callback for the leading eigenvector community finding method.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.7.8.2"></a><pre class="programlisting">
|
||
typedef igraph_error_t igraph_community_leading_eigenvector_callback_t(
|
||
const igraph_vector_int_t *membership,
|
||
igraph_int_t comm,
|
||
igraph_real_t eigenvalue,
|
||
const igraph_vector_t *eigenvector,
|
||
igraph_arpack_function_t *arpack_multiplier,
|
||
void *arpack_extra,
|
||
void *extra);
|
||
</pre>
|
||
<p>
|
||
|
||
|
||
The leading eigenvector community finding implementation in igraph
|
||
is able to call a callback function, after each eigenvalue
|
||
calculation. This callback function must be of <code class="constant">igraph_community_leading_eigenvector_callback_t</code> type.
|
||
The following arguments are passed to the callback:
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The actual membership vector, before recording
|
||
the potential change implied by the newly found eigenvalue.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>comm</code></em>:</span></p></td>
|
||
<td><p>
|
||
The id of the community that the algorithm tried to
|
||
split in the last iteration. The community IDs are indexed from
|
||
zero here!
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>eigenvalue</code></em>:</span></p></td>
|
||
<td><p>
|
||
The eigenvalue the algorithm has just found.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>eigenvector</code></em>:</span></p></td>
|
||
<td><p>
|
||
The eigenvector corresponding to the eigenvalue
|
||
the algorithm just found.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>arpack_multiplier</code></em>:</span></p></td>
|
||
<td><p>
|
||
A function that was passed to <a class="link" href="igraph-Linalg.html#igraph_arpack_rssolve" title="3.2.1. igraph_arpack_rssolve — ARPACK solver for symmetric matrices."><code class="function">igraph_arpack_rssolve()</code></a> to solve the last eigenproblem.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>arpack_extra</code></em>:</span></p></td>
|
||
<td><p>
|
||
The extra argument that was passed to the
|
||
ARPACK solver.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>extra</code></em>:</span></p></td>
|
||
<td><p>
|
||
Extra argument that as passed to <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version)."><code class="function">igraph_community_leading_eigenvector()</code></a>.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version)."><code class="function">igraph_community_leading_eigenvector()</code></a>, <a class="link" href="igraph-Linalg.html#igraph_arpack_function_t" title="3.1.3. igraph_arpack_function_t — Type of the ARPACK callback function."><code class="function">igraph_arpack_function_t</code></a>, <a class="link" href="igraph-Linalg.html#igraph_arpack_rssolve" title="3.2.1. igraph_arpack_rssolve — ARPACK solver for symmetric matrices."><code class="function">igraph_arpack_rssolve()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_le_community_to_membership"></a>3.3. <code class="function">igraph_le_community_to_membership</code> — Cut an incomplete dendrogram after a given number of merges, starting with an initial cluster assignment.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.7.9.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_le_community_to_membership(const igraph_matrix_int_t *merges,
|
||
igraph_int_t steps,
|
||
igraph_vector_int_t *membership,
|
||
igraph_vector_int_t *csize);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function takes a dendrogram whose leaves are cluster IDs given in an
|
||
initial cluster assignment provided in <em class="parameter"><code>membership</code></em>. Then it updates
|
||
the cluster assignment by performing the specified number of mergers,
|
||
as given by the dendrogram encoded in <em class="parameter"><code>merges</code></em>. It is a more general
|
||
version of <a class="link" href="igraph-Community.html#igraph_community_to_membership" title="1.4. igraph_community_to_membership — Cut a dendrogram after a given number of merges."><code class="function">igraph_community_to_membership()</code></a>, which assumes that
|
||
the dendrogram leaves are singleton clusters corresponding to individual
|
||
vertices.
|
||
|
||
</p>
|
||
<p>
|
||
This dendrogram format is suitable for divise hierarchical community
|
||
detection algorithms that stop before dividing the graph into individual
|
||
vertices, such as <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version)."><code class="function">igraph_community_leading_eigenvector()</code></a>.
|
||
|
||
</p>
|
||
<p>
|
||
Initially, <em class="parameter"><code>membership</code></em> is expected to contain <code class="constant">m</code> contiguous cluster
|
||
indices, numbered from zero. These correspond to the leaf nodes of the
|
||
dendrogram. Row <code class="constant">i</code> of the two-column <em class="parameter"><code>merges</code></em> matrix contains the IDs of
|
||
clusters that are merged together into dendrogram node <code class="literal">m + i</code>.
|
||
It may have up to <code class="literal">m - 1</code> rows.
|
||
|
||
</p>
|
||
<p>
|
||
This function performs <em class="parameter"><code>steps</code></em> merge operations as prescribed by the
|
||
<em class="parameter"><code>merges</code></em> matrix and updates <em class="parameter"><code>membership</code></em> to the resulting partitioning
|
||
into <code class="literal">m - steps</code> communities.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
The two-column matrix containing the merge operations.
|
||
See <a class="link" href="igraph-Community.html#igraph_community_leading_eigenvector" title="3.1. igraph_community_leading_eigenvector — Leading eigenvector community finding (proper version)."><code class="function">igraph_community_leading_eigenvector()</code></a> for the
|
||
detailed syntax. This is usually from the output of the
|
||
leading eigenvector community structure detection routines.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>steps</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of steps to make according to <code class="constant">merges</code>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Initially the starting membership vector,
|
||
on output the resulting membership vector, after performing <code class="constant">steps</code> merges.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>csize</code></em>:</span></p></td>
|
||
<td><p>
|
||
Optionally the sizes of the communities are stored here,
|
||
if this is not a null pointer, but an initialized vector.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_to_membership" title="1.4. igraph_community_to_membership — Cut a dendrogram after a given number of merges."><code class="function">igraph_community_to_membership()</code></a> for a simpler interface that
|
||
starts by merging individual vertices.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|V|), the number of vertices.
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="walktrap-community-structure-based-on-random-walks"></a>4. Walktrap: Community structure based on random walks</h2></div></div></div>
|
||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="igraph-Community.html#igraph_community_walktrap">4.1. <code class="function">igraph_community_walktrap</code> — Community finding using a random walk based similarity measure.</a></span></dt></dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_walktrap"></a>4.1. <code class="function">igraph_community_walktrap</code> — Community finding using a random walk based similarity measure.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.8.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_walktrap(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_int_t steps,
|
||
igraph_matrix_int_t *merges,
|
||
igraph_vector_t *modularity,
|
||
igraph_vector_int_t *membership);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function is the implementation of the Walktrap community
|
||
finding algorithm, see Pascal Pons, Matthieu Latapy: Computing
|
||
communities in large networks using random walks,
|
||
<a class="ulink" href="https://arxiv.org/abs/physics/0512106" target="_top">https://arxiv.org/abs/physics/0512106</a>
|
||
|
||
</p>
|
||
<p>
|
||
Currently the original C++ implementation is used in igraph,
|
||
see <a class="ulink" href="https://www-complexnetworks.lip6.fr/~latapy/PP/walktrap.html" target="_top">https://www-complexnetworks.lip6.fr/~latapy/PP/walktrap.html</a>
|
||
We are grateful to Matthieu Latapy and Pascal Pons for providing this
|
||
source code.
|
||
|
||
</p>
|
||
<p>
|
||
In contrast to the original implementation, isolated vertices are allowed
|
||
in the graph and they are assumed to have a single incident loop edge with
|
||
weight 1.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph, edge directions are ignored.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector giving the weights of the edges.
|
||
If it is a NULL pointer then all edges will have equal
|
||
weights. The weights are expected to be positive.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>steps</code></em>:</span></p></td>
|
||
<td><p>
|
||
Integer constant, the length of the random walks.
|
||
Typically, good results are obtained with values between
|
||
3-8 with 4-5 being a reasonable default.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a matrix, the merges performed by the
|
||
algorithm will be stored here (if not <code class="constant">NULL</code>). Each merge is a
|
||
row in a two-column matrix and contains the IDs of the merged
|
||
clusters. Clusters are numbered from zero and cluster numbers
|
||
smaller than the number of nodes in the network belong to the
|
||
individual vertices as singleton clusters. In each step a new
|
||
cluster is created from two other clusters and its id will be
|
||
one larger than the largest cluster id so far. This means that
|
||
before the first merge we have <code class="constant">n</code> clusters (the number of
|
||
vertices in the graph) numbered from zero to <code class="literal">n - 1</code>.
|
||
The first merge creates cluster <code class="constant">n</code>, the second cluster
|
||
<code class="literal">n + 1</code>, etc.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector. If not <code class="constant">NULL</code> then the
|
||
modularity score of the current clustering is stored here after
|
||
each merge operation.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector. If not a <code class="constant">NULL</code> pointer, then
|
||
the membership vector corresponding to the maximal modularity
|
||
score is stored here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_spinglass" title="2.1. igraph_community_spinglass — Community detection based on statistical mechanics."><code class="function">igraph_community_spinglass()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|E||V|^2) in the worst case, O(|V|^2 log|V|) typically,
|
||
|V| is the number of vertices, |E| is the number of edges.
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.8.2.12.1"></a><p class="title"><b>Example 25.3. File <code class="code">examples/simple/walktrap.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t g;
|
||
igraph_matrix_int_t merges;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> modularity;
|
||
igraph_int_t no_of_nodes;
|
||
igraph_int_t i;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&g, 5, IGRAPH_UNDIRECTED,
|
||
0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4,
|
||
5, 6, 5, 7, 5, 8, 5, 9, 6, 7, 6, 8, 6, 9, 7, 8, 7, 9, 8, 9, 0, 5, 4, 9, -1);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&modularity, 0);
|
||
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&merges, 0, 0);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure.">igraph_community_walktrap</a></strong></span>(&g,
|
||
NULL <span class="emphasis"><em>/* no weights */</em></span>,
|
||
4 <span class="emphasis"><em>/* steps */</em></span>,
|
||
&merges, &modularity,
|
||
<span class="emphasis"><em>/* membership=*/</em></span> NULL);
|
||
|
||
no_of_nodes = <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&g);
|
||
<span class="strong"><strong>printf</strong></span>("Merges:\n");
|
||
<span class="strong"><strong>for</strong></span> (i = 0; i < <span class="strong"><strong>igraph_matrix_int_nrow</strong></span>(&merges); i++) {
|
||
<span class="strong"><strong>printf</strong></span>("%2.1" IGRAPH_PRId " + %2." IGRAPH_PRId " -> %2." IGRAPH_PRId " (modularity %4.2f)\n",
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#MATRIX" title="3.4.1. MATRIX — Accessing an element of a matrix.">MATRIX</a></strong></span>(merges, i, 0), <span class="strong"><strong><a class="link" href="igraph-Data-structures.html#MATRIX" title="3.4.1. MATRIX — Accessing an element of a matrix.">MATRIX</a></strong></span>(merges, i, 1),
|
||
no_of_nodes + i, <span class="strong"><strong><a class="link" href="igraph-Data-structures.html#VECTOR" title="2.4.1. VECTOR — Accessing an element of a vector.">VECTOR</a></strong></span>(modularity)[i]);
|
||
}
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&g);
|
||
|
||
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&merges);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&modularity);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="edge-betweenness-based-community-detection"></a>5. Edge betweenness based community detection</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_edge_betweenness">5.1. <code class="function">igraph_community_edge_betweenness</code> — Community finding based on edge betweenness.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_eb_get_merges">5.2. <code class="function">igraph_community_eb_get_merges</code> — Calculating the merges, i.e. the dendrogram for an edge betweenness community structure.</a></span></dt>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_edge_betweenness"></a>5.1. <code class="function">igraph_community_edge_betweenness</code> — Community finding based on edge betweenness.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.9.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_edge_betweenness(const igraph_t *graph,
|
||
igraph_vector_int_t *removed_edges,
|
||
igraph_vector_t *edge_betweenness,
|
||
igraph_matrix_int_t *merges,
|
||
igraph_vector_int_t *bridges,
|
||
igraph_vector_t *modularity,
|
||
igraph_vector_int_t *membership,
|
||
igraph_bool_t directed,
|
||
const igraph_vector_t *weights,
|
||
const igraph_vector_t *lengths);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
Community structure detection based on the betweenness of the edges
|
||
in the network. This method is also known as the Girvan-Newman
|
||
algorithm.
|
||
|
||
</p>
|
||
<p>
|
||
The idea behind this method is that the betweenness of the edges connecting
|
||
two communities is typically high, as many of the shortest paths between
|
||
vertices in separate communities pass through them. The algorithm
|
||
successively removes edges with the highest betweenness, recalculating
|
||
betweenness values after each removal. This way eventually the network splits
|
||
into two components, then one of these components splits again, and so on,
|
||
until all edges are removed. The resulting hierarhical partitioning of the
|
||
vertices can be encoded as a dendrogram.
|
||
|
||
</p>
|
||
<p>
|
||
In directed graphs, when <em class="parameter"><code>directed</code></em> is set to true, the directed version
|
||
of betweenness and modularity are used, however, only splits into
|
||
<span class="emphasis"><em>weakly</em></span> connected components are detected.
|
||
|
||
</p>
|
||
<p>
|
||
When edge weights are given, the ratio of betweenness and weight values
|
||
is used to choose which edges to remove first, as described in
|
||
M. E. J. Newman: Analysis of Weighted Networks (2004), Section C.
|
||
Thus, edges with large weights are treated as strong connections,
|
||
and will be removed later than weak connections having similar betweenness.
|
||
Weights are also used for calculating modularity.
|
||
|
||
</p>
|
||
<p>
|
||
If lengths are given, they will be considered for shortest path length
|
||
calculations while computing betweenness values.
|
||
|
||
</p>
|
||
<p>
|
||
Note: In igraph 0.10, this function interpreted weights in a different,
|
||
erroneous way, and issued a warning when weights were used. Please
|
||
see <a class="ulink" href="https://github.com/igraph/igraph/issues/2229" target="_top">https://github.com/igraph/igraph/issues/2229</a> for additional details.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
M. Girvan and M. E. J. Newman,
|
||
Community Structure in Social and Biological Networks, PNAS 99, 7821 (2002).
|
||
<a class="ulink" href="https://doi.org/10.1073/pnas.122653799" target="_top">https://doi.org/10.1073/pnas.122653799</a>
|
||
|
||
</p>
|
||
<p>
|
||
M. E. J. Newman,
|
||
Analysis of Weighted Networks, Phys. Rev. E 70, 9 (2004).
|
||
<a class="ulink" href="https://doi.org/10.1103/PhysRevE.70.056131" target="_top">https://doi.org/10.1103/PhysRevE.70.056131</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>removed_edges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized integer vector, which will
|
||
be resized as needed. The IDs of the removed edges in the order of their
|
||
removal will be stored here. This vector is suitable as input to
|
||
<a class="link" href="igraph-Community.html#igraph_community_eb_get_merges" title="5.2. igraph_community_eb_get_merges — Calculating the merges, i.e. the dendrogram for an edge betweenness community structure."><code class="function">igraph_community_eb_get_merges()</code></a>. This parameter may be <code class="constant">NULL</code> if
|
||
the edge IDs are not needed by the caller.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>edge_betweenness</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector or
|
||
<code class="constant">NULL</code>. In the former case the edge betweenness of the removed
|
||
edges is stored here. The vector will be resized as needed.
|
||
Note that the betweenness values stored here are <span class="emphasis"><em>not</em></span> divided
|
||
by weights.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized matrix or <code class="constant">NULL</code>. If not <code class="constant">NULL</code>
|
||
then merges performed by the algorithm are stored here. Even if
|
||
this is a divisive algorithm, we can replay it backwards and
|
||
note which two clusters were merged. Clusters are numbered from
|
||
zero. See <a class="link" href="igraph-Community.html#igraph_community_to_membership" title="1.4. igraph_community_to_membership — Cut a dendrogram after a given number of merges."><code class="function">igraph_community_to_membership()</code></a> for details. The
|
||
matrix will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>bridges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector of <code class="constant">NULL</code>. If not
|
||
<code class="constant">NULL</code> then the indices into <em class="parameter"><code>result</code></em> of all edges which caused
|
||
one of the <em class="parameter"><code>merges</code></em> will be put here. This is equivalent to all edge removals
|
||
which separated the network into more components, in reverse order.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then the modularity values
|
||
of the different divisions are stored here, in the order
|
||
corresponding to the merge matrix. The modularity values will
|
||
take weights into account if <em class="parameter"><code>weights</code></em> is not null.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then the membership vector,
|
||
corresponding to the highest modularity value, is stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>directed</code></em>:</span></p></td>
|
||
<td><p>
|
||
Boolean constant. Controls whether to calculate directed
|
||
betweenness (i.e. directed paths) for directed graphs, and whether
|
||
to use the directed version of modularity. It is ignored for undirected
|
||
graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
An optional vector containing edge weights. If not <code class="constant">NULL</code>,
|
||
the weights will be used to divide the edge betweenness scores,
|
||
as well as for the calculation of modularity.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>lengths</code></em>:</span></p></td>
|
||
<td><p>
|
||
An optional vector containing edge lengths. If not <code class="constant">NULL</code>,
|
||
path lengths used in the betweenness calculation will take these
|
||
lengths into account.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_eb_get_merges" title="5.2. igraph_community_eb_get_merges — Calculating the merges, i.e. the dendrogram for an edge betweenness community structure."><code class="function">igraph_community_eb_get_merges()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_spinglass" title="2.1. igraph_community_spinglass — Community detection based on statistical mechanics."><code class="function">igraph_community_spinglass()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|V||E|^2), as the betweenness calculation requires
|
||
O(|V||E|) and we do it |E|-1 times.
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.9.2.18.1"></a><p class="title"><b>Example 25.4. File <code class="code">examples/simple/igraph_community_edge_betweenness.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t graph;
|
||
igraph_vector_int_t edges;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> eb, weights;
|
||
igraph_matrix_int_t merges;
|
||
igraph_vector_int_t bridges;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&graph, 5, IGRAPH_UNDIRECTED,
|
||
0, 1, 1, 2, 0, 2, 0, 3, 1, 3, 1, 4,
|
||
-1);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init_range" title="2.2.4. igraph_vector_init_range — Initializes a vector with a range.">igraph_vector_init_range</a></strong></span>(&weights, 1, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_ecount" title="5.2.2. igraph_ecount — The number of edges in a graph.">igraph_ecount</a></strong></span>(&graph)+1);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&eb, 0);
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&edges, 0);
|
||
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&merges, 0, 0);
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&bridges, 0);
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness.">igraph_community_edge_betweenness</a></strong></span>(&graph, &edges, &eb, &merges,
|
||
&bridges, <span class="emphasis"><em>/*modularity*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*membership*/</em></span> NULL,
|
||
IGRAPH_UNDIRECTED,
|
||
&weights,
|
||
NULL);
|
||
<span class="strong"><strong>printf</strong></span>("edges:\n");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&edges);
|
||
<span class="strong"><strong>printf</strong></span>("edge betweenness:\n");
|
||
<span class="strong"><strong>igraph_vector_print</strong></span>(&eb);
|
||
<span class="strong"><strong>printf</strong></span>("merges:\n");
|
||
<span class="strong"><strong>igraph_matrix_int_print</strong></span>(&merges);
|
||
<span class="strong"><strong>printf</strong></span>("bridges:\n");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&bridges);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&edges);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&eb);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&weights);
|
||
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&merges);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&bridges);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_eb_get_merges"></a>5.2. <code class="function">igraph_community_eb_get_merges</code> — Calculating the merges, i.e. the dendrogram for an edge betweenness community structure.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.9.3.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_eb_get_merges(const igraph_t *graph,
|
||
const igraph_bool_t directed,
|
||
const igraph_vector_int_t *edges,
|
||
const igraph_vector_t *weights,
|
||
igraph_matrix_int_t *res,
|
||
igraph_vector_int_t *bridges,
|
||
igraph_vector_t *modularity,
|
||
igraph_vector_int_t *membership);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function is handy if you have a sequence of edges which are
|
||
gradually removed from the network and you would like to know how
|
||
the network falls apart into separate components. The edge sequence
|
||
may come from the <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>
|
||
function, but this is not necessary. Note that <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a> can also calculate the
|
||
dendrogram, via its <em class="parameter"><code>merges</code></em> argument. Merges happen when the
|
||
edge removal process is run backwards and two components become
|
||
connected.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>directed</code></em>:</span></p></td>
|
||
<td><p>
|
||
Whether to use the directed or undirected version
|
||
of modularity. Will be ignored for undirected graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>edges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Vector containing the edges to be removed from the
|
||
network, all edges are expected to appear exactly once in the
|
||
vector.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
An optional vector containing edge weights. If null,
|
||
the unweighted modularity scores will be calculated. If not null,
|
||
the weighted modularity scores will be calculated. Ignored if both
|
||
<em class="parameter"><code>modularity</code></em> and <em class="parameter"><code>membership</code></em> are <code class="constant">NULL</code> pointers.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>res</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized matrix, if not <code class="constant">NULL</code> then the
|
||
dendrogram will be stored here, in the same form as for the
|
||
<a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a> function: the matrix has two columns
|
||
and each line is a merge given by the IDs of the merged
|
||
components. The component IDs are numbered from zero and
|
||
component IDs smaller than the number of vertices in the graph
|
||
belong to individual vertices. The non-trivial components
|
||
containing at least two vertices are numbered from <code class="constant">n</code>, where <code class="constant">n</code> is
|
||
the number of vertices in the graph. So if the first line
|
||
contains <code class="constant">a</code> and <code class="constant">b</code> that means that components <code class="constant">a</code> and <code class="constant">b</code>
|
||
are merged into component <code class="constant">n</code>, the second line creates
|
||
component <code class="literal">n + 1</code>, etc. The matrix will be resized as needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>bridges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector of <code class="constant">NULL</code>. If not
|
||
<code class="constant">NULL</code> then the indices into <em class="parameter"><code>edges</code></em> of all edges which caused
|
||
one of the merges will be put here. This is equal to all edge removals
|
||
which separated the network into more components, in reverse order.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then the modularity values
|
||
for the different divisions, corresponding to the merges matrix,
|
||
will be stored here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not a null pointer, then the membership vector
|
||
for the best division (in terms of modularity) will be stored
|
||
here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|E|+|V|log|V|), |V| is the number of vertices,
|
||
|E| is the number of edges.
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="community-structure-based-on-the-optimization-of-modularity"></a>6. Community structure based on the optimization of modularity</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_fastgreedy">6.1. <code class="function">igraph_community_fastgreedy</code> — Finding community structure by greedy optimization of modularity.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_multilevel">6.2. <code class="function">igraph_community_multilevel</code> — Finding community structure by multi-level optimization of modularity (Louvain).</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_leiden">6.3. <code class="function">igraph_community_leiden</code> — Finding community structure using the Leiden algorithm.</a></span></dt>
|
||
<dt><span class="section"><a href="igraph-Community.html#igraph_community_leiden_simple">6.4. <code class="function">igraph_community_leiden_simple</code> — Finding community structure using the Leiden algorithm, simple interface.</a></span></dt>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_fastgreedy"></a>6.1. <code class="function">igraph_community_fastgreedy</code> — Finding community structure by greedy optimization of modularity.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.10.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_fastgreedy(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_matrix_int_t *merges,
|
||
igraph_vector_t *modularity,
|
||
igraph_vector_int_t *membership);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This function implements the fast greedy modularity optimization
|
||
algorithm for finding community structure, see
|
||
A Clauset, MEJ Newman, C Moore: Finding community structure in very
|
||
large networks, <a class="ulink" href="http://www.arxiv.org/abs/cond-mat/0408187" target="_top">http://www.arxiv.org/abs/cond-mat/0408187</a> for the
|
||
details.
|
||
|
||
</p>
|
||
<p>
|
||
Some improvements proposed in K Wakita, T Tsurumi: Finding community
|
||
structure in mega-scale social networks,
|
||
<a class="ulink" href="http://www.arxiv.org/abs/cs.CY/0702048v1" target="_top">http://www.arxiv.org/abs/cs.CY/0702048v1</a> have also been implemented.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. It must be a graph without multiple edges.
|
||
This is checked and an error message is given for graphs with multiple
|
||
edges.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Potentially a numeric vector containing edge
|
||
weights. Supply a null pointer here for unweighted graphs. The
|
||
weights are expected to be non-negative.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>merges</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized matrix or <code class="constant">NULL</code>, the result of the
|
||
computation is stored here as a merges matrix representing a dendrogram.
|
||
The matrix has two columns and each merge corresponds to one merge, the
|
||
IDs of the two merged components are stored. The component IDs are numbered
|
||
from zero and the first <code class="constant">n</code> components are the individual vertices, <code class="constant">n</code> is
|
||
the number of vertices in the graph. Component <code class="constant">n</code> is created
|
||
in the first merge, component <code class="literal">n+1</code> in the second merge, etc.
|
||
The matrix will be resized as needed. If this argument is <code class="constant">NULL</code>
|
||
then it is ignored completely.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to an initialized vector or <code class="constant">NULL</code> pointer,
|
||
in the former case the modularity scores along the stages of the
|
||
computation are recorded here. The vector will be resized as
|
||
needed.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector. If not a null pointer, then
|
||
the membership vector corresponding to the best split (in terms
|
||
of modularity) is stored here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_to_membership" title="1.4. igraph_community_to_membership — Cut a dendrogram after a given number of merges."><code class="function">igraph_community_to_membership()</code></a> to cut the dendrogram at
|
||
an arbitrary number of steps.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|E||V|log|V|) in the worst case,
|
||
O(|E|+|V|log^2|V|) typically, |V| is the number of vertices, |E| is
|
||
the number of edges.
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.10.2.11.1"></a><p class="title"><b>Example 25.5. File <code class="code">examples/simple/igraph_community_fastgreedy.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t graph;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> weights;
|
||
igraph_matrix_int_t merges;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&merges, 0, 0);
|
||
<span class="strong"><strong>igraph_vector_init_int</strong></span>(&weights, 8, 10, 10, 1, 1, 1, 1, 1, 1);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&graph, 6, IGRAPH_UNDIRECTED,
|
||
0,1, 1,2, 2,3, 2,4, 2,5, 3,4, 3,5, 4,5, -1);
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_fastgreedy" title="6.1. igraph_community_fastgreedy — Finding community structure by greedy optimization of modularity.">igraph_community_fastgreedy</a></strong></span>(&graph, &weights, &merges,
|
||
<span class="emphasis"><em>/*modularity*/</em></span> NULL,
|
||
<span class="emphasis"><em>/*membership=*/</em></span> NULL);
|
||
<span class="strong"><strong>igraph_matrix_int_print</strong></span>(&merges);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&weights);
|
||
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&merges);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_multilevel"></a>6.2. <code class="function">igraph_community_multilevel</code> — Finding community structure by multi-level optimization of modularity (Louvain).</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.10.3.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_multilevel(const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
const igraph_real_t resolution,
|
||
igraph_vector_int_t *membership,
|
||
igraph_matrix_int_t *memberships,
|
||
igraph_vector_t *modularity);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
This function implements a multi-level modularity optimization algorithm
|
||
for finding community structure, sometimes known as the Louvain algorithm.
|
||
|
||
</p>
|
||
<p>
|
||
The algorithm is based on the modularity measure and a hierarchical approach.
|
||
Initially, each vertex is assigned to a community on its own. In every step,
|
||
vertices are re-assigned to communities in a local, greedy way: in a random
|
||
order, each vertex is moved to the community with which it achieves the highest
|
||
contribution to modularity. When no vertices can be reassigned, each community
|
||
is considered a vertex on its own, and the process starts again with the merged
|
||
communities. The process stops when there is only a single vertex left or when
|
||
the modularity cannot be increased any more in a step.
|
||
|
||
</p>
|
||
<p>
|
||
The resolution parameter <code class="constant">γ</code> allows finding communities at different
|
||
resolutions. Higher values of the resolution parameter typically result in
|
||
more, smaller communities. Lower values typically result in fewer, larger
|
||
communities. The original definition of modularity is retrieved when setting
|
||
<code class="literal">γ=1</code>. Note that the returned modularity value is calculated using
|
||
the indicated resolution parameter. See <a class="link" href="igraph-Community.html#igraph_modularity" title="1.1. igraph_modularity — Calculates the modularity of a graph with respect to some clusters or vertex types."><code class="function">igraph_modularity()</code></a> for more details.
|
||
|
||
</p>
|
||
<p>
|
||
The original version of this function was contributed by Tom Gregorovic.
|
||
|
||
</p>
|
||
<p>
|
||
Reference:
|
||
|
||
</p>
|
||
<p>
|
||
Blondel, V. D., Guillaume, J.-L., Lambiotte, R., & Lefebvre, E.:
|
||
Fast unfolding of communities in large networks.
|
||
Journal of Statistical Mechanics: Theory and Experiment, 10008(10), 6 (2008).
|
||
<a class="ulink" href="https://doi.org/10.1088/1742-5468/2008/10/P10008" target="_top">https://doi.org/10.1088/1742-5468/2008/10/P10008</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. It must be an undirected graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector containing edge weights. If <code class="constant">NULL</code>, every edge
|
||
has equal weight. The weights are expected to be non-negative.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>resolution</code></em>:</span></p></td>
|
||
<td><p>
|
||
Resolution parameter. Must be greater than or equal to 0.
|
||
Lower values favor fewer, larger communities;
|
||
higher values favor more, smaller communities.
|
||
Set it to 1 to use the classical definition of modularity.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The membership vector, the result is returned here.
|
||
For each vertex it gives the ID of its community. The vector
|
||
must be initialized and it will be resized accordingly.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>memberships</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric matrix that will contain the membership vector after
|
||
each level, if not <code class="constant">NULL</code>. It must be initialized and
|
||
it will be resized accordingly.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector that will contain the modularity score
|
||
after each level, if not <code class="constant">NULL</code>. It must be initialized
|
||
and it will be resized accordingly.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: in average near linear on sparse graphs.
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.10.3.13.1"></a><p class="title"><b>Example 25.6. File <code class="code">examples/simple/igraph_community_multilevel.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
|
||
void <span class="strong"><strong>show_results</strong></span>(igraph_t *g, igraph_vector_int_t *membership, igraph_matrix_int_t *memberships, <a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> *modularity, FILE* f) {
|
||
igraph_int_t i, j, no_of_nodes = <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(g);
|
||
|
||
j = <span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_which_max" title="2.10.4. igraph_vector_which_max — Gives the index of the maximum element of the vector.">igraph_vector_which_max</a></strong></span>(modularity);
|
||
<span class="strong"><strong>for</strong></span> (i = 0; i < <span class="strong"><strong>igraph_vector_int_size</strong></span>(membership); i++) {
|
||
<span class="strong"><strong>if</strong></span> (<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#VECTOR" title="2.4.1. VECTOR — Accessing an element of a vector.">VECTOR</a></strong></span>(*membership)[i] != <span class="strong"><strong><a class="link" href="igraph-Data-structures.html#MATRIX" title="3.4.1. MATRIX — Accessing an element of a matrix.">MATRIX</a></strong></span>(*memberships, j, i)) {
|
||
<span class="strong"><strong>fprintf</strong></span>(f, "WARNING: best membership vector element %" IGRAPH_PRId " does not match the best one in the membership matrix\n", i);
|
||
}
|
||
}
|
||
|
||
<span class="strong"><strong>fprintf</strong></span>(f, "Modularities:\n");
|
||
<span class="strong"><strong>igraph_vector_print</strong></span>(modularity);
|
||
|
||
<span class="strong"><strong>for</strong></span> (i = 0; i < <span class="strong"><strong>igraph_matrix_int_nrow</strong></span>(memberships); i++) {
|
||
<span class="strong"><strong>for</strong></span> (j = 0; j < no_of_nodes; j++) {
|
||
<span class="strong"><strong>fprintf</strong></span>(f, "%" IGRAPH_PRId " ", <span class="strong"><strong><a class="link" href="igraph-Data-structures.html#MATRIX" title="3.4.1. MATRIX — Accessing an element of a matrix.">MATRIX</a></strong></span>(*memberships, i, j));
|
||
}
|
||
<span class="strong"><strong>fprintf</strong></span>(f, "\n");
|
||
}
|
||
|
||
<span class="strong"><strong>fprintf</strong></span>(f, "\n");
|
||
}
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
igraph_t g;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> modularity;
|
||
igraph_vector_int_t edges;
|
||
igraph_vector_int_t membership;
|
||
igraph_matrix_int_t memberships;
|
||
igraph_int_t i, j, k;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&modularity, 0);
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, 0);
|
||
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&memberships, 0, 0);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_seed" title="3.3. igraph_rng_seed — Seeds a random number generator.">igraph_rng_seed</a></strong></span>(<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_default" title="2.1. igraph_rng_default — Query the default random number generator.">igraph_rng_default</a></strong></span>(), 42);
|
||
|
||
<span class="emphasis"><em>/* Unweighted test graph from the paper of Blondel et al */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&g, 16, IGRAPH_UNDIRECTED,
|
||
0, 2, 0, 3, 0, 4, 0, 5,
|
||
1, 2, 1, 4, 1, 7,
|
||
2, 4, 2, 5, 2, 6,
|
||
3, 7,
|
||
4, 10,
|
||
5, 7, 5, 11,
|
||
6, 7, 6, 11,
|
||
8, 9, 8, 10, 8, 11, 8, 14, 8, 15,
|
||
9, 12, 9, 14,
|
||
10, 11, 10, 12, 10, 13, 10, 14,
|
||
11, 13,
|
||
-1);
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_multilevel" title="6.2. igraph_community_multilevel — Finding community structure by multi-level optimization of modularity (Louvain).">igraph_community_multilevel</a></strong></span>(&g, 0, 1, &membership, &memberships, &modularity);
|
||
<span class="strong"><strong>show_results</strong></span>(&g, &membership, &memberships, &modularity, stdout);
|
||
|
||
<span class="emphasis"><em>/* Higher resolution */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_multilevel" title="6.2. igraph_community_multilevel — Finding community structure by multi-level optimization of modularity (Louvain).">igraph_community_multilevel</a></strong></span>(&g, 0, 1.5, &membership, &memberships, &modularity);
|
||
<span class="strong"><strong>show_results</strong></span>(&g, &membership, &memberships, &modularity, stdout);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&g);
|
||
|
||
<span class="emphasis"><em>/* Ring of 30 cliques */</em></span>
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&edges, 0);
|
||
<span class="strong"><strong>for</strong></span> (i = 0; i < 30; i++) {
|
||
<span class="strong"><strong>for</strong></span> (j = 0; j < 5; j++) {
|
||
<span class="strong"><strong>for</strong></span> (k = j + 1; k < 5; k++) {
|
||
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&edges, i * 5 + j);
|
||
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&edges, i * 5 + k);
|
||
}
|
||
}
|
||
}
|
||
<span class="strong"><strong>for</strong></span> (i = 0; i < 30; i++) {
|
||
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&edges, i * 5 % 150);
|
||
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&edges, (i * 5 + 6) % 150);
|
||
}
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_create" title="2.1. igraph_create — Creates a graph with the specified edges.">igraph_create</a></strong></span>(&g, &edges, 150, 0);
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_multilevel" title="6.2. igraph_community_multilevel — Finding community structure by multi-level optimization of modularity (Louvain).">igraph_community_multilevel</a></strong></span>(&g, 0, 1, &membership, &memberships, &modularity);
|
||
<span class="strong"><strong>show_results</strong></span>(&g, &membership, &memberships, &modularity, stdout);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&g);
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&modularity);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&edges);
|
||
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&memberships);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_leiden"></a>6.3. <code class="function">igraph_community_leiden</code> — Finding community structure using the Leiden algorithm.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.10.4.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_leiden(
|
||
const igraph_t *graph,
|
||
const igraph_vector_t *edge_weights,
|
||
const igraph_vector_t *vertex_out_weights,
|
||
const igraph_vector_t *vertex_in_weights,
|
||
igraph_real_t resolution,
|
||
igraph_real_t beta,
|
||
igraph_bool_t start,
|
||
igraph_int_t n_iterations,
|
||
igraph_vector_int_t *membership,
|
||
igraph_int_t *nb_clusters,
|
||
igraph_real_t *quality);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
This function implements the Leiden algorithm for finding community
|
||
structure.
|
||
|
||
</p>
|
||
<p>
|
||
It is similar to the multilevel algorithm, often called the Louvain
|
||
algorithm, but it is faster and yields higher quality solutions. It can
|
||
optimize both modularity and the Constant Potts Model, which does not suffer
|
||
from the resolution-limit (see Traag, Van Dooren & Nesterov).
|
||
|
||
</p>
|
||
<p>
|
||
The Leiden algorithm consists of three phases: (1) local moving of vertices, (2)
|
||
refinement of the partition and (3) aggregation of the network based on the
|
||
refined partition, using the non-refined partition to create an initial
|
||
partition for the aggregate network. In the local move procedure in the
|
||
Leiden algorithm, only vertices whose neighborhood has changed are visited. Only
|
||
moves that strictly improve the quality function are made. The refinement is
|
||
done by restarting from a singleton partition within each cluster and
|
||
gradually merging the subclusters. When aggregating, a single cluster may
|
||
then be represented by several vertices (which are the subclusters identified in
|
||
the refinement).
|
||
|
||
</p>
|
||
<p>
|
||
The Leiden algorithm provides several guarantees. The Leiden algorithm is
|
||
typically iterated: the output of one iteration is used as the input for the
|
||
next iteration. At each iteration all clusters are guaranteed to be (weakly)
|
||
connected and well-separated. After an iteration in which nothing has
|
||
changed, all vertices and some parts are guaranteed to be locally optimally
|
||
assigned. Note that even if a single iteration did not result in any change,
|
||
it is still possible that a subsequent iteration might find some
|
||
improvement. Each iteration explores different subsets of vertices to consider
|
||
for moving from one cluster to another. Finally, asymptotically, all subsets
|
||
of all clusters are guaranteed to be locally optimally assigned. For more
|
||
details, please see Traag, Waltman & van Eck (2019).
|
||
|
||
</p>
|
||
<p>
|
||
The objective function being optimized is
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">1 / 2m sum_ij (A_ij - γ n_i n_j) δ(s_i, s_j)</code>
|
||
|
||
</p>
|
||
<p>
|
||
in the undirected case and
|
||
|
||
</p>
|
||
<p>
|
||
<code class="literal">1 / m sum_ij (A_ij - γ n^out_i n^in_j) δ(s_i, s_j)</code>
|
||
|
||
</p>
|
||
<p>
|
||
in the directed case.
|
||
Here <code class="constant">m</code> is the total edge weight, <code class="literal">A_ij</code> is the weight of edge
|
||
(i, j), <code class="constant">γ</code> is the so-called resolution parameter, <code class="literal">n_i</code>
|
||
is the vertex weight of vertex <code class="constant">i</code> (separate out- and in-weights are used
|
||
with directed graphs), <code class="literal">s_i</code> is the cluster of vertex
|
||
<code class="constant">i</code> and <code class="literal">δ(x, y) = 1</code> if and only if <code class="literal">x = y</code> and 0
|
||
otherwise.
|
||
|
||
</p>
|
||
<p>
|
||
By setting <code class="literal">n_i = k_i</code>, the degree of vertex <code class="constant">i</code>, and
|
||
dividing <code class="constant">γ</code> by <code class="literal">2m</code> (by <code class="constant">m</code> in the directed case), we effectively
|
||
obtain an expression for modularity. Hence, the standard modularity will be
|
||
optimized when you supply the degrees (out- and in-degrees with directed graphs)
|
||
as the vertex weights and by supplying as a resolution parameter
|
||
<code class="literal">1/(2m)</code> (<code class="literal">1/m</code> with directed graphs).
|
||
Use the <a class="link" href="igraph-Community.html#igraph_community_leiden_simple" title="6.4. igraph_community_leiden_simple — Finding community structure using the Leiden algorithm, simple interface."><code class="function">igraph_community_leiden_simple()</code></a> convenience function to
|
||
compute vertex weights automatically for modularity maximization.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
V. A. Traag, L. Waltman, N. J. van Eck:
|
||
From Louvain to Leiden: guaranteeing well-connected communities.
|
||
Scientific Reports, 9(1), 5233 (2019).
|
||
<a class="ulink" href="http://dx.doi.org/10.1038/s41598-019-41695-z" target="_top">http://dx.doi.org/10.1038/s41598-019-41695-z</a>
|
||
|
||
</p>
|
||
<p>
|
||
V. A. Traag, P. Van Dooren, and Y. Nesterov:
|
||
Narrow scope for resolution-limit-free community detection.
|
||
Phys. Rev. E 84, 016114 (2011).
|
||
<a class="ulink" href="https://doi.org/10.1103/PhysRevE.84.016114" target="_top">https://doi.org/10.1103/PhysRevE.84.016114</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>edge_weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector containing edge weights. If <code class="constant">NULL</code>,
|
||
every edge has equal weight of 1. The weights need not be non-negative.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>vertex_out_weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector containing vertex weights, or vertex
|
||
out-weights for directed graphs. If <code class="constant">NULL</code>, every vertex has equal
|
||
weight of 1.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>vertex_in_weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector containing vertex in-weights for
|
||
directed graphs. If set to <code class="constant">NULL</code>, in-weights are assumed to be the same
|
||
as out-weights, which effectively ignores edge directions.
|
||
Must be <code class="constant">NULL</code> for undirected graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>n_iterations</code></em>:</span></p></td>
|
||
<td><p>
|
||
Iterate the core Leiden algorithm the indicated number
|
||
of times. If this is a negative number, it will continue iterating until
|
||
an iteration did not change the clustering. Two iterations are often
|
||
sufficient, thus 2 is a reasonable default.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>beta</code></em>:</span></p></td>
|
||
<td><p>
|
||
The randomness used in the refinement step when merging. A small
|
||
amount of randomness (<code class="constant">beta</code> = 0.01) typically works well.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>start</code></em>:</span></p></td>
|
||
<td><p>
|
||
Start from membership vector. If this is true, the optimization
|
||
will start from the provided membership vector. If this is false, the
|
||
optimization will start from a singleton partition.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>n_iterations</code></em>:</span></p></td>
|
||
<td><p>
|
||
Iterate the core Leiden algorithm for the indicated number
|
||
of times. If this is a negative number, it will continue iterating until
|
||
an iteration did not change the clustering.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The membership vector. This is both used as the initial
|
||
membership from which optimisation starts and is updated in place. It
|
||
must hence be properly initialized. When finding clusters from scratch it
|
||
is typically started using a singleton clustering. This can be achieved
|
||
using <a class="link" href="igraph-Data-structures.html#igraph_vector_init_range" title="2.2.4. igraph_vector_init_range — Initializes a vector with a range."><code class="function">igraph_vector_int_init_range()</code></a>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>nb_clusters</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of clusters contained in the final <em class="parameter"><code>membership</code></em>.
|
||
If <code class="constant">NULL</code>, the number of clusters will not be returned.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>quality</code></em>:</span></p></td>
|
||
<td><p>
|
||
The quality of the partition, in terms of the objective
|
||
function as included in the documentation. If <code class="constant">NULL</code> the quality will
|
||
not be calculated.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: near linear on sparse graphs.
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_leiden_simple" title="6.4. igraph_community_leiden_simple — Finding community structure using the Leiden algorithm, simple interface."><code class="function">igraph_community_leiden_simple()</code></a> for a simplified interface
|
||
that allows specifying an objective function directly and does not require
|
||
vertex weights.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.10.4.22.1"></a><p class="title"><b>Example 25.7. File <code class="code">examples/simple/igraph_community_leiden.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
<span class="strong"><strong>#include</strong></span> <stdio.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t graph;
|
||
igraph_vector_int_t membership;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> vertex_weights;
|
||
<a class="link" href="igraph-Data-structures.html#igraph_vector_t" title="2.1. About igraph_vector_t objects">igraph_vector_t</a> vertex_out_weights, vertex_in_weights;
|
||
igraph_int_t nb_clusters;
|
||
igraph_real_t quality;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="emphasis"><em>/* Set default seed to get reproducible results */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_seed" title="3.3. igraph_rng_seed — Seeds a random number generator.">igraph_rng_seed</a></strong></span>(<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_default" title="2.1. igraph_rng_default — Query the default random number generator.">igraph_rng_default</a></strong></span>(), 0);
|
||
|
||
<span class="emphasis"><em>/* UNDIRECTED EXAMPLE */</em></span>
|
||
|
||
<span class="emphasis"><em>/* Simple unweighted undirected graph */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&graph, 10, IGRAPH_UNDIRECTED,
|
||
0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4,
|
||
5, 6, 5, 7, 5, 8, 5, 9, 6, 7, 6, 8, 6, 9, 7, 8, 7, 9, 8, 9,
|
||
0, 5, -1);
|
||
|
||
<span class="emphasis"><em>/* Perform Leiden algorithm using CPM for 1 iteration */</em></span>
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&graph));
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm.">igraph_community_leiden</a></strong></span>(&graph, NULL, NULL, NULL,
|
||
<span class="emphasis"><em>/* resolution */</em></span> 0.05,
|
||
<span class="emphasis"><em>/* beta */</em></span> 0.01,
|
||
<span class="emphasis"><em>/* start */</em></span> false,
|
||
<span class="emphasis"><em>/* iterations */</em></span> 1,
|
||
&membership, &nb_clusters, &quality);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Leiden found %" IGRAPH_PRId " clusters using CPM (resolution parameter 0.05), quality is %.4f.\n", nb_clusters, quality);
|
||
<span class="strong"><strong>printf</strong></span>("Membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
<span class="strong"><strong>printf</strong></span>("\n");
|
||
|
||
<span class="emphasis"><em>/* Start from existing membership for 10 iterations to improve it further */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm.">igraph_community_leiden</a></strong></span>(&graph, NULL, NULL, NULL,
|
||
<span class="emphasis"><em>/* resolution */</em></span> 0.05,
|
||
<span class="emphasis"><em>/* beta */</em></span> 0.01,
|
||
<span class="emphasis"><em>/* start */</em></span> true,
|
||
<span class="emphasis"><em>/* iterations */</em></span> 10,
|
||
&membership, &nb_clusters, &quality);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Iterated Leiden, using CPM (resolution parameter 0.05), quality is %.4f.\n", quality);
|
||
<span class="strong"><strong>printf</strong></span>("Membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
<span class="strong"><strong>printf</strong></span>("\n");
|
||
|
||
<span class="emphasis"><em>/* Use degrees as vertex weights for optimizing modularity */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&vertex_weights, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&graph));
|
||
<span class="strong"><strong><a class="link" href="igraph-Structural.html#igraph_strength" title="11.11. igraph_strength — Strength of the vertices, also called weighted vertex degree.">igraph_strength</a></strong></span>(&graph, &vertex_weights, <span class="strong"><strong><a class="link" href="igraph-Iterators.html#igraph_vss_all" title="4.1. igraph_vss_all — All vertices of a graph (immediate version).">igraph_vss_all</a></strong></span>(), IGRAPH_ALL, IGRAPH_LOOPS, NULL);
|
||
|
||
<span class="emphasis"><em>/* Perform Leiden algorithm using modularity until stable iteration */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm.">igraph_community_leiden</a></strong></span>(&graph, NULL, &vertex_weights, NULL,
|
||
<span class="emphasis"><em>/* resolution */</em></span> 1.0 / (2 * <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_ecount" title="5.2.2. igraph_ecount — The number of edges in a graph.">igraph_ecount</a></strong></span>(&graph)),
|
||
<span class="emphasis"><em>/* beta */</em></span> 0.01,
|
||
<span class="emphasis"><em>/* start */</em></span> false,
|
||
<span class="emphasis"><em>/* iterations */</em></span> -1,
|
||
&membership, &nb_clusters, &quality);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Leiden found %" IGRAPH_PRId " clusters using modularity, quality is %.4f.\n", nb_clusters, quality);
|
||
<span class="strong"><strong>printf</strong></span>("Membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
<span class="strong"><strong>printf</strong></span>("\n");
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&vertex_weights);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
|
||
<span class="emphasis"><em>/* DIRECTED EXAMPLE */</em></span>
|
||
|
||
<span class="emphasis"><em>/* Simple unweighted directed graph */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_small" title="2.2. igraph_small — Shorthand to create a small graph, giving the edges as arguments.">igraph_small</a></strong></span>(&graph, 6, IGRAPH_DIRECTED,
|
||
0, 1, 0, 3, 0, 5, 1, 3, 1, 4, 2, 3, 4, 1, 5, 2, 5, 4,
|
||
-1);
|
||
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&graph));
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&vertex_out_weights, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&graph));
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_init" title="2.2.1. igraph_vector_init — Initializes a vector object (constructor).">igraph_vector_init</a></strong></span>(&vertex_in_weights, <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_vcount" title="5.2.1. igraph_vcount — The number of vertices in a graph.">igraph_vcount</a></strong></span>(&graph));
|
||
<span class="strong"><strong><a class="link" href="igraph-Structural.html#igraph_strength" title="11.11. igraph_strength — Strength of the vertices, also called weighted vertex degree.">igraph_strength</a></strong></span>(&graph, &vertex_out_weights, <span class="strong"><strong><a class="link" href="igraph-Iterators.html#igraph_vss_all" title="4.1. igraph_vss_all — All vertices of a graph (immediate version).">igraph_vss_all</a></strong></span>(), IGRAPH_OUT, IGRAPH_LOOPS, NULL);
|
||
<span class="strong"><strong><a class="link" href="igraph-Structural.html#igraph_strength" title="11.11. igraph_strength — Strength of the vertices, also called weighted vertex degree.">igraph_strength</a></strong></span>(&graph, &vertex_in_weights, <span class="strong"><strong><a class="link" href="igraph-Iterators.html#igraph_vss_all" title="4.1. igraph_vss_all — All vertices of a graph (immediate version).">igraph_vss_all</a></strong></span>(), IGRAPH_IN, IGRAPH_LOOPS, NULL);
|
||
|
||
<span class="emphasis"><em>/* Perform Leiden algorithm using modularity for two iterations,</em></span>
|
||
<span class="emphasis"><em> * which are usually sufficient to achieve stability.</em></span>
|
||
<span class="emphasis"><em> * Note that in the directed case, we divide by the edge count m, not 2*m. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm.">igraph_community_leiden</a></strong></span>(&graph, NULL, &vertex_out_weights, &vertex_in_weights,
|
||
<span class="emphasis"><em>/* resolution */</em></span> 1.0 / <span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_ecount" title="5.2.2. igraph_ecount — The number of edges in a graph.">igraph_ecount</a></strong></span>(&graph),
|
||
<span class="emphasis"><em>/* beta */</em></span> 0.01,
|
||
<span class="emphasis"><em>/* start */</em></span> false,
|
||
<span class="emphasis"><em>/* iterations */</em></span> 2,
|
||
&membership, &nb_clusters, &quality);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Leiden found %" IGRAPH_PRId " clusters using modularity, quality is %.4f.\n", nb_clusters, quality);
|
||
<span class="strong"><strong>printf</strong></span>("Membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
<span class="strong"><strong>printf</strong></span>("\n");
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&vertex_in_weights);
|
||
<span class="strong"><strong><a class="link" href="igraph-Data-structures.html#igraph_vector_destroy" title="2.2.5. igraph_vector_destroy — Destroys a vector object.">igraph_vector_destroy</a></strong></span>(&vertex_out_weights);
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_leiden_simple"></a>6.4. <code class="function">igraph_community_leiden_simple</code> — Finding community structure using the Leiden algorithm, simple interface.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.10.5.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_leiden_simple(
|
||
const igraph_t *graph,
|
||
const igraph_vector_t *weights,
|
||
igraph_leiden_objective_t objective,
|
||
igraph_real_t resolution,
|
||
igraph_real_t beta,
|
||
igraph_bool_t start,
|
||
igraph_int_t n_iterations,
|
||
igraph_vector_int_t *membership,
|
||
igraph_int_t *nb_clusters,
|
||
igraph_real_t *quality);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
This is a simplified interface to <a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm."><code class="function">igraph_community_leiden()</code></a> for
|
||
convenience purposes. Instead of requiring vertex weights, it allows
|
||
choosing from a set of objective functions to maximize. It implements
|
||
these objective functions by passing suitable vertex weights to
|
||
<a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm."><code class="function">igraph_community_leiden()</code></a>, as explained in the documentation of
|
||
that function.
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. May be directed or undirected.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
The edge weights. If <code class="constant">NULL</code>, all weights are assumed to be 1.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>objective</code></em>:</span></p></td>
|
||
<td>
|
||
<p>
|
||
The objective function to maximize.
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEIDEN_OBJECTIVE_MODULARITY</code></span></p></td>
|
||
<td><p>
|
||
|
||
Use the generalized modularity, defined as
|
||
<code class="literal">Q = 1/(2m) sum_ij (A_ij - γ k_i k_j / (2m)) δ(c_i, c_j)</code>
|
||
for undirected graphs and as
|
||
<code class="literal">Q = 1/m sum_ij (A_ij - γ k^out_i k^in_j / m) δ(c_i, c_j)</code>
|
||
for directed graphs. This effectively uses a multigraph configuration
|
||
model as the null model. Edge weights must not be negative.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEIDEN_OBJECTIVE_CPM</code></span></p></td>
|
||
<td><p>
|
||
|
||
Use the constant Potts model, whose objective function is defined as
|
||
<code class="literal">Q = 1/(2m) sum_ij (A_ij - γ) δ(c_i, c_j)</code>
|
||
for undirected graphs and as
|
||
<code class="literal">Q = 1/m sum_ij (A_ij - γ) δ(c_i, c_j)</code>
|
||
for directed graphs. Edge weights are allowed to be negative.
|
||
Edge directions have no impact on the result.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LEIDEN_OBJECTIVE_ER</code></span></p></td>
|
||
<td><p>
|
||
|
||
Use an objective function based on the multigraph Erdős-Rényi G(n,p)
|
||
null model, defined as
|
||
<code class="literal">Q = 1/(2m) sum_ij (A_ij - γ p) δ(c_i, c_j)</code>
|
||
for undirected graphs and as
|
||
<code class="literal">Q = 1/m sum_ij (A_ij - γ p) δ(c_i, c_j)</code>
|
||
for directed graphs. <code class="constant">p</code> is the weighted density, i.e. the average
|
||
link strength between all vertex pairs (whether adjacent or not).
|
||
Edge weights must not be negative. Edge directions have no impact on
|
||
the result.
|
||
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
In the above formulas, <code class="constant">A</code> is the adjacency matrix, <code class="constant">m</code> is the total
|
||
edge weight, <code class="constant">k</code> are the (out- and in-) degrees, <code class="constant">γ</code> is the resolution
|
||
parameter, and <code class="literal">δ(c_i, c_j)</code> is 1 if vertices <code class="constant">i</code> and <code class="constant">j</code>
|
||
are in the same community and 0 otherwise. Edge directions are only
|
||
relevant with <code class="constant">IGRAPH_LEIDEN_OBJECTIVE_MODULARITY</code>. The other two
|
||
objective functions are equivalent between directed and undirected graphs:
|
||
the formal difference is due to each edge being included twice in
|
||
undirected (symmetric) adjacency matrices.
|
||
</p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>resolution</code></em>:</span></p></td>
|
||
<td><p>
|
||
The resolution parameter, which is represented by γ in
|
||
the objective functions detailed above.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>beta</code></em>:</span></p></td>
|
||
<td><p>
|
||
The randomness used in the refinement step when merging. A small
|
||
amount of randomness (<code class="constant">beta</code> = 0.01) typically works well.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>start</code></em>:</span></p></td>
|
||
<td><p>
|
||
Start from membership vector. If this is true, the optimization
|
||
will start from the provided membership vector. If this is false, the
|
||
optimization will start from a singleton partition.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>n_iterations</code></em>:</span></p></td>
|
||
<td><p>
|
||
Iterate the core Leiden algorithm the indicated number
|
||
of times. If this is a negative number, it will continue iterating until
|
||
an iteration did not change the clustering. Two iterations are often
|
||
sufficient, thus 2 is a reasonable default.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The membership vector. If <em class="parameter"><code>start</code></em> is set to <code class="constant">false</code>,
|
||
it will be resized appropriately. If <em class="parameter"><code>start</code></em> is <code class="constant">true</code>, it must be
|
||
a valid membership vector for the given <em class="parameter"><code>graph</code></em>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>nb_clusters</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of clusters contained in the final <em class="parameter"><code>membership</code></em>.
|
||
If <code class="constant">NULL</code>, the number of clusters will not be returned.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>quality</code></em>:</span></p></td>
|
||
<td><p>
|
||
The quality of the partition, in terms of the objective
|
||
function selected by <em class="parameter"><code>objective</code></em>. If <code class="constant">NULL</code> the quality will
|
||
not be calculated.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: near linear on sparse graphs.
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_leiden" title="6.3. igraph_community_leiden — Finding community structure using the Leiden algorithm."><code class="function">igraph_community_leiden()</code></a> for a more flexible interface that
|
||
allows specifying raw vertex weights.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="fluid-communities"></a>7. Fluid communities</h2></div></div></div>
|
||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="igraph-Community.html#igraph_community_fluid_communities">7.1. <code class="function">igraph_community_fluid_communities</code> — Community detection based on fluids interacting on the graph.</a></span></dt></dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_fluid_communities"></a>7.1. <code class="function">igraph_community_fluid_communities</code> — Community detection based on fluids interacting on the graph.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.11.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_fluid_communities(
|
||
const igraph_t *graph,
|
||
igraph_int_t no_of_communities,
|
||
igraph_vector_int_t *membership);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
The algorithm is based on the simple idea of
|
||
several fluids interacting in a non-homogeneous environment
|
||
(the graph topology), expanding and contracting based on their
|
||
interaction and density. Weighted graphs are not supported.
|
||
|
||
</p>
|
||
<p>
|
||
This function implements the community detection method described in:
|
||
Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,
|
||
Scalable and Diverse Community Detection Algorithm. In: Complex Networks
|
||
& Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth
|
||
International Conference on Complex Networks and Their Applications),
|
||
Springer, vol 689, p 229. <a class="ulink" href="https://doi.org/10.1007/978-3-319-72150-7_19" target="_top">https://doi.org/10.1007/978-3-319-72150-7_19</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. The graph must be simple and connected.
|
||
Edge directions will be ignored.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>no_of_communities</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of communities to be found. Must be
|
||
greater than 0 and fewer than number of vertices in the graph.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The result vector mapping vertices to the communities
|
||
they are assigned to.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(|E|)
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="label-propagation"></a>8. Label propagation</h2></div></div></div>
|
||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="igraph-Community.html#igraph_community_label_propagation">8.1. <code class="function">igraph_community_label_propagation</code> — Community detection based on label propagation.</a></span></dt></dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_label_propagation"></a>8.1. <code class="function">igraph_community_label_propagation</code> — Community detection based on label propagation.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.12.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_label_propagation(const igraph_t *graph,
|
||
igraph_vector_int_t *membership,
|
||
igraph_neimode_t mode,
|
||
const igraph_vector_t *weights,
|
||
const igraph_vector_int_t *initial,
|
||
const igraph_vector_bool_t *fixed,
|
||
igraph_lpa_variant_t lpa_variant);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
|
||
This function implements the label propagation-based community detection
|
||
algorithm described by Raghavan, Albert and Kumara (2007). This version extends
|
||
the original method by the ability to take edge weights into consideration
|
||
and also by allowing some labels to be fixed. In addition, it implements
|
||
the fast label propagation alternative introduced by Traag and Šubelj (2023).
|
||
|
||
</p>
|
||
<p>
|
||
The algorithm works by iterating over nodes and updating the label of a node
|
||
based on the labels of its neighbors. The labels that are most frequent among
|
||
the neighbors are said to be dominant labels. The label of a node is always
|
||
updated to a dominant label. The algorithm guarantees that the label for each
|
||
is dominant when it terminates.
|
||
|
||
</p>
|
||
<p>
|
||
There are several variants implemented, which work slightly differently with
|
||
the dominance of labels. Nodes with a dominant label might no longer have a
|
||
dominant label if one of their neighbors change label. In <code class="constant">IGRAPH_LPA_DOMINANCE</code> an additional iteration over all nodes is made after
|
||
updating all labels to double check whether all nodes indeed have a dominant
|
||
label. When updating the label of a node, labels are always sampled from
|
||
among all dominant labels. The algorithm stops when all nodes have dominant
|
||
labels. In <code class="constant">IGRAPH_LPA_RETENTION</code> instead labels are only updated when they
|
||
are not dominant. That is, they retain their current label whenever the
|
||
current label is already dominant. The algorithm does not make an additional
|
||
iteration to check for dominance. Instead, it simply keeps track whether a
|
||
label has been updated, and terminates if no updates have been made. In <code class="constant">IGRAPH_LPA_FAST</code> labels are sampled from among all dominant labels, similar to
|
||
<code class="constant">IGRAPH_LPA_DOMINANCE</code>. Instead of iterating over all nodes, it keeps track
|
||
of a queue of nodes that should be considered. Nodes are popped from the
|
||
queue when they are considered for update. When the label of a node is
|
||
updated, the node's neighbors are added to the queue again (if they weren't
|
||
already in the queue). The algorithm terminates when the queue is empty. All
|
||
variants guarantee that the labels for all nodes are dominant.
|
||
|
||
</p>
|
||
<p>
|
||
Weights are taken into account as follows: when the new label of node
|
||
<code class="constant">i</code> is determined, the algorithm iterates over all edges incident on
|
||
node <code class="constant">i</code> and calculate the total weight of edges leading to other
|
||
nodes with label 0, 1, 2, ..., <code class="constant">k</code> - 1 (where <code class="constant">k</code> is the number of possible
|
||
labels). The new label of node <code class="constant">i</code> will then be the label whose edges
|
||
(among the ones incident on node <code class="constant">i</code>) have the highest total weight.
|
||
|
||
</p>
|
||
<p>
|
||
For directed graphs, it is important to know that labels can circulate
|
||
freely only within the strongly connected components of the graph and
|
||
may propagate in only one direction (or not at all) <span class="emphasis"><em>between</em></span> strongly
|
||
connected components. You should treat directed edges as directed only
|
||
if you are aware of the consequences.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
Raghavan, U.N. and Albert, R. and Kumara, S.: Near linear time algorithm to
|
||
detect community structures in large-scale networks. Phys Rev E 76, 036106
|
||
(2007). <a class="ulink" href="https://doi.org/10.1103/PhysRevE.76.036106" target="_top">https://doi.org/10.1103/PhysRevE.76.036106</a>
|
||
|
||
</p>
|
||
<p>
|
||
Šubelj, L.: Label propagation for clustering. Chapter in "Advances in
|
||
Network Clustering and Blockmodeling" edited by P. Doreian, V. Batagelj
|
||
& A. Ferligoj (Wiley, New York, 2018).
|
||
<a class="ulink" href="https://doi.org/10.1002/9781119483298.ch5" target="_top">https://doi.org/10.1002/9781119483298.ch5</a>
|
||
<a class="ulink" href="https://arxiv.org/abs/1709.05634" target="_top">https://arxiv.org/abs/1709.05634</a>
|
||
|
||
</p>
|
||
<p>
|
||
Traag, V. A., and Šubelj, L.: Large network community detection by fast
|
||
label propagation. Scientific Reports, 13:1, (2023).
|
||
<a class="ulink" href="https://doi.org/10.1038/s41598-023-29610-z" target="_top">https://doi.org/10.1038/s41598-023-29610-z</a>
|
||
<a class="ulink" href="https://arxiv.org/abs/2209.13338" target="_top">https://arxiv.org/abs/2209.13338</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. Note that the algorithm was originally
|
||
defined for undirected graphs. You are advised to set <em class="parameter"><code>mode</code></em> to
|
||
<code class="constant">IGRAPH_ALL</code> if you pass a directed graph here to treat it as
|
||
undirected.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
The membership vector, the result is returned here.
|
||
For each vertex it gives the ID of its community (label).
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>mode</code></em>:</span></p></td>
|
||
<td><p>
|
||
Whether to consider edge directions for the label propagation,
|
||
and if so, which direction the labels should propagate. Ignored for
|
||
undirected graphs. <code class="constant">IGRAPH_ALL</code> means to ignore edge directions (even
|
||
in directed graphs). <code class="constant">IGRAPH_OUT</code> means to propagate labels along the
|
||
natural direction of the edges. <code class="constant">IGRAPH_IN</code> means to propagate labels
|
||
<span class="emphasis"><em>backwards</em></span> (i.e. from head to tail). It is advised to set this to
|
||
<code class="constant">IGRAPH_ALL</code> unless you are specifically interested in the effect of
|
||
edge directions.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
The weight vector, it should contain a positive
|
||
weight for all the edges.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>initial</code></em>:</span></p></td>
|
||
<td><p>
|
||
The initial state. If <code class="constant">NULL</code>, every vertex will have
|
||
a different label at the beginning. Otherwise it must be a vector
|
||
with an entry for each vertex. Non-negative values denote different
|
||
labels, negative entries denote vertices without labels. Unlabeled
|
||
vertices which are not reachable from any labeled ones will remain
|
||
unlabeled at the end of the label propagation process, and will be
|
||
labeled in an additional step to avoid returning negative values in
|
||
<em class="parameter"><code>membership</code></em>. In undirected graphs, this happens when entire connected
|
||
components are unlabeled. Then, each unlabeled component will receive
|
||
its own separate label. In directed graphs, the outcome of the
|
||
additional labeling should be considered undefined and may change
|
||
in the future; please do not rely on it.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>fixed</code></em>:</span></p></td>
|
||
<td><p>
|
||
Boolean vector denoting which labels are fixed. Of course
|
||
this makes sense only if you provided an initial state, otherwise
|
||
this element will be ignored. Note that vertices without labels
|
||
cannot be fixed. The fixed status will be ignored for these with a
|
||
warning. Also note that label numbers by themselves have no meaning,
|
||
and igraph may renumber labels. However, co-membership constraints
|
||
will be respected: two vertices can be fixed to be in the same or in
|
||
different communities.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>lpa_variant</code></em>:</span></p></td>
|
||
<td>
|
||
<p>
|
||
Which variant of the label propagation algorithm to run.
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LPA_DOMINANCE</code></span></p></td>
|
||
<td><p>
|
||
|
||
check for dominance of all nodes after each iteration.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LPA_RETENTION</code></span></p></td>
|
||
<td><p>
|
||
|
||
keep current label if among dominant labels, only check if labels changed.
|
||
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><code class="constant">IGRAPH_LPA_FAST</code></span></p></td>
|
||
<td><p>
|
||
|
||
sample from dominant labels, only check neighbors.
|
||
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: O(m+n)
|
||
|
||
</p>
|
||
<div class="hideshow" onClick="toggle(this, event)">
|
||
<div class="example">
|
||
<a name="id-1.26.12.2.16.1"></a><p class="title"><b>Example 25.8. File <code class="code">examples/simple/igraph_community_label_propagation.c</code></b></p>
|
||
<div class="example-contents">
|
||
<pre class="programlisting"><span class="strong"><strong>#include</strong></span> <igraph.h>
|
||
<span class="strong"><strong>#include</strong></span> <stdio.h>
|
||
|
||
int <span class="strong"><strong>main</strong></span>(void) {
|
||
igraph_t graph;
|
||
igraph_vector_int_t membership;
|
||
igraph_real_t modularity;
|
||
|
||
<span class="emphasis"><em>/* Initialize the library. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_setup" title="4.1. igraph_setup — Initializes the igraph library.">igraph_setup</a></strong></span>();
|
||
|
||
<span class="strong"><strong><a class="link" href="igraph-Generators.html#igraph_famous" title="8.1. igraph_famous — Create a famous graph by simply providing its name.">igraph_famous</a></strong></span>(&graph, "Zachary"); <span class="emphasis"><em>/* We use Zachary's karate club network. */</em></span>
|
||
|
||
<span class="emphasis"><em>/* Label propagation is a stochastic method; the result will depend on the random seed. */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_seed" title="3.3. igraph_rng_seed — Seeds a random number generator.">igraph_rng_seed</a></strong></span>(<span class="strong"><strong><a class="link" href="igraph-Random.html#igraph_rng_default" title="2.1. igraph_rng_default — Query the default random number generator.">igraph_rng_default</a></strong></span>(), 123);
|
||
|
||
<span class="emphasis"><em>/* All igraph functions that returns their result in an igraph_vector_t must be given</em></span>
|
||
<span class="emphasis"><em> an already initialized vector. */</em></span>
|
||
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&membership, 0);
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_community_label_propagation" title="8.1. igraph_community_label_propagation — Community detection based on label propagation.">igraph_community_label_propagation</a></strong></span>(
|
||
&graph, &membership, <span class="emphasis"><em>/* mode = */</em></span> IGRAPH_ALL,
|
||
<span class="emphasis"><em>/* weights= */</em></span> NULL, <span class="emphasis"><em>/* initial= */</em></span> NULL, <span class="emphasis"><em>/* fixed= */</em></span> NULL,
|
||
IGRAPH_LPA_DOMINANCE);
|
||
|
||
<span class="emphasis"><em>/* Also calculate the modularity of the partition */</em></span>
|
||
<span class="strong"><strong><a class="link" href="igraph-Community.html#igraph_modularity" title="1.1. igraph_modularity — Calculates the modularity of a graph with respect to some clusters or vertex types.">igraph_modularity</a></strong></span>(
|
||
&graph, &membership, <span class="emphasis"><em>/* weights= */</em></span> NULL, <span class="emphasis"><em>/* resolution = */</em></span> 1,
|
||
<span class="emphasis"><em>/* directed= */</em></span> false, &modularity);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("%" IGRAPH_PRId " communities found; modularity score is %g.\n",
|
||
<span class="strong"><strong>igraph_vector_int_max</strong></span>(&membership) + 1, modularity);
|
||
|
||
<span class="strong"><strong>printf</strong></span>("Communities membership: ");
|
||
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&membership);
|
||
|
||
<span class="emphasis"><em>/* Destroy data structures at the end. */</em></span>
|
||
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&membership);
|
||
<span class="strong"><strong><a class="link" href="igraph-Basic.html#igraph_destroy" title="5.1.4. igraph_destroy — Frees the memory allocated for a graph object.">igraph_destroy</a></strong></span>(&graph);
|
||
|
||
<span class="strong"><strong>return</strong></span> 0;
|
||
}
|
||
</pre>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
<br class="example-break">
|
||
</div>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="infomap-algorithm"></a>9. The InfoMAP algorithm</h2></div></div></div>
|
||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="igraph-Community.html#igraph_community_infomap">9.1. <code class="function">igraph_community_infomap</code> — Community structure that minimizes the expected description length of a random walker trajectory.</a></span></dt></dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_infomap"></a>9.1. <code class="function">igraph_community_infomap</code> — Community structure that minimizes the expected description length of a random walker trajectory.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.13.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_infomap(
|
||
const igraph_t *graph,
|
||
const igraph_vector_t *edge_weights,
|
||
const igraph_vector_t *vertex_weights,
|
||
igraph_int_t nb_trials,
|
||
igraph_bool_t is_regularized,
|
||
igraph_real_t regularization_strength,
|
||
igraph_vector_int_t *membership,
|
||
igraph_real_t *codelength);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
Implementation of the Infomap community detection algorithm of
|
||
Martin Rosvall and Carl T. Bergstrom. This algorithm takes edge directions
|
||
into account. For more details, see the visualization of the math and the
|
||
map generator at <a class="ulink" href="https://www.mapequation.org" target="_top">https://www.mapequation.org</a>.
|
||
|
||
</p>
|
||
<p>
|
||
Infomap is based on a random walker model similar to PageRank: the walker
|
||
either chooses out-edges to follow with probabilities proportional to edge
|
||
weights, or teleports to a random vertex with probability 0.15. Vertex weights
|
||
can be given to control the probability of choosing different vertices as
|
||
the target of the teleportation. In addition, Infomap can be regularized to
|
||
account for potential missing links.
|
||
|
||
</p>
|
||
<p>
|
||
As of igraph 1.0, the Infomap library written by Daniel Edler, Anton Holmgren
|
||
and Martin Rosvall is used. See <a class="ulink" href="https://github.com/mapequation/infomap/" target="_top">https://github.com/mapequation/infomap/</a>.
|
||
|
||
</p>
|
||
<p>
|
||
If you want to specify a random seed (as in the original
|
||
implementation) you can use <a class="link" href="igraph-Random.html#igraph_rng_seed" title="3.3. igraph_rng_seed — Seeds a random number generator."><code class="function">igraph_rng_seed()</code></a>.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
M. Rosvall and C. T. Bergstrom:
|
||
Maps of information flow reveal community structure in complex networks,
|
||
PNAS 105, 1118 (2008).
|
||
<a class="ulink" href="https://dx.doi.org/10.1073/pnas.0706851105" target="_top">https://dx.doi.org/10.1073/pnas.0706851105</a>, <a class="ulink" href="https://arxiv.org/abs/0707.0609" target="_top">https://arxiv.org/abs/0707.0609</a>
|
||
|
||
</p>
|
||
<p>
|
||
M. Rosvall, D. Axelsson, and C. T. Bergstrom:
|
||
The map equation,
|
||
Eur. Phys. J. Special Topics 178, 13 (2009).
|
||
<a class="ulink" href="https://dx.doi.org/10.1140/epjst/e2010-01179-1" target="_top">https://dx.doi.org/10.1140/epjst/e2010-01179-1</a>, <a class="ulink" href="https://arxiv.org/abs/0906.1405" target="_top">https://arxiv.org/abs/0906.1405</a>
|
||
|
||
</p>
|
||
<p>
|
||
Smiljanić, Jelena, Daniel Edler, and Martin Rosvall: Mapping Flows on
|
||
Sparse Networks with Missing Links. Phys Rev E 102 (1–1): 012302 (2020).
|
||
<a class="ulink" href="https://doi.org/10.1103/PhysRevE.102.012302" target="_top">https://doi.org/10.1103/PhysRevE.102.012302</a>, <a class="ulink" href="https://arxiv.org/abs/2106.14798" target="_top">https://arxiv.org/abs/2106.14798</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. Edge directions are taken into account.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>edge_weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector giving the weights of the edges.
|
||
The random walker will favour edges with high weights over
|
||
edges with low weights; the probability of picking a particular
|
||
outbound edge from a node is directly proportional to its weight.
|
||
If it is <code class="constant">NULL</code> then all edges will have equal
|
||
weights. The weights are expected to be non-negative.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>vertex_weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Numeric vector giving the weights of the vertices.
|
||
Vertices with higher weights are favoured by the random walker
|
||
when it teleports to a new vertex. The probability of picking a vertex
|
||
when the random walker teleports is directly proportional to the weight
|
||
of the vertex. If this argument is <code class="constant">NULL</code> then all vertices will have
|
||
equal weights. Weights are expected to be positive.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>nb_trials</code></em>:</span></p></td>
|
||
<td><p>
|
||
The number of attempts to partition the network
|
||
(can be any integer value equal to or larger than 1).
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>is_regularized</code></em>:</span></p></td>
|
||
<td><p>
|
||
If true, adds a fully connected Bayesian prior network
|
||
to avoid overfitting due to missing links.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>regularization_strength</code></em>:</span></p></td>
|
||
<td><p>
|
||
Adjust relative strength of the Bayesian prior
|
||
network used for regularization. This multiplies the default strength, a
|
||
parameter of 1 hence uses the default regularization strength. Ignored
|
||
when <em class="parameter"><code>is_regularized</code></em> is set to <code class="constant">false</code>.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a vector. The membership vector is
|
||
stored here. <code class="constant">NULL</code> means that the caller is not interested in the
|
||
membership vector.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>codelength</code></em>:</span></p></td>
|
||
<td><p>
|
||
Pointer to a real. If not <code class="constant">NULL</code> the code length of the
|
||
partition is stored here.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
When Infomap is not available, <code class="constant">IGRAPH_UNIMPLEMENTED</code> is returned.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Community.html#igraph_community_spinglass" title="2.1. igraph_community_spinglass — Community detection based on statistical mechanics."><code class="function">igraph_community_spinglass()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_edge_betweenness" title="5.1. igraph_community_edge_betweenness — Community finding based on edge betweenness."><code class="function">igraph_community_edge_betweenness()</code></a>, <a class="link" href="igraph-Community.html#igraph_community_walktrap" title="4.1. igraph_community_walktrap — Community finding using a random walk based similarity measure."><code class="function">igraph_community_walktrap()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: TODO.
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="voronoi-communities"></a>10. Voronoi communities</h2></div></div></div>
|
||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="igraph-Community.html#igraph_community_voronoi">10.1. <code class="function">igraph_community_voronoi</code> — Finds communities using Voronoi partitioning.</a></span></dt></dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="igraph_community_voronoi"></a>10.1. <code class="function">igraph_community_voronoi</code> — Finds communities using Voronoi partitioning.</h3></div></div></div>
|
||
<a class="indexterm" name="id-1.26.14.2.2"></a><p>
|
||
</p>
|
||
<div class="informalexample"><pre class="programlisting">
|
||
igraph_error_t igraph_community_voronoi(
|
||
const igraph_t *graph,
|
||
igraph_vector_int_t *membership, igraph_vector_int_t *generators,
|
||
igraph_real_t *modularity,
|
||
const igraph_vector_t *lengths, const igraph_vector_t *weights,
|
||
igraph_neimode_t mode, igraph_real_t r);
|
||
</pre></div>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
|
||
|
||
|
||
</p>
|
||
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
|
||
<h3 class="title">Warning</h3>
|
||
<p>This function is experimental and its signature is not considered final yet.
|
||
We reserve the right to change the function signature without changing the
|
||
major version of igraph. Use it at your own risk.</p>
|
||
</div>
|
||
<p>This function finds communities using a Voronoi partitioning of vertices based
|
||
on the given edge lengths divided by the edge clustering coefficient
|
||
(<a class="link" href="igraph-Structural.html#igraph_ecc" title="17.5. igraph_ecc — Edge clustering coefficient of some edges."><code class="function">igraph_ecc()</code></a>). The generator vertices are chosen to be those with the
|
||
largest local relative density within a radius <em class="parameter"><code>r</code></em>, with the local relative
|
||
density of a vertex defined as
|
||
<code class="literal">s m / (m + k)</code>, where <code class="constant">s</code> is the strength of the vertex,
|
||
<code class="constant">m</code> is the number of edges within the vertex's first order neighborhood,
|
||
while <code class="constant">k</code> is the number of edges with only one endpoint within this
|
||
neighborhood.
|
||
|
||
</p>
|
||
<p>
|
||
References:
|
||
|
||
</p>
|
||
<p>
|
||
Deritei et al., Community detection by graph Voronoi diagrams,
|
||
New Journal of Physics 16, 063007 (2014)
|
||
<a class="ulink" href="https://doi.org/10.1088/1367-2630/16/6/063007" target="_top">https://doi.org/10.1088/1367-2630/16/6/063007</a>
|
||
|
||
</p>
|
||
<p>
|
||
Molnár et al., Community Detection in Directed Weighted Networks using Voronoi Partitioning,
|
||
Scientific Reports 14, 8124 (2024)
|
||
<a class="ulink" href="https://doi.org/10.1038/s41598-024-58624-4" target="_top">https://doi.org/10.1038/s41598-024-58624-4</a>
|
||
|
||
</p>
|
||
<p><b>Arguments: </b>
|
||
</p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>graph</code></em>:</span></p></td>
|
||
<td><p>
|
||
The input graph. It must be simple.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>membership</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not <code class="constant">NULL</code>, the membership of each vertex is returned here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>generators</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not <code class="constant">NULL</code>, the generator points used for Voronoi partitioning are returned here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>modularity</code></em>:</span></p></td>
|
||
<td><p>
|
||
If not <code class="constant">NULL</code>, the modularity score of the partitioning is returned here.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>lengths</code></em>:</span></p></td>
|
||
<td><p>
|
||
Edge lengths, or <code class="constant">NULL</code> to consider all edges as having unit length.
|
||
Voronoi partitioning will use edge lengths equal to lengths / ECC where ECC is the edge
|
||
clustering coefficient.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>weights</code></em>:</span></p></td>
|
||
<td><p>
|
||
Edge weights, or <code class="constant">NULL</code> to consider all edges as having unit weight.
|
||
Weights are used when selecting generator points, as well as for computing modularity.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>mode</code></em>:</span></p></td>
|
||
<td><p>
|
||
If <code class="constant">IGRAPH_OUT</code>, distances from generator points to all other nodes are considered.
|
||
If <code class="constant">IGRAPH_IN</code>, the reverse distances are used. If <code class="constant">IGRAPH_ALL</code>, edge directions are ignored.
|
||
This parameter is ignored for undirected graphs.
|
||
</p></td>
|
||
</tr>
|
||
<tr>
|
||
<td><p><span class="term"><em class="parameter"><code>r</code></em>:</span></p></td>
|
||
<td><p>
|
||
The radius/resolution to use when selecting generator points. The larger this value, the
|
||
fewer partitions there will be. Pass in a negative value to automatically select the radius
|
||
that maximizes modularity.
|
||
</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
<p>
|
||
</p>
|
||
<p><b>Returns: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
Error code.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
</p>
|
||
<p><b>See also: </b></p>
|
||
<div class="variablelist"><table border="0" class="variablelist">
|
||
<colgroup>
|
||
<col align="left" valign="top">
|
||
<col>
|
||
</colgroup>
|
||
<tbody><tr>
|
||
<td><p><span class="term"><em class="parameter"><code></code></em></span></p></td>
|
||
<td><p>
|
||
<a class="link" href="igraph-Structural.html#igraph_voronoi" title="3.28. igraph_voronoi — Voronoi partitioning of a graph."><code class="function">igraph_voronoi()</code></a>, <a class="link" href="igraph-Structural.html#igraph_ecc" title="17.5. igraph_ecc — Edge clustering coefficient of some edges."><code class="function">igraph_ecc()</code></a>.
|
||
</p></td>
|
||
</tr></tbody>
|
||
</table></div>
|
||
<p>
|
||
|
||
Time complexity: TODO.
|
||
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<table class="navigation-footer" width="100%" summary="Navigation footer" cellpadding="2" cellspacing="0"><tr valign="middle">
|
||
<td align="left"><a accesskey="p" href="igraph-Separators.html"><b>← Chapter 24. Vertex separators</b></a></td>
|
||
<td align="right"><a accesskey="n" href="igraph-Graphlets.html"><b>Chapter 26. Graphlets →</b></a></td>
|
||
</tr></table>
|
||
</body>
|
||
</html>
|