Files
agent_compositor_test/references/igraph-1.0.1/doc/html/igraph-Community.html
T
Abdelrahman Said a11edf0c53 Add graph references
2026-06-28 13:49:01 +01:00

4544 lines
209 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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. 35 (2010): 75174.
<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): 144.
<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> &lt;igraph.h&gt;
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>(&amp;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>(&amp;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>(&amp;<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>(&amp;graph, NULL, 1, &amp;modularity, &amp;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>(&amp;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>(&amp;graph);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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) &gt;= 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> &lt;igraph.h&gt;
<span class="strong"><strong>#include</strong></span> &lt;stdio.h&gt;
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>(&amp;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>(&amp;merges, 0, 0);
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&amp;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>(&amp;g, <span class="emphasis"><em>/*weights=*/</em></span> NULL,
&amp;merges, &amp;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>(&amp;merges);
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&amp;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>(&amp;g, <span class="emphasis"><em>/*weights=*/</em></span> NULL,
&amp;merges, &amp;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>(&amp;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>(&amp;merges);
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&amp;membership);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;membership);
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&amp;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>(&amp;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> &lt;igraph.h&gt;
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>(&amp;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>(&amp;modularity, 0);
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&amp;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>(&amp;g,
NULL <span class="emphasis"><em>/* no weights */</em></span>,
4 <span class="emphasis"><em>/* steps */</em></span>,
&amp;merges, &amp;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>(&amp;g);
<span class="strong"><strong>printf</strong></span>("Merges:\n");
<span class="strong"><strong>for</strong></span> (i = 0; i &lt; <span class="strong"><strong>igraph_matrix_int_nrow</strong></span>(&amp;merges); i++) {
<span class="strong"><strong>printf</strong></span>("%2.1" IGRAPH_PRId " + %2." IGRAPH_PRId " -&gt; %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>(&amp;g);
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&amp;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>(&amp;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> &lt;igraph.h&gt;
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>(&amp;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>(&amp;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>(&amp;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>(&amp;eb, 0);
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&amp;edges, 0);
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&amp;merges, 0, 0);
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&amp;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>(&amp;graph, &amp;edges, &amp;eb, &amp;merges,
&amp;bridges, <span class="emphasis"><em>/*modularity*/</em></span> NULL,
<span class="emphasis"><em>/*membership*/</em></span> NULL,
IGRAPH_UNDIRECTED,
&amp;weights,
NULL);
<span class="strong"><strong>printf</strong></span>("edges:\n");
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&amp;edges);
<span class="strong"><strong>printf</strong></span>("edge betweenness:\n");
<span class="strong"><strong>igraph_vector_print</strong></span>(&amp;eb);
<span class="strong"><strong>printf</strong></span>("merges:\n");
<span class="strong"><strong>igraph_matrix_int_print</strong></span>(&amp;merges);
<span class="strong"><strong>printf</strong></span>("bridges:\n");
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&amp;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>(&amp;graph);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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>(&amp;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>(&amp;weights);
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&amp;merges);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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> &lt;igraph.h&gt;
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>(&amp;merges, 0, 0);
<span class="strong"><strong>igraph_vector_init_int</strong></span>(&amp;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>(&amp;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>(&amp;graph, &amp;weights, &amp;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>(&amp;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>(&amp;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>(&amp;weights);
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&amp;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., &amp; 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> &lt;igraph.h&gt;
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 &lt; <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 &lt; <span class="strong"><strong>igraph_matrix_int_nrow</strong></span>(memberships); i++) {
<span class="strong"><strong>for</strong></span> (j = 0; j &lt; 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>(&amp;modularity, 0);
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&amp;membership, 0);
<span class="strong"><strong>igraph_matrix_int_init</strong></span>(&amp;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>(&amp;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>(&amp;g, 0, 1, &amp;membership, &amp;memberships, &amp;modularity);
<span class="strong"><strong>show_results</strong></span>(&amp;g, &amp;membership, &amp;memberships, &amp;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>(&amp;g, 0, 1.5, &amp;membership, &amp;memberships, &amp;modularity);
<span class="strong"><strong>show_results</strong></span>(&amp;g, &amp;membership, &amp;memberships, &amp;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>(&amp;g);
<span class="emphasis"><em>/* Ring of 30 cliques */</em></span>
<span class="strong"><strong>igraph_vector_int_init</strong></span>(&amp;edges, 0);
<span class="strong"><strong>for</strong></span> (i = 0; i &lt; 30; i++) {
<span class="strong"><strong>for</strong></span> (j = 0; j &lt; 5; j++) {
<span class="strong"><strong>for</strong></span> (k = j + 1; k &lt; 5; k++) {
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&amp;edges, i * 5 + j);
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&amp;edges, i * 5 + k);
}
}
}
<span class="strong"><strong>for</strong></span> (i = 0; i &lt; 30; i++) {
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&amp;edges, i * 5 % 150);
<span class="strong"><strong>igraph_vector_int_push_back</strong></span>(&amp;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>(&amp;g, &amp;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>(&amp;g, 0, 1, &amp;membership, &amp;memberships, &amp;modularity);
<span class="strong"><strong>show_results</strong></span>(&amp;g, &amp;membership, &amp;memberships, &amp;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>(&amp;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>(&amp;modularity);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;membership);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;edges);
<span class="strong"><strong>igraph_matrix_int_destroy</strong></span>(&amp;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 &amp; 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 &amp; 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> &lt;igraph.h&gt;
<span class="strong"><strong>#include</strong></span> &lt;stdio.h&gt;
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>(&amp;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>(&amp;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>(&amp;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>(&amp;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,
&amp;membership, &amp;nb_clusters, &amp;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>(&amp;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>(&amp;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,
&amp;membership, &amp;nb_clusters, &amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;graph, &amp;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>(&amp;graph, NULL, &amp;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>(&amp;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,
&amp;membership, &amp;nb_clusters, &amp;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>(&amp;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>(&amp;vertex_weights);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;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>(&amp;graph, &amp;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>(&amp;graph, &amp;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>(&amp;graph, NULL, &amp;vertex_out_weights, &amp;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>(&amp;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,
&amp;membership, &amp;nb_clusters, &amp;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>(&amp;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>(&amp;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>(&amp;vertex_out_weights);
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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>(&amp;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
&amp; 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
&amp; 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> &lt;igraph.h&gt;
<span class="strong"><strong>#include</strong></span> &lt;stdio.h&gt;
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>(&amp;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>(&amp;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>(
&amp;graph, &amp;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>(
&amp;graph, &amp;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, &amp;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>(&amp;membership) + 1, modularity);
<span class="strong"><strong>printf</strong></span>("Communities membership: ");
<span class="strong"><strong>igraph_vector_int_print</strong></span>(&amp;membership);
<span class="emphasis"><em>/* Destroy data structures at the end. */</em></span>
<span class="strong"><strong>igraph_vector_int_destroy</strong></span>(&amp;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>(&amp;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 (11): 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>