Mix.install([
{:yog_ex, "~> 0.98"},
{:kino_vizjs, "~> 0.8.0"}
])Introduction
Network analysis allows us to understand the underlying structure of a graph. Who are the most influential actors? Are there distinct communities? Where are the bottlenecks that could cause the network to fail?
Yog provides professional-grade tools for these questions, used in everything from social network analysis to logistics.
Centrality: Who is Important?
Centrality measures tell us which nodes are the most "important," but "importance" can mean different things:
- Degree Centrality: Who has the most connections? (Popularity)
- Betweenness Centrality: Who acts as a bridge between groups? (Brokerage)
- Closeness Centrality: Who can reach everyone else fastest? (Efficiency)
- PageRank: Who is connected to other important nodes? (Influence)
# Create a "Bowtie" graph: two triangles connected by a bridge
g = Yog.undirected()
|> Yog.add_edges!([
{:a, :b, 1}, {:b, :c, 1}, {:c, :a, 1}, # Triangle 1
{:c, :d, 1}, # The Bridge
{:d, :e, 1}, {:e, :f, 1}, {:f, :d, 1} # Triangle 2
])
# 1. Degree Centrality
IO.inspect(Yog.Centrality.degree_total(g), label: "Degree")
# 2. Betweenness (Brokerage)
# Node :c and :d should have high scores as they bridge the two groups
IO.inspect(Yog.Centrality.betweenness(g), label: "Betweenness")
# 3. Closeness
IO.inspect(Yog.Centrality.closeness(g), label: "Closeness")
# 4. PageRank (Influence)
IO.inspect(Yog.Centrality.pagerank(g), label: "PageRank Scores")Community Detection
Community detection finds groups of nodes that are more densely connected to each other than to the rest of the network.
# Generate a random graph with built-in communities
# Using Stochastic Block Model (SBM)
g = Yog.Generator.Random.sbm([10, 10, 10], [[0.8, 0.1, 0.1], [0.1, 0.8, 0.1], [0.1, 0.1, 0.8]])
# Detect communities using the Louvain method
result = Yog.Community.Louvain.detect(g)
IO.puts "Found #{result.num_communities} communities."
IO.inspect(result.assignments, label: "Node -> Community")
# Visualize it! (We'll color nodes by community)
opts = Yog.Render.DOT.community_to_options(result)
Kino.VizJS.render(Yog.Render.DOT.to_dot(g, opts))Connectivity & Robustness
A network is only as strong as its weakest link. Yog can find Articulation Points (nodes whose removal increases the number of connected components) and Bridges (edges whose removal does the same).
g = Yog.undirected()
|> Yog.add_edges!([
{1, 2, 1}, {2, 3, 1}, {3, 1, 1}, # Component 1
{3, 4, 1}, # Bridge!
{4, 5, 1}, {5, 6, 1}, {6, 4, 1} # Component 2
])
# Find Articulation Points
# Nodes 3 and 4 are articulation points
aps = Yog.Connectivity.Articulation.find(g)
IO.inspect(aps, label: "Articulation Points")
# Find Bridges
# Edge {3, 4} is a bridge
bridges = Yog.Connectivity.Bridge.find(g)
IO.inspect(bridges, label: "Bridges")
# Visualize with articulation points highlighted
node_attrs = fn id, _data ->
if id in aps do
[{:fillcolor, "#ef4444"}, {:style, "filled"}, {:shape, "doublecircle"}]
else
[]
end
end
edge_attrs = fn u, v, _w ->
if {u, v} in bridges or {v, u} in bridges do
[{:color, "#ef4444"}, {:penwidth, 3}]
else
[]
end
end
dot = Yog.Render.DOT.to_dot(g,
Yog.Render.DOT.theme(:minimal)
|> Map.put(:node_attributes, node_attrs)
|> Map.put(:edge_attributes, edge_attrs)
)
Kino.VizJS.render(dot)Summary
Yog's network analysis toolkit includes:
- 9+ Centrality Measures for identifying key actors.
- State-of-the-art Community Detection (Louvain, Leiden, Infomap).
- Connectivity Analysis to identify vulnerabilities and bottlenecks.
Next, explore Network Flow to see how much "traffic" your network can handle!