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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*!
# graphrs
`graphrs` is a Rust package for the creation, manipulation and analysis of [graphs](<https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)>).
It allows graphs to be created with support for:
- directed and undirected edges
- multiple edges between two nodes
- self-loops
A `Graph` has two generic arguments:
- `T`: Specifies the type to use for node names.
- `A`: Specifies the type to use for node and edge attributes. Attributes are _optional_
extra data that are associated with a node or an edge. For example, if nodes represent
people and `T` is an `i32` of their employee ID then the node attributes might store
their first and last names.
## Documentation
The doc.rs documentation [is here](<https://docs.rs/graphrs>).
## Python bindings
Python bindings are available in the [graphrs-python](<https://pypi.org/project/graphrs-python/>) package.
## Major structs
- `Graph`
- `Node`
- `Edge`
## Modules
- `algorithms::boundary`
- `algorithms::cuts`
- `algorithms::centrality`
- `algorithms::cluster`
- `algorithms::community`
- `algorithms::components`
- `algorithms::structural_holes`
- `algorithms::shortest_path`
- `generators`
- `readwrite`
## Examples
### Create a weighted, directed graph
```rust
use graphrs::{Edge, Graph, GraphSpecs, Node};
let nodes = vec![
Node::from_name("n1"),
Node::from_name("n2"),
Node::from_name("n3"),
];
let edges = vec![
Edge::with_weight("n1", "n2", 1.0),
Edge::with_weight("n2", "n1", 2.0),
Edge::with_weight("n1", "n3", 3.0),
Edge::with_weight("n2", "n3", 3.0),
];
let specs = GraphSpecs::directed();
let graph = Graph::<&str, ()>::new_from_nodes_and_edges(
nodes,
edges,
specs
);
```
### Create an undirected graph from just edges
```rust
use graphrs::{Edge, Graph, GraphSpecs};
let mut graph: Graph<&str, ()> = Graph::new(GraphSpecs::undirected_create_missing());
let result = graph.add_edges(vec![
Edge::new("n1", "n2"),
Edge::new("n2", "n3"),
]);
```
### Create an empty graph with all possible specifications
```rust
use graphrs::{Graph, GraphSpecs, EdgeDedupeStrategy, MissingNodeStrategy, SelfLoopsFalseStrategy};
let graph = Graph::<&str, ()>::new(
GraphSpecs {
directed: true,
edge_dedupe_strategy: EdgeDedupeStrategy::Error,
missing_node_strategy: MissingNodeStrategy::Error,
multi_edges: false,
self_loops: false,
self_loops_false_strategy: SelfLoopsFalseStrategy::Error,
}
);
```
### Generate graphs
```rust
use graphrs::{generators};
let graph_complete = generators::classic::complete_graph(5, true);
let graph_random = generators::random::fast_gnp_random_graph(250, 0.25, true, None);
```
### Find the shortest path between two nodes
```rust
use graphrs::{Edge, Graph, GraphSpecs, Node};
use graphrs::{algorithms::{shortest_path::{dijkstra}}};
let mut graph = Graph::<&str, ()>::new(GraphSpecs::directed_create_missing());
graph.add_edges(vec![
Edge::with_weight("n1", "n2", 1.0),
Edge::with_weight("n2", "n1", 2.0),
Edge::with_weight("n1", "n3", 3.0),
Edge::with_weight("n2", "n3", 1.1),
]);
let shortest_paths = dijkstra::single_source(&graph, true, "n1", Some("n3"), None, false, true);
assert_eq!(shortest_paths.unwrap().get("n3").unwrap().distance, 2.1);
```
### Compute the betweenness, closeness and eigenvector centrality for all nodes
```rust
use graphrs::{algorithms::centrality, generators};
let graph = generators::social::karate_club_graph();
let centralities = centrality::betweenness::betweenness_centrality(&graph, false, true);
let closeness = centrality::closeness::closeness_centrality(&graph, false, true);
let centralities = centrality::eigenvector::eigenvector_centrality(&graph, false, None, None);
```
### Detect communities within a graph
```rust
use graphrs::{algorithms::{community}, generators};
use graphrs::{algorithms::community::leiden::{leiden, QualityFunction}};
let graph = generators::social::karate_club_graph();
let partitions = community::louvain::louvain_partitions(&graph, false, None, None, Some(1));
let partitions = leiden(&graph, true, QualityFunction::CPM, None, None, None);
```
### Read and write graphml files
```rust,ignore
use graphrs::{readwrite, GraphSpecs};
let graph = readwrite::graphml::read_graphml_file("/some/file.graphml", GraphSpecs::directed());
readwrite::graphml::write_graphml(&graph, "/some/other/file.graphml");
```
### Get an adjacency matrix
*This is an optional feature. Enable in Cargo.toml with:*
`graphrs = { version = "x.y.z", features = ["adjacency_matrix"] }`
```rust,ignore
use graphrs::generators;
let graph = generators::social::karate_club_graph();
let matrix = graph.get_sparse_adjacency_matrix().unwrap();
```
## Performance
A comparison of the performance of `graphrs` against `NetworkX`, `igraph` and `graph-tool` can be found [here](<https://github.com/malcolmvr/graphrs/blob/main/performance.md>).
## Credits
Some of the structure of the API and some of the algorithms were inspired by NetworkX.
## License
MIT
*/
extern crate doc_comment;
doc_comment!;
pub use Edge;
pub use ;
pub use Graph;
pub use ToUndirectedCollapseEdgeWeightsStrategy;
pub use AdjacentNode;
pub use ;
pub use Node;