1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
//! Graph density - measures how dense or sparse a graph is.
//!
//! It is defined as the ratio of the number of edges in the graph to the total number of possible
//! edges. A dense graph has a high edge-to-node ratio, while a sparse graph has a low
//! edge-to-node ratio.
//!
//! For example in social network analysis, a dense graph may indicate a highly interconnected
//! community_detection, while a sparse graph may indicate more isolated individuals.
//!
//! # Examples
//!
//! ```rust
//! use raphtory::algorithms::metrics::directed_graph_density::directed_graph_density;
//! use raphtory::prelude::*;
//!
//! let g = Graph::new();
//! let windowed_graph = g.window(0, 7);
//! let vs = vec![
//! (1, 1, 2),
//! (2, 1, 3),
//! (3, 2, 1),
//! (4, 3, 2),
//! (5, 1, 4),
//! (6, 4, 5),
//! ];
//!
//! for (t, src, dst) in &vs {
//! g.add_edge(*t, *src, *dst, NO_PROPS, None);
//! }
//!
//! println!("graph density: {:?}", directed_graph_density(&windowed_graph));
//! ```
//!
use crate::db::api::view::*;
/// Measures how dense or sparse a graph is
pub fn directed_graph_density<'graph, G: GraphViewOps<'graph>>(graph: &G) -> f32 {
graph.count_edges() as f32 / (graph.count_nodes() as f32 * (graph.count_nodes() as f32 - 1.0))
}
#[cfg(test)]
mod directed_graph_density_tests {
use super::*;
use crate::{
db::{api::mutation::AdditionOps, graph::graph::Graph},
prelude::NO_PROPS,
test_storage,
};
#[test]
fn low_graph_density() {
let graph = Graph::new();
let vs = vec![
(1, 1, 2),
(2, 1, 3),
(3, 2, 1),
(4, 3, 2),
(5, 1, 4),
(6, 4, 5),
];
for (t, src, dst) in &vs {
graph.add_edge(*t, *src, *dst, NO_PROPS, None).unwrap();
}
test_storage!(&graph, |graph| {
let windowed_graph = graph.window(0, 7);
let actual = directed_graph_density(&windowed_graph);
let expected = 0.3;
assert_eq!(actual, expected);
});
}
#[test]
fn complete_graph_has_graph_density_of_one() {
let graph = Graph::new();
let vs = vec![(1, 1, 2), (2, 2, 1)];
for (t, src, dst) in &vs {
graph.add_edge(*t, *src, *dst, NO_PROPS, None).unwrap();
}
test_storage!(&graph, |graph| {
let windowed_graph = graph.window(0, 3);
let actual = directed_graph_density(&windowed_graph);
let expected = 1.0;
assert_eq!(actual, expected);
});
}
}