Skip to content

Commit fb61051

Browse files
committed
docs
1 parent 7180cd6 commit fb61051

File tree

7 files changed

+620
-6
lines changed

7 files changed

+620
-6
lines changed

doc/louvain_clustering.html

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2+
<!--
3+
Copyright (c) 2026 Arnaud Becheler
4+
5+
Distributed under the Boost Software License, Version 1.0.
6+
(See accompanying file LICENSE_1_0.txt or copy at
7+
http://www.boost.org/LICENSE_1_0.txt)
8+
-->
9+
<HTML>
10+
<Head>
11+
<Title>Boost Graph Library: Louvain Clustering</Title>
12+
</Head>
13+
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
14+
ALINK="#ff0000">
15+
<IMG SRC="../../../boost.png"
16+
ALT="C++ Boost" width="277" height="86">
17+
18+
<BR Clear>
19+
20+
<H1><A NAME="sec:louvain-clustering"></A>
21+
<TT>louvain_clustering</TT>
22+
</H1>
23+
24+
<PRE>
25+
template &lt;typename QualityFunction = newman_and_girvan,
26+
typename Graph, typename ComponentMap,
27+
typename WeightMap, typename URBG&gt;
28+
typename property_traits&lt;WeightMap&gt;::value_type
29+
louvain_clustering(const Graph&amp; g,
30+
ComponentMap components,
31+
const WeightMap&amp; w,
32+
URBG&amp;&amp; gen,
33+
typename property_traits&lt;WeightMap&gt;::value_type min_improvement_inner = 0,
34+
typename property_traits&lt;WeightMap&gt;::value_type min_improvement_outer = 0);
35+
</PRE>
36+
37+
<P>
38+
This algorithm implements the Louvain method for community detection
39+
[<a href="#references">1</a>]. It finds a partition of the vertices into communities
40+
that approximately maximizes a quality function (by default,
41+
<a href="louvain_quality_functions.html#newman_and_girvan">Newman&ndash;Girvan
42+
modularity</a>).
43+
44+
<P>The algorithm alternates two phases:
45+
<OL>
46+
<LI><B>Local optimization.</B> Each vertex is moved to the neighboring
47+
community that yields the largest improvement in the quality function.
48+
Vertices are visited in random order and the process repeats until no
49+
single-vertex move improves the quality by more than
50+
<TT>min_improvement_inner</TT>.
51+
52+
<LI><B>Aggregation.</B> The graph is contracted by collapsing each
53+
community into a single super-vertex. Edge weights between
54+
super-vertices are the sums of the original inter-community edge
55+
weights and self-loops carry the total intra-community weight.
56+
</OL>
57+
58+
<P> These two phases are applied repeatedly on the coarsened graph,
59+
discovering communities of communities, until
60+
the quality improvement between successive levels falls below
61+
<TT>min_improvement_outer</TT>, or the graph can no longer be
62+
coarsened.
63+
64+
<P> Once every level has converged, the algorithm iterates
65+
from the coarsest aggregated graph down to the original graph to
66+
trace assignment of vertices to communities to produce the final
67+
community label written into <TT>components</TT>.
68+
69+
<P> The speed of the local optimization phase depends on the quality
70+
function's interface. A quality function that only models
71+
<a href="louvain_quality_functions.html#base_concept">
72+
<TT>GraphPartitionQualityFunctionConcept</TT></a> requires a full
73+
O(V+E) recomputation of the quality for every candidate vertex move.
74+
A quality function that also models
75+
<a href="louvain_quality_functions.html#incremental_concept">
76+
<TT>GraphPartitionQualityFunctionIncrementalConcept</TT></a>
77+
evaluates each candidate move in O(1) using incremental
78+
bookkeeping, making the total cost per vertex O(degree).
79+
The algorithm detects which interface is available at
80+
compile time and selects the appropriate code path automatically.
81+
82+
<H3>Where Defined</H3>
83+
84+
<P>
85+
<a href="../../../boost/graph/louvain_clustering.hpp"><TT>boost/graph/louvain_clustering.hpp</TT></a>
86+
87+
<H3>Parameters</H3>
88+
89+
IN: <tt>const Graph&amp; g</tt>
90+
<blockquote>
91+
An undirected graph. Must model
92+
<a href="VertexListGraph.html">Vertex List Graph</a> and
93+
<a href="IncidenceGraph.html">Incidence Graph</a>.
94+
The graph is not modified by the algorithm.
95+
Passing a directed graph produces a compile-time error.
96+
</blockquote>
97+
98+
OUT: <tt>ComponentMap components</tt>
99+
<blockquote>
100+
Records the community each vertex belongs to. After the call,
101+
<tt>get(components, v)</tt> returns an identifier (a vertex
102+
descriptor of the original graph) for the community of vertex
103+
<tt>v</tt>. Two vertices with the same identifier are in the
104+
same community.<br>
105+
Must model
106+
<a href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write
107+
Property Map</a> with the graph's vertex descriptor as both key
108+
type and value type.
109+
</blockquote>
110+
111+
IN: <tt>const WeightMap&amp; w</tt>
112+
<blockquote>
113+
Edge weights. Must model
114+
<a href="../../property_map/doc/ReadablePropertyMap.html">Readable
115+
Property Map</a> with the graph's edge descriptor as key type.
116+
Weights must be non-negative.
117+
</blockquote>
118+
119+
IN: <tt>URBG&amp;&amp; gen</tt>
120+
<blockquote>
121+
A random number generator used to shuffle the vertex processing
122+
order at each pass. Any type meeting the C++
123+
<i>UniformRandomBitGenerator</i> requirements works
124+
(e.g.&nbsp;<tt>std::mt19937</tt>).
125+
</blockquote>
126+
127+
IN: <tt>weight_type min_improvement_inner</tt>
128+
<blockquote>
129+
The inner loop (local optimization) stops when a full pass over
130+
all vertices improves quality by less than this value.<br>
131+
<b>Default:</b> <tt>0</tt>
132+
</blockquote>
133+
134+
IN: <tt>weight_type min_improvement_outer</tt>
135+
<blockquote>
136+
The outer loop (aggregation) stops when quality improves by less
137+
than this value between successive levels.<br>
138+
<b>Default:</b> <tt>0</tt>
139+
</blockquote>
140+
141+
<H3>Template Parameters</H3>
142+
143+
<tt>QualityFunction</tt>
144+
<blockquote>
145+
The partition quality metric to maximize. Must model
146+
<a href="louvain_quality_functions.html#base_concept">
147+
<tt>GraphPartitionQualityFunctionConcept</tt></a>. If it also models
148+
<a href="louvain_quality_functions.html#incremental_concept">
149+
<tt>GraphPartitionQualityFunctionIncrementalConcept</tt></a>, the
150+
faster incremental code path is selected automatically.<br>
151+
<b>Default:</b>
152+
<tt><a href="louvain_quality_functions.html#newman_and_girvan">newman_and_girvan</a></tt>
153+
</blockquote>
154+
155+
<H3>Return Value</H3>
156+
<P>The quality (e.g.&nbsp;modularity) of the best partition found.
157+
For Newman&ndash;Girvan modularity this is a value in
158+
[&minus;0.5,&nbsp;1).
159+
160+
<H3>Complexity</H3>
161+
<P>With the incremental quality function (the default), each local
162+
optimization pass costs O(E) since every vertex is visited once and
163+
each visit scans its neighbors. With a non-incremental quality function,
164+
each candidate move requires a full O(V+E) traversal, making each pass
165+
O(E&nbsp;&middot;&nbsp;(V+E)). The number of passes per level and the
166+
number of aggregation levels are both small in practice, so the
167+
incremental path typically runs in O(E&nbsp;log&nbsp;V) overall on
168+
sparse graphs.
169+
170+
<H3>Preconditions</H3>
171+
<UL>
172+
<LI>The graph must be undirected (enforced at compile time).
173+
<LI>Edge weights must be non-negative.
174+
<LI>The graph must have a <TT>vertex_index</TT> property mapping
175+
vertices to contiguous integers in
176+
[0,&nbsp;<TT>num_vertices(g)</TT>).
177+
</UL>
178+
179+
<H3>Example</H3>
180+
<PRE>
181+
#include &lt;boost/graph/adjacency_list.hpp&gt;
182+
#include &lt;boost/graph/louvain_clustering.hpp&gt;
183+
#include &lt;random&gt;
184+
#include &lt;iostream&gt;
185+
186+
int main()
187+
{
188+
using Graph = boost::adjacency_list&lt;
189+
boost::vecS, boost::vecS, boost::undirectedS,
190+
boost::no_property,
191+
boost::property&lt;boost::edge_weight_t, double&gt;&gt;;
192+
193+
// Two triangles connected by a weak bridge
194+
Graph g(6);
195+
boost::add_edge(0, 1, 1.0, g);
196+
boost::add_edge(1, 2, 1.0, g);
197+
boost::add_edge(0, 2, 1.0, g);
198+
boost::add_edge(3, 4, 1.0, g);
199+
boost::add_edge(4, 5, 1.0, g);
200+
boost::add_edge(3, 5, 1.0, g);
201+
boost::add_edge(2, 3, 0.1, g);
202+
203+
using vertex_t = boost::graph_traits&lt;Graph&gt;::vertex_descriptor;
204+
std::vector&lt;vertex_t&gt; communities(boost::num_vertices(g));
205+
auto cmap = boost::make_iterator_property_map(
206+
communities.begin(), boost::get(boost::vertex_index, g));
207+
208+
std::mt19937 rng(42);
209+
double Q = boost::louvain_clustering(
210+
g, cmap, boost::get(boost::edge_weight, g), rng);
211+
212+
std::cout &lt;&lt; "Modularity: " &lt;&lt; Q &lt;&lt; "\n";
213+
for (auto v : boost::make_iterator_range(boost::vertices(g)))
214+
std::cout &lt;&lt; " vertex " &lt;&lt; v
215+
&lt;&lt; " -&gt; community " &lt;&lt; boost::get(cmap, v) &lt;&lt; "\n";
216+
}
217+
</PRE>
218+
219+
<H3>See Also</H3>
220+
<P>
221+
<a href="louvain_quality_functions.html">Louvain Quality Function Concepts</a>,
222+
<a href="bc_clustering.html"><TT>betweenness_centrality_clustering</TT></a>
223+
224+
<H3>References</H3>
225+
<a name="references"></a>
226+
<P>[1] V.&nbsp;D.&nbsp;Blondel, J.&#8209;L.&nbsp;Guillaume,
227+
R.&nbsp;Lambiotte, and E.&nbsp;Lefebvre,
228+
&ldquo;Fast unfolding of communities in large networks,&rdquo;
229+
<i>Journal of Statistical Mechanics: Theory and Experiment</i>,
230+
vol.&nbsp;2008, no.&nbsp;10, P10008, 2008.
231+
<a href="https://doi.org/10.1088/1742-5468/2008/10/P10008">doi:10.1088/1742-5468/2008/10/P10008</a>
232+
233+
<P>[2] V.&nbsp;A.&nbsp;Traag, L.&nbsp;Waltman, and
234+
N.&nbsp;J.&nbsp;van&nbsp;Eck,
235+
&ldquo;From Louvain to Leiden: guaranteeing well-connected communities,&rdquo;
236+
<i>Scientific Reports</i>, vol.&nbsp;9, 5233, 2019.
237+
<a href="https://doi.org/10.1038/s41598-019-41695-z">doi:10.1038/s41598-019-41695-z</a>
238+
239+
<BR>
240+
<HR>
241+
<TABLE>
242+
<TR valign=top>
243+
<TD nowrap>Copyright &copy; 2026</TD><TD>
244+
Arnaud Becheler
245+
</TD></TR></TABLE>
246+
247+
</BODY>
248+
</HTML>

0 commit comments

Comments
 (0)