Skip to content

Commit eb45f8f

Browse files
committed
WIP
1 parent fb51cb0 commit eb45f8f

16 files changed

+837
-241
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ tracing-subscriber = "0.3.19"
4444
petgraph = { version = "0.7.1", features = ["graphmap", "stable_graph", "matrix_graph", "serde-1", "rayon"] }
4545
rand = "0.9.0"
4646
sprs = "0.11.3"
47+
ordered-float = "5.0.0"
4748

4849
[dev-dependencies]
4950
criterion = { version = "0.5", features = ["html_reports"] }

README.md

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,14 @@ set of ready-to-use algorithms for graph analysis and mining.
2323
2424
## Features
2525

26-
* **Graphs**:
27-
- [x] Directed and undirected graphs
28-
- [x] Weighted and unweighted graphs
29-
30-
* **IO**:
31-
- [x] Edge list
32-
- [x] Adjacency list
33-
- [ ] GraphML
34-
- [ ] GML
35-
- [ ] JSON
36-
37-
* **Generators**:
38-
- [x] Erdős–Rényi Graph
39-
- [x] Complete Graph
40-
- [x] Bipartite Graph
41-
- [x] Star Graph
42-
- [x] Cycle Graph
43-
- [x] Watts–Strogatz Graph
44-
- [x] Barabási–Albert Graph
45-
46-
* **Algorithms**:
47-
- [ ] Graph traversal
48-
- [ ] Shortest paths
49-
- [ ] Minimum spanning tree
50-
- [ ] Connected components
51-
- [ ] Clustering, partitioning, and community detection
52-
- [ ] Centrality
53-
- [ ] Graph matching
54-
- [ ] Graph visualization
26+
| Module | Feature |
27+
|-------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
28+
| [**Graphs**](src/graph/types.rs) | - ✓ Directed and undirected graphs<br>- ✓ Weighted and unweighted graphs |
29+
| [**IO**](src/graph/io.rs) | - ✓ Edge list<br>- ✓ Adjacency list<br>- ☐ GraphML<br>- ☐ GML<br>- ☐ JSON |
30+
| [**Generators**](src/graph/generators.rs) | - ✓ Erdős–Rényi graph<br>- ✓ Watts–Strogatz graph<br>- ✓ Barabási–Albert graph<br>- ✓ Complete graph<br>- ✓ Bipartite graph<br>- ✓ Star graph<br>- ✓ Cycle graph |
31+
| [**Graph Traversal**](src/traversal/) | - ✓ Breadth-first search<br>- ✓ Depth-first search<br>- ✓ Iterative deepening DFS<br>- ✓ Bidirectional search |
32+
| [**Shortest Paths**](src/paths/) | - ✓ Dijkstra's algorithm<br>- ✓ Bellman–Ford algorithm<br>- ✓ Floyd–Warshall algorithm<br>- ✓ Johnson's algorithm<br>- ✓ A* search algorithm<br>- ✓ Iterative deepening A* search algorithm |
33+
| **Remaining Modules** | - ☐ Minimum spanning tree<br>- ☐ Connected components<br>- ☐ Clustering, partitioning, and community detection<br>- ☐ Centrality<br>- ☐ Graph matching<br>- ☐ Graph visualization |
5534

5635
## Installation
5736

src/graph/generators.rs_ renamed to src/graph/generators.rs

Lines changed: 128 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::graph::types::{BaseGraph, GraphConstructor, MyEdgeType};
2-
use petgraph::EdgeType;
1+
use crate::graph::types::{BaseGraph, GraphConstructor};
32
use rand::rngs::StdRng;
43
use rand::{Rng, SeedableRng};
54

@@ -13,23 +12,23 @@ use rand::{Rng, SeedableRng};
1312
///
1413
/// # Type Parameters
1514
///
16-
/// * `Ty` - The edge type of the graph, which must implement
17-
/// `GraphConstructor<i32, f32> + MyEdgeType + EdgeType`.
15+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
1816
///
1917
/// # Returns
2018
///
21-
/// * `BaseGraph<i32, f32, Ty>` - The generated graph.
22-
pub fn erdos_renyi_graph<Ty>(n: usize, p: f64, seed: u64) -> BaseGraph<i32, f32, Ty>
23-
where
24-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
25-
{
26-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
19+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
20+
pub fn erdos_renyi_graph<Ty: GraphConstructor<u32, f32>>(
21+
n: usize,
22+
p: f64,
23+
seed: u64,
24+
) -> BaseGraph<u32, f32, Ty> {
25+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
2726
let mut nodes = Vec::with_capacity(n);
2827
for i in 0..n {
29-
nodes.push(graph.add_node(i as i32));
28+
nodes.push(graph.add_node(i as u32));
3029
}
3130
let mut rng = StdRng::seed_from_u64(seed);
32-
if <Ty as GraphConstructor<i32, f32>>::is_directed() {
31+
if <Ty as GraphConstructor<u32, f32>>::is_directed() {
3332
for i in 0..n {
3433
for j in 0..n {
3534
if i != j && rng.random_bool(p) {
@@ -50,16 +49,25 @@ where
5049
}
5150

5251
/// Generates a complete graph.
53-
pub fn complete_graph<Ty>(n: usize) -> BaseGraph<i32, f32, Ty>
54-
where
55-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
56-
{
57-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
52+
///
53+
/// # Arguments
54+
///
55+
/// * `n` - The number of nodes.
56+
///
57+
/// # Type Parameters
58+
///
59+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
60+
///
61+
/// # Returns
62+
///
63+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
64+
pub fn complete_graph<Ty: GraphConstructor<u32, f32>>(n: usize) -> BaseGraph<u32, f32, Ty> {
65+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
5866
let mut nodes = Vec::with_capacity(n);
5967
for i in 0..n {
60-
nodes.push(graph.add_node(i as i32));
68+
nodes.push(graph.add_node(i as u32));
6169
}
62-
if <Ty as GraphConstructor<i32, f32>>::is_directed() {
70+
if <Ty as GraphConstructor<u32, f32>>::is_directed() {
6371
for i in 0..n {
6472
for j in 0..n {
6573
if i != j {
@@ -78,18 +86,35 @@ where
7886
}
7987

8088
/// Generates a bipartite graph.
81-
pub fn bipartite_graph<Ty>(n1: usize, n2: usize, p: f64, seed: u64) -> BaseGraph<i32, f32, Ty>
82-
where
83-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
84-
{
85-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
89+
///
90+
/// # Arguments
91+
///
92+
/// * `n1` - The number of nodes in the first set.
93+
/// * `n2` - The number of nodes in the second set.
94+
/// * `p` - The probability of edge creation.
95+
/// * `seed` - The seed for the random number generator.
96+
///
97+
/// # Type Parameters
98+
///
99+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
100+
///
101+
/// # Returns
102+
///
103+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
104+
pub fn bipartite_graph<Ty: GraphConstructor<u32, f32>>(
105+
n1: usize,
106+
n2: usize,
107+
p: f64,
108+
seed: u64,
109+
) -> BaseGraph<u32, f32, Ty> {
110+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
86111
let mut group1 = Vec::with_capacity(n1);
87112
let mut group2 = Vec::with_capacity(n2);
88113
for i in 0..n1 {
89-
group1.push(graph.add_node(i as i32));
114+
group1.push(graph.add_node(i as u32));
90115
}
91116
for j in 0..n2 {
92-
group2.push(graph.add_node((n1 + j) as i32));
117+
group2.push(graph.add_node((n1 + j) as u32));
93118
}
94119
let mut rng = StdRng::seed_from_u64(seed);
95120
for &u in &group1 {
@@ -103,34 +128,52 @@ where
103128
}
104129

105130
/// Generates a star graph.
106-
pub fn star_graph<Ty>(n: usize) -> BaseGraph<i32, f32, Ty>
107-
where
108-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
109-
{
110-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
131+
///
132+
/// # Arguments
133+
///
134+
/// * `n` - The number of nodes.
135+
///
136+
/// # Type Parameters
137+
///
138+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
139+
///
140+
/// # Returns
141+
///
142+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
143+
pub fn star_graph<Ty: GraphConstructor<u32, f32>>(n: usize) -> BaseGraph<u32, f32, Ty> {
144+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
111145
if n == 0 {
112146
return graph;
113147
}
114148
let center = graph.add_node(0);
115149
for i in 1..n {
116-
let node = graph.add_node(i as i32);
150+
let node = graph.add_node(i as u32);
117151
graph.add_edge(center, node, 1.0);
118152
}
119153
graph
120154
}
121155

122156
/// Generates a cycle graph.
123-
pub fn cycle_graph<Ty>(n: usize) -> BaseGraph<i32, f32, Ty>
124-
where
125-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
126-
{
127-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
157+
///
158+
/// # Arguments
159+
///
160+
/// * `n` - The number of nodes.
161+
///
162+
/// # Type Parameters
163+
///
164+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
165+
///
166+
/// # Returns
167+
///
168+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
169+
pub fn cycle_graph<Ty: GraphConstructor<u32, f32>>(n: usize) -> BaseGraph<u32, f32, Ty> {
170+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
128171
if n == 0 {
129172
return graph;
130173
}
131174
let mut nodes = Vec::with_capacity(n);
132175
for i in 0..n {
133-
nodes.push(graph.add_node(i as i32));
176+
nodes.push(graph.add_node(i as u32));
134177
}
135178
for i in 0..n {
136179
let j = (i + 1) % n;
@@ -140,26 +183,44 @@ where
140183
}
141184

142185
/// Generates a Watts–Strogatz small-world graph.
143-
pub fn watts_strogatz_graph<Ty>(n: usize, k: usize, beta: f64, seed: u64) -> BaseGraph<i32, f32, Ty>
144-
where
145-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
146-
{
186+
///
187+
/// # Arguments
188+
///
189+
/// * `n` - The number of nodes.
190+
/// * `k` - Each node is joined with its `k` nearest neighbors in a ring topology.
191+
/// * `beta` - The probability of rewiring each edge.
192+
/// * `seed` - The seed for the random number generator.
193+
///
194+
/// # Type Parameters
195+
///
196+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
197+
///
198+
/// # Returns
199+
///
200+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
201+
pub fn watts_strogatz_graph<Ty: GraphConstructor<u32, f32>>(
202+
n: usize,
203+
k: usize,
204+
beta: f64,
205+
seed: u64,
206+
) -> BaseGraph<u32, f32, Ty> {
147207
// Watts–Strogatz is defined for undirected graphs.
148-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
208+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
149209
let mut nodes = Vec::with_capacity(n);
150210
for i in 0..n {
151-
nodes.push(graph.add_node(i as i32));
211+
nodes.push(graph.add_node(i as u32));
152212
}
153213
let mut rng = StdRng::seed_from_u64(seed);
154214
let half_k = k / 2;
155-
// Create ring lattice.
215+
// Create ring lattice
156216
for i in 0..n {
157217
for j in 1..=half_k {
158218
let neighbor = (i + j) % n;
159219
graph.add_edge(nodes[i], nodes[neighbor], 1.0);
160220
}
161221
}
162222
// Rewire each edge with probability beta.
223+
// For simplicity, we add new edges for rewired connections.
163224
for i in 0..n {
164225
for _ in 1..=half_k {
165226
if rng.random_bool(beta) {
@@ -178,19 +239,34 @@ where
178239
}
179240

180241
/// Generates a Barabási–Albert scale-free graph.
181-
pub fn barabasi_albert_graph<Ty>(n: usize, m: usize, seed: u64) -> BaseGraph<i32, f32, Ty>
182-
where
183-
Ty: GraphConstructor<i32, f32> + MyEdgeType + EdgeType,
184-
{
242+
///
243+
/// # Arguments
244+
///
245+
/// * `n` - The number of nodes.
246+
/// * `m` - The number of edges to attach from a new node to existing nodes.
247+
/// * `seed` - The seed for the random number generator.
248+
///
249+
/// # Type Parameters
250+
///
251+
/// * `Ty` - The edge type of the graph, which must implement `GraphConstructor`.
252+
///
253+
/// # Returns
254+
///
255+
/// * `BaseGraph<u32, f32, Ty>` - The generated graph.
256+
pub fn barabasi_albert_graph<Ty: GraphConstructor<u32, f32>>(
257+
n: usize,
258+
m: usize,
259+
seed: u64,
260+
) -> BaseGraph<u32, f32, Ty> {
185261
// Barabási–Albert is defined for undirected graphs.
186-
let mut graph = BaseGraph::<i32, f32, Ty>::new();
262+
let mut graph = BaseGraph::<u32, f32, Ty>::new();
187263
if n < m || m == 0 {
188264
return graph;
189265
}
190266
// Start with a complete graph of m nodes.
191267
let mut nodes = Vec::with_capacity(n);
192268
for i in 0..m {
193-
nodes.push(graph.add_node(i as i32));
269+
nodes.push(graph.add_node(i as u32));
194270
}
195271
for i in 0..m {
196272
for j in (i + 1)..m {
@@ -201,7 +277,7 @@ where
201277
let mut degrees: Vec<usize> = vec![m - 1; m];
202278
let mut total_degree = m * (m - 1);
203279
for i in m..n {
204-
let new_node = graph.add_node(i as i32);
280+
let new_node = graph.add_node(i as u32);
205281
nodes.push(new_node);
206282
let mut targets = Vec::new();
207283
while targets.len() < m {

0 commit comments

Comments
 (0)