Skip to content

Centrality Examples

Use various centrality measures to identify important nodes in a graph.

Degree Centrality

Computes the centrality of nodes based on the number of connections.

use graphina::centrality::degree::{degree_centrality, in_degree_centrality, out_degree_centrality};
use graphina::core::types::{Graph, Digraph};

fn main() {
    // 1. Undirected Degree
    let mut g = Graph::new();
    let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
    g.add_edge(nodes[0], nodes[1], ());
    g.add_edge(nodes[0], nodes[2], ());

    let cent = degree_centrality(&g).unwrap();
    println!("Node 1 degree: {}", cent[&nodes[0]]); // 2.0

    // 2. Directed In/Out Degree
    let mut dg = Digraph::new();
    let dnodes = [dg.add_node(1), dg.add_node(2)];
    dg.add_edge(dnodes[0], dnodes[1], ());

    let in_cent = in_degree_centrality(&dg).unwrap();
    let out_cent = out_degree_centrality(&dg).unwrap();

    println!("Node 1 Out-Degree: {}", out_cent[&dnodes[0]]); // 1.0
    println!("Node 2 In-Degree: {}", in_cent[&dnodes[1]]);   // 1.0
}

PageRank

Detailed example of computing PageRank on a directed graph.

use graphina::centrality::pagerank::pagerank;
use graphina::core::types::Digraph;

fn page_rank_example() {
    let mut graph = Digraph::new();
    let nodes = (0..5).map(|i| graph.add_node(i)).collect::<Vec<_>>();

    // Create a citation-like structure
    let edges = [(0, 1, 1.0), (0, 2, 1.0), (1, 3, 1.0)];
    for (s, d, w) in edges {
        graph.add_edge(nodes[s], nodes[d], w);
    }

    // Compute PageRank (damping: 0.85, iter: 1000, tol: 1e-6)
    let scores = pagerank(&graph, 0.85, 1000, 1e-6_f64, None).unwrap();

    for n in nodes {
        println!("Node {:?}: {:.4}", n, scores[&n]);
    }
}

Eigenvector Centrality

Measures influence by looking at connections to other high-scoring nodes.

use graphina::centrality::eigenvector::eigenvector_centrality;
use graphina::core::types::Graph;

fn main() {
    let mut g = Graph::new();
    let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
    g.add_edge(nodes[0], nodes[1], 1.0);
    g.add_edge(nodes[0], nodes[2], 2.0);

    let scores = eigenvector_centrality(&g, 1000, 1e-6).expect("Failed to converge");

    // Node 0 is connected to both 1 and 2, so it should be most central
    assert!(scores[&nodes[0]] > scores[&nodes[1]]);
}

Katz Centrality

A generalization of degree centrality that counts paths of all lengths, penalized by an attenuation factor \(\alpha\).

use graphina::centrality::katz::katz_centrality;
use graphina::core::types::Graph;

fn main() {
    let mut g = Graph::new();
    let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
    g.add_edge(nodes[0], nodes[1], 1.0);
    g.add_edge(nodes[0], nodes[2], 2.0);

    // alpha = 0.1, beta = 1.0
    let scores = katz_centrality(&g, 0.1, Some(&|_| 1.0), 1000, 1e-6).unwrap();

    println!("Node 1 Katz Score: {:.4}", scores[&nodes[0]]);
}

Closeness Centrality

Based on the average shortest path distance to all other nodes.

use graphina::centrality::closeness::closeness_centrality;
use graphina::core::types::Graph;
use ordered_float::OrderedFloat;

fn main() {
    let mut graph: Graph<i32, OrderedFloat<f64>> = Graph::new();
    let nodes = (0..5).map(|i| graph.add_node(i)).collect::<Vec<_>>();
    let edges = [
        (0, 1, OrderedFloat(1.0)),
        (0, 2, OrderedFloat(1.0)),
        (1, 3, OrderedFloat(1.0))
    ];

    for (s, d, w) in edges {
        graph.add_edge(nodes[s], nodes[d], w);
    }

    let scores = closeness_centrality(&graph).unwrap();
    println!("Node 0 Closeness: {:.4}", scores[&nodes[0]]);
}