use crate::graph::builders::GraphBuilder;
use crate::graph::Graph;
pub fn barabasi_albert_graph<T>(n: usize, m: usize) -> Graph<T, f64>
where
T: Clone + Default,
{
if n == 0 {
return Graph::directed();
}
let mut builder = GraphBuilder::undirected();
let initial_size = (m + 1).min(n);
builder = builder.with_nodes((0..initial_size).map(|_| T::default()));
for i in 0..initial_size {
for j in (i + 1)..initial_size {
builder = builder.with_edge(i, j, 1.0);
}
}
for new_node in initial_size..n {
builder = builder.with_nodes(std::iter::once(T::default()));
for node_idx in 0..m.min(new_node) {
builder = builder.with_edge(node_idx, new_node, 1.0);
}
#[cfg(feature = "rand")]
{
use rand::Rng;
let mut rng = rand::thread_rng();
let mut connected = m.min(new_node);
while connected < m && connected < new_node {
let random_node = rng.gen_range(0..new_node);
builder = builder.with_edge(random_node, new_node, 1.0);
connected += 1;
}
}
}
builder.build().unwrap_or_else(|_| Graph::directed())
}