Repository navigation
LaNet-vi 5.3.0
LaNet-vi 5.3.0 — k-connectivity, and a minute becomes 26 seconds
LaNet-vi draws large networks by their k-core, k-dense and d-core decomposition: nodes in concentric rings by shell index, so the structure of a graph with a hundred thousand nodes is readable at a glance (Alvarez-Hamelin, Dall'Asta, Barrat & Vespignani, NIPS 2005; the C++ tool of Mariano Beiró and Ignacio Alvarez-Hamelin). 5.1.0 brought the original algorithms back and 5.2.0 closed the option-by-option comparison; 5.3.0 ports the last planned feature of the C++ tool, the k-connectivity analysis of the shells, and makes the whole pipeline two to three times faster on large graphs. Documentation: https://conexdat.github.io/LaNet-vi/.
pip install --upgrade lanet-vi
lanet-vi visualize --input edges.txt --output network.png --kconn--kconn: which shells are really k-connected
The C++ -kconn (Beiró, Alvarez-Hamelin & Busch, A low complexity visualization tool that helps to perform complex systems analysis, New J. Phys. 10, 2008). A node of the k-shell has degree at least k inside its core, but that does not make its cluster k-connected to the center of the network. The analysis walks the component tree from the top core down: the first cluster of diameter ≤ 2 seeds a k-connected set, and at every lower index a cluster joins when its graph with the set contracted has diameter ≤ 2 and enough of its nodes touch the set (or the cut condition of the paper holds). Nodes that never join are painted black on white / white on black, and drawn as squares in the bw / bwi schemes, exactly as the C++ did. --kconn-type wide (default) gives a skipped cluster another chance at every lower index; strict drops it. --kconn-file writes node shell k_connectivity lines (the C++ log/kconn.log); in Python, Network.compute_kconnectivity().
A synthetic network — ten dense blocks of 60 to 8 nodes hanging from a sparse random tree — with --kconn (left, wide) and --kconn --kconn-type strict (right). The disconnected blocks are never k-connected to the center; wide reaches the periphery through the 1-shell, where the diameter condition does not apply, and strict keeps only the top core:
On the Internet AS-level topology (CAIDA AS relationships, October 2025: 78,370 ASes, 489,407 links) wide finds every AS k-connected (803 of them at a lower index than their shell) and strict leaves 1,841 out, all in shells 1–4 — white dots on the rim of this picture:
The port was verified against a literal transcription of the C++ loops on 2,400 random graphs. Two things of the C++ are not reproduced: its crash on a shell without clusters and the shell == 77 debugging escape of the strict seed. Like the C++, --kconn is for the k-cores of a simple, unweighted, undirected graph.
Faster on large graphs
The CAIDA graph above took about a minute in 5.2.0 and takes about 26 s now, with the same decomposition and the same pictures up to the random arrangement of a shell:
| Stage | 5.2.0 | 5.3.0 |
|---|---|---|
| k-core decomposition | 7.3 s | 1.8 s |
| component tree of the layout | 25 s | 1.7 s |
compute_layout() |
30 s | 7 s |
| rasterization | twice | once |
- The nested component tree that drives the layout (and now the k-connectivity) is built in one union-find pass over the edges grouped by index; the old traversal re-walked the top of the hierarchy once per level (34 million edge visits on CAIDA).
- The k-core numbers come from a bucket peeling (Batagelj–Zaversnik) for every graph type;
nx.core_numberdeletes neighbors from lists. Identical results, checked againstnx.core_numberand against brute force on multigraphs. - The connected pieces of every level are found in one pass (
lanet_vi.decomposition.components.components_by_index, shared by the three decompositions) instead of one induced subgraph per level. - The figure is rasterized once:
plt.savefigredraws the whole figure after saving;fig.savefigdoes not.
What remains is matplotlib drawing half a million edge segments, which is the picture itself.
Compatibility
The Python API is unchanged; new members: Network.compute_kconnectivity(), Network.kconnectivity, lanet_vi.decomposition.kconnectivity.compute_kconnectivity, lanet_vi.decomposition.components.components_by_index, lanet_vi.union_find.UnionFind, lanet_vi.visualization.lanet_layout.component_tree. Because sibling components and clusters are now ordered by their first node in graph order, a picture drawn with a given --seed is not byte-identical to the one 5.2.0 drew (it is the same picture up to the random arrangement inside a shell), and --kconn can assign another value to a few nodes for the same seed. The JSON export lists the components of a level in that order. A negative node index or an edge index above one of its endpoints handed to build_component_tree is now a ValueError.
Still open
Nothing from the C++ comparison: the Gomory-Hu connectivity report and the POV-Ray scenes were closed as won't-fix (#25), and this release ports the last planned feature (#47). Community detection and the random generators remain NetworkX-based replacements (#26). The full list of changes is in CHANGELOG.md.
Credits
LaNet-vi is the work of J. Ignacio Alvarez-Hamelin, Mariano G. Beiró, Luca Dall'Asta, Alain Barrat and Alessandro Vespignani; the C++ sources (2005–2016) are the reference for every port. CAIDA AS relationships data: https://www.caida.org/catalog/datasets/as-relationships/.

