/rust/registry/src/index.crates.io-1949cf8c6b5b557f/petgraph-0.8.3/src/lib.rs
Line | Count | Source |
1 | | /*! |
2 | | `petgraph` is a graph data structure library. |
3 | | |
4 | | Graphs are collections of nodes, and edges between nodes. `petgraph` |
5 | | provides several [graph types](index.html#graph-types) (each differing in the |
6 | | tradeoffs taken in their internal representation), |
7 | | [algorithms](./algo/index.html) on those graphs, and functionality to |
8 | | [output graphs](./dot/struct.Dot.html) in |
9 | | [`Graphviz`](https://www.graphviz.org/) format. Both nodes and edges |
10 | | can have arbitrary associated data, and edges may be either directed or undirected. |
11 | | |
12 | | # Overview |
13 | | |
14 | | Here is a simple example showing off some features of `petgraph`: |
15 | | ``` |
16 | | use petgraph::graph::UnGraph; |
17 | | use petgraph::algo::{dijkstra, min_spanning_tree}; |
18 | | use petgraph::data::FromElements; |
19 | | use petgraph::dot::{Dot, Config}; |
20 | | use petgraph::visit::NodeIndexable; |
21 | | |
22 | | // Create an undirected graph with associated data |
23 | | // of type `i32` for the nodes and `()` for the edges. |
24 | | let g = UnGraph::<i32, ()>::from_edges(&[ |
25 | | (0, 1), (1, 2), (2, 3), (0, 3) |
26 | | ]); |
27 | | |
28 | | // The graph looks like this: |
29 | | // 0 -- 1 |
30 | | // | | |
31 | | // 3 -- 2 |
32 | | |
33 | | // Find the shortest path from `0` to `2` using `1` as the cost for every edge. |
34 | | let node_map = dijkstra(&g, 0.into(), Some(2.into()), |_| 1); |
35 | | assert_eq!(&2i32, node_map.get(&g.from_index(2)).unwrap()); |
36 | | |
37 | | // Get the minimum spanning tree of the graph as a new graph, and check that |
38 | | // one edge was trimmed. |
39 | | let mst = UnGraph::<_, _>::from_elements(min_spanning_tree(&g)); |
40 | | assert_eq!(g.raw_edges().len() - 1, mst.raw_edges().len()); |
41 | | |
42 | | // Output the tree to `graphviz` `DOT` format |
43 | | println!("{:?}", Dot::with_config(&mst, &[Config::EdgeNoLabel])); |
44 | | // graph { |
45 | | // 0 [ label = "0" ] |
46 | | // 1 [ label = "0" ] |
47 | | // 2 [ label = "0" ] |
48 | | // 3 [ label = "0" ] |
49 | | // 0 -- 1 [ ] |
50 | | // 2 -- 3 [ ] |
51 | | // 1 -- 2 [ ] |
52 | | // } |
53 | | ``` |
54 | | |
55 | | `petgraph` provides several concrete graph types — [`Graph`](./graph/struct.Graph.html), |
56 | | [`StableGraph`](./stable_graph/struct.StableGraph.html), [`GraphMap`](./graphmap/struct.GraphMap.html), |
57 | | [`MatrixGraph`](./matrix_graph/struct.MatrixGraph.html), and [`Csr`](./csr/struct.Csr.html) |
58 | | — each optimized for different trade-offs in memory layout, index stability, and lookup speed. |
59 | | Some types (e.g., [`Graph`](./graph/struct.Graph.html)) expose the fullest set of methods |
60 | | and algorithm support, while others (like [`StableGraph`](./stable_graph/struct.StableGraph.html) |
61 | | or [`Csr`](./csr/struct.Csr.html)) are more recent and may not yet implement the full feature set, |
62 | | see [Graph Types](#graph-types) for more details. |
63 | | |
64 | | With these types as building blocks, you can insert or remove nodes and edges, attach arbitrary data to them, |
65 | | explore neighbors, and apply standard graph algorithms. The [`algo`] module implements routines such as |
66 | | shortest‐path searches and minimum spanning trees for any compatible graph, and the [`dot`] module exports |
67 | | functionality to convert graphs to DOT format so you can visualize or analyze them with |
68 | | [`Graphviz`](https://www.graphviz.org/). |
69 | | |
70 | | The remainder of this documentation is organized as follows: |
71 | | |
72 | | * [Usage](#usage) shows how to add `petgraph` to your project. |
73 | | |
74 | | * [Graph types](#graph-types) explains each implementation’s internal structure and feature set. |
75 | | |
76 | | * [Generic parameters](#generic-parameters) clarifies what N, E, Ty, and Ix signify and any trait bounds they impose. |
77 | | |
78 | | * [Shorthand types](#shorthand-types) lists commonly used aliases (for example, [`DiGraph<_, _>`](./graph/type.DiGraph.html) for [`Graph<_, _, Directed>`](./graph/struct.Graph.html). |
79 | | |
80 | | * [Examples](#examples) walks through common tasks such as basic graph construction, index behavior, running algorithms, weight transformations, and DOT export. |
81 | | |
82 | | * [Crate features](#crate-features) covers (optional) Cargo flags (e.g. serde or rayon support). |
83 | | |
84 | | * Finally, each submodule page (e.g., [`algo`], [`graph`], [`graphmap`], etc.) provides detailed API documentation and design notes. |
85 | | |
86 | | # Usage |
87 | | |
88 | | `petgraph` is available on [crates.io](https://crates.io/crates/petgraph) and can be added to your |
89 | | project by adding `petgraph` to your `Cargo.toml`. Or more simply, by running `cargo add petgraph`. |
90 | | |
91 | | Here is an example that creates a new Rust project, adds a dependency on `petgraph`, and runs |
92 | | a simple program that creates an undirected graph. |
93 | | |
94 | | First, create a new Rust project in a new directory: |
95 | | ```bash |
96 | | cargo new petgraph_example |
97 | | cd petgraph_example |
98 | | ``` |
99 | | |
100 | | Second, add a dependency on `petgraph`: |
101 | | ```bash |
102 | | cargo add petgraph |
103 | | ``` |
104 | | |
105 | | Third, replace the contents of your main function in `src/main.rs` with the following code: |
106 | | ```text |
107 | | use petgraph::graph::UnGraph; |
108 | | |
109 | | fn main() { |
110 | | let g = UnGraph::<(), ()>::from_edges(&[(0, 1), (1, 2), (2, 3), (0, 3)]); |
111 | | |
112 | | println!("Graph: {:?}", g); |
113 | | } |
114 | | ``` |
115 | | |
116 | | Finally, run the program with `cargo run`: |
117 | | ```bash |
118 | | Graph { Ty: "Undirected", node_count: 4, edge_count: 4, edges: (0, 1), (1, 2), (2, 3), (0, 3) } |
119 | | ``` |
120 | | |
121 | | # Graph types |
122 | | |
123 | | * [`Graph`](./graph/struct.Graph.html) - |
124 | | An adjacency list graph with arbitrary associated data. |
125 | | * [`StableGraph`](./stable_graph/struct.StableGraph.html) - |
126 | | Similar to `Graph`, but it keeps indices stable across removals. |
127 | | * [`GraphMap`](./graphmap/struct.GraphMap.html) - |
128 | | An adjacency list graph backed by a hash table. The node identifiers are the keys |
129 | | into the table. |
130 | | * [`MatrixGraph`](./matrix_graph/struct.MatrixGraph.html) - |
131 | | An adjacency matrix graph. |
132 | | * [`CSR`](./csr/struct.Csr.html) - |
133 | | A sparse adjacency matrix graph with arbitrary associated data. |
134 | | |
135 | | ### Generic parameters |
136 | | |
137 | | Each graph type is generic over a handful of parameters. All graphs share 3 common |
138 | | parameters, `N`, `E`, and `Ty`. This is a broad overview of what those are. Each |
139 | | graph type's documentation will have finer detail on these parameters. |
140 | | |
141 | | `N` & `E` are called *weights* in this implementation, and are associated with |
142 | | nodes and edges respectively. They can generally be of arbitrary type, and don't have to |
143 | | be what you might conventionally consider weight-like. For example, using `&str` for `N` |
144 | | will work. Many algorithms that require costs let you provide a cost function that |
145 | | translates your `N` and `E` weights into costs appropriate to the algorithm. Some graph |
146 | | types and choices do impose bounds on `N` or `E`. |
147 | | [`min_spanning_tree`](./algo/fn.min_spanning_tree.html) for example requires edge weights that |
148 | | implement [`PartialOrd`](https://doc.rust-lang.org/stable/core/cmp/trait.PartialOrd.html). |
149 | | [`GraphMap`](./graphmap/struct.GraphMap.html) requires node weights that can serve as hash |
150 | | map keys, since that graph type does not create standalone node indices. |
151 | | |
152 | | `Ty` controls whether edges are [`Directed`](./enum.Directed.html) or |
153 | | [`Undirected`](./enum.Undirected.html). |
154 | | |
155 | | `Ix` appears on graph types that use indices. It is exposed so you can control |
156 | | the size of node and edge indices, and therefore the memory footprint of your graphs. |
157 | | Allowed values are `u8`, `u16`, `u32`, and `usize`, with `u32` being the default. |
158 | | |
159 | | ### Shorthand types |
160 | | |
161 | | Each graph type vends a few shorthand type definitions that name some specific |
162 | | generic choices. For example, [`DiGraph<_, _>`](./graph/type.DiGraph.html) is shorthand |
163 | | for [`Graph<_, _, Directed>`](graph/struct.Graph.html). |
164 | | [`UnMatrix<_, _>`](./matrix_graph/type.UnMatrix.html) is shorthand for |
165 | | [`MatrixGraph<_, _, Undirected>`](./matrix_graph/struct.MatrixGraph.html). Each graph type's |
166 | | module documentation lists the available shorthand types. |
167 | | |
168 | | # Examples |
169 | | |
170 | | * [Creating an undirected graph and manipulating nodes and edges](#creating-an-undirected-graph-and-manipulating-nodes-and-edges) |
171 | | * [Differences of stable and non-stable graphs in index management](#differences-of-stable-and-non-stable-graphs-in-index-management) |
172 | | * [Using algorithms on graphs](#using-algorithms-on-graphs) |
173 | | * [Associating data with nodes and edges and transmuting the type of the data](#associating-data-with-nodes-and-edges-and-transmuting-the-type-of-the-data) |
174 | | * [Exporting graphs to DOT format](#exporting-graphs-to-dot-format) |
175 | | |
176 | | ### Creating an undirected graph and manipulating nodes and edges |
177 | | |
178 | | ``` |
179 | | use petgraph::graph::UnGraph; |
180 | | use petgraph::visit::NodeIndexable; |
181 | | |
182 | | // Create an undirected graph with associated data of type `i32` for nodes and `()` for edges. |
183 | | let mut g = UnGraph::<i32, ()>::from_edges(&[(0, 1), (1, 2), (2, 3), (0, 3)]); |
184 | | |
185 | | // The graph looks like this: |
186 | | // 0 -- 1 |
187 | | // | | |
188 | | // 3 -- 2 |
189 | | |
190 | | // Add two more edges between nodes 0 and 2, and 1 and 3 |
191 | | g.extend_with_edges(&[(0, 2), (1, 3)]); |
192 | | |
193 | | // Add another node with a weight of 5 |
194 | | let node = g.add_node(5); |
195 | | |
196 | | // Connect the new node to node 2. |
197 | | // We can access the recently added node via the returned `NodeIndex`. |
198 | | g.add_edge(node, 2.into(), ()); |
199 | | |
200 | | // The graph now looks like this: |
201 | | // 0 -- 1 |
202 | | // | \/ | |
203 | | // | /\ | |
204 | | // 3 -- 2 |
205 | | // \ |
206 | | // 4 |
207 | | |
208 | | // We can also access existing nodes by creating a `NodeIndex` using the from_index |
209 | | // method on g. Indexes are zero-based, so the first node is at index 0. |
210 | | let node_0 = g.from_index(0); |
211 | | |
212 | | // And then change the weight of node 0 to 10. |
213 | | let node_0_weight = g.node_weight_mut(node_0).unwrap(); |
214 | | *node_0_weight = 10; |
215 | | assert_eq!(g.node_weight(node_0), Some(&10)); |
216 | | ``` |
217 | | |
218 | | Note that when creating the graph, we only specified the edges, and the nodes were created |
219 | | automatically. Since we did not specify the node weights, they default to `i32::default()`, which |
220 | | is `0`. |
221 | | |
222 | | ### Differences of stable and non-stable graphs in index management |
223 | | |
224 | | This example shows how to remove a node from a graph and how this might change node indices. |
225 | | Removing a node also automatically takes care of removing all edges connected to the removed node. |
226 | | |
227 | | When removing a node from a non-stable graph, the node indices might change depending on two cases. |
228 | | If the node had the highest index, the other nodes' indices don't change. If the removed |
229 | | node did not have the highest index, the node with the highest index will take the index of the |
230 | | removed node and all other indices stay the same. |
231 | | |
232 | | [Stable graphs](./stable_graph/struct.StableGraph.html) address this by keeping the indices of nodes |
233 | | and edges stable, even after removals. Currently, this comes at the cost of possible additional memory |
234 | | usage and lack of some features that other graph types provide. For all the graph types, and their |
235 | | internal structure and feature set, please refer to [Graph Types](#graph-types). |
236 | | |
237 | | ``` |
238 | | #[cfg(feature = "stable_graph")] |
239 | | { |
240 | | use petgraph::graph::UnGraph; |
241 | | use petgraph::stable_graph::StableUnGraph; |
242 | | use petgraph::visit::IntoNodeIdentifiers; |
243 | | |
244 | | // Create an stable and non-stable undirected graph. |
245 | | let mut g_non_stable = UnGraph::<i32, ()>::from_edges(&[(0, 1), (1, 2), (2, 3), (0, 3)]); |
246 | | let mut g_stable = StableUnGraph::<i32, ()>::from_edges(&[(0, 1), (1, 2), (2, 3), (0, 3)]); |
247 | | |
248 | | // The graphs look like this: |
249 | | // 0 -- 1 |
250 | | // | | |
251 | | // 3 -- 2 |
252 | | |
253 | | // Remove node 1 and see how the node indexes change. |
254 | | g_non_stable.remove_node(1.into()); |
255 | | g_stable.remove_node(1.into()); |
256 | | |
257 | | println!("Node Indices (Non-Stable): {:?}", g_non_stable.node_identifiers().collect::<Vec<_>>()); |
258 | | // Output: Node Indices (Non-Stable): [NodeIndex(0), NodeIndex(1), NodeIndex(2)] |
259 | | println!("Node Indices (Stable): {:?}", g_stable.node_identifiers().collect::<Vec<_>>()); |
260 | | // Output: Node Indices (Stable): [NodeIndex(0), NodeIndex(1), NodeIndex(3)] |
261 | | |
262 | | // The non-stable graph now looks like this: |
263 | | // 0 |
264 | | // | |
265 | | // 1 -- 2 |
266 | | // The node which previously had index 1 has been removed, and the node which previously had |
267 | | // index 2 has now taken index 1. The other nodes' indices remain unchanged. |
268 | | |
269 | | // The stable graph now looks like this: |
270 | | // 0 |
271 | | // | |
272 | | // 2 -- 3 |
273 | | // The node indices have remained stable and the node with index 1 has been removed. |
274 | | } |
275 | | ``` |
276 | | |
277 | | ### Using algorithms on graphs |
278 | | |
279 | | Petgraph provides not only data structures for modeling graphs, but also a wide range of algorithms |
280 | | that can be applied to them. For example, given a graph, one can compute shortest paths, |
281 | | minimum spanning trees, or even compute the maximal cliques of a graph. |
282 | | |
283 | | Generally, algorithms are found in the [`algo`] module, except for algorithms like |
284 | | depth-/breadth-first-search, which can be found in the [`visit`] module. All of them should include |
285 | | an example of how to use them. For example, to compute the minimum spanning tree of a graph, one can use the |
286 | | [`min_spanning_tree`](algo/min_spanning_tree/fn.min_spanning_tree.html) function. |
287 | | |
288 | | ``` |
289 | | use petgraph::algo::min_spanning_tree; |
290 | | use petgraph::data::FromElements; |
291 | | use petgraph::graph::UnGraph; |
292 | | |
293 | | // Create a graph to compute the minimum spanning tree of. |
294 | | let g = UnGraph::<i32, ()>::from_edges(&[(0, 1), (1, 2), (2, 3), (0, 3)]); |
295 | | |
296 | | // The graphs look like this: |
297 | | // 0 -- 1 |
298 | | // | | |
299 | | // 3 -- 2 |
300 | | |
301 | | // Compute a minimum spanning tree of the graph and collect it into a new graph. |
302 | | let mst = UnGraph::<_, _>::from_elements(min_spanning_tree(&g)); |
303 | | |
304 | | // Check that the minimum spanning tree has one edge less than the original graph. |
305 | | assert_eq!(g.raw_edges().len() - 1, mst.raw_edges().len()); |
306 | | ``` |
307 | | |
308 | | ### Associating data with nodes and edges and transmuting the type of the data |
309 | | |
310 | | In many cases, it is useful to associate data with nodes and/or edges in a graph. |
311 | | For example, associating an integer with each edge to represent its usage cost in a network. |
312 | | |
313 | | Petgraph allows you to associate arbitrary data with both nodes and edges in a graph. |
314 | | Not only that, but it also exposes functionality to easily work with your associated |
315 | | data and transform it into a different type using the `map` methods. |
316 | | |
317 | | Associated data might also be referred to as *weights* in the documentation. |
318 | | |
319 | | ``` |
320 | | use petgraph::graph::UnGraph; |
321 | | |
322 | | // Create an undirected graph with city names as node data and their distances as edge data. |
323 | | let mut g = UnGraph::<String, u32>::new_undirected(); |
324 | | |
325 | | let ber = g.add_node("Berlin".to_owned()); |
326 | | let del = g.add_node("New Delhi".to_owned()); |
327 | | let mex = g.add_node("Mexico City".to_owned()); |
328 | | let syd = g.add_node("Sydney".to_owned()); |
329 | | |
330 | | // Add distances in kilometers as edge data. |
331 | | g.extend_with_edges(&[ |
332 | | (ber, del, 6_000), |
333 | | (ber, mex, 10_000), |
334 | | (ber, syd, 16_000), |
335 | | (del, mex, 14_000), |
336 | | (del, syd, 12_000), |
337 | | (mex, syd, 15_000), |
338 | | ]); |
339 | | |
340 | | // We might now want to change up the distances to be in miles instead and to be strings. |
341 | | // We can do this using the `map` method, which takes two closures for the node and edge data, |
342 | | // respectively, and returns a new graph with the transformed data. |
343 | | let g_miles: UnGraph<String, String> = g.map( |
344 | | |_, city| city.to_owned(), |
345 | | |_, distance| format!("{} miles", (*distance as f64 * 0.621371).round() as i32), |
346 | | ); |
347 | | ``` |
348 | | |
349 | | ### Exporting graphs to DOT format |
350 | | |
351 | | Petgraph provides functionality to export graphs to the [DOT](https://www.graphviz.org/doc/info/lang.html) |
352 | | format, which can be used with the [Graphviz](https://www.graphviz.org/) suite of tools for |
353 | | visualization and analysis of graphs. The [`dot`] module provides the necessary functionality to |
354 | | convert graphs into DOT format. |
355 | | |
356 | | Let's try exporting the graph we created in the previous example to DOT format. |
357 | | |
358 | | ``` |
359 | | use petgraph::dot::{Config, Dot}; |
360 | | use petgraph::graph::UnGraph; |
361 | | use petgraph::visit::EdgeRef; |
362 | | |
363 | | // Create an undirected graph with city names as node data and their distances as edge data. |
364 | | let mut g = UnGraph::<String, u32>::new_undirected(); |
365 | | |
366 | | let ber = g.add_node("Berlin".to_owned()); |
367 | | let del = g.add_node("New Delhi".to_owned()); |
368 | | let mex = g.add_node("Mexico City".to_owned()); |
369 | | let syd = g.add_node("Sydney".to_owned()); |
370 | | |
371 | | // Add distances in kilometers as edge data. |
372 | | g.extend_with_edges(&[ |
373 | | (ber, del, 6_000), |
374 | | (ber, mex, 10_000), |
375 | | (ber, syd, 16_000), |
376 | | (del, mex, 14_000), |
377 | | (del, syd, 12_000), |
378 | | (mex, syd, 15_000), |
379 | | ]); |
380 | | |
381 | | // Basic DOT export with automatic labels |
382 | | let basic_dot = Dot::new(&g); |
383 | | println!("Basic DOT format:\n{:?}\n", basic_dot); |
384 | | // Output: |
385 | | // Basic DOT format: |
386 | | // graph { |
387 | | // 0 [ label = "\"Berlin\"" ] |
388 | | // 1 [ label = "\"New Delhi\"" ] |
389 | | // 2 [ label = "\"Mexico City\"" ] |
390 | | // 3 [ label = "\"Sydney\"" ] |
391 | | // 0 -- 1 [ label = "6000" ] |
392 | | // 0 -- 2 [ label = "10000" ] |
393 | | // 0 -- 3 [ label = "16000" ] |
394 | | // 1 -- 2 [ label = "14000" ] |
395 | | // 1 -- 3 [ label = "12000" ] |
396 | | // 2 -- 3 [ label = "15000" ] |
397 | | // } |
398 | | |
399 | | // Enhanced DOT export with custom attributes |
400 | | let fancy_dot = Dot::with_attr_getters( |
401 | | &g, |
402 | | // Global graph attributes |
403 | | &[], |
404 | | // Edge attribute getter |
405 | | &|graph_reference, edge_reference| { |
406 | | // Style edges depending on distance |
407 | | if graph_reference.edge_weight(edge_reference.id()).unwrap() > &12_500 { |
408 | | "style=dashed, penwidth=3".to_owned() |
409 | | } else { |
410 | | "style=solid".to_owned() |
411 | | } |
412 | | }, |
413 | | // Node attribute getter; We don't change any node attributes |
414 | | &|_, (_, _)| String::new(), |
415 | | ); |
416 | | |
417 | | println!("Enhanced DOT format:\n{:?}", fancy_dot); |
418 | | // Output: |
419 | | // Enhanced DOT format: |
420 | | // graph { |
421 | | // 0 [ label = "\"Berlin\"" ] |
422 | | // 1 [ label = "\"New Delhi\"" ] |
423 | | // 2 [ label = "\"Mexico City\"" ] |
424 | | // 3 [ label = "\"Sydney\"" ] |
425 | | // 0 -- 1 [ label = "6000" style=solid] |
426 | | // 0 -- 2 [ label = "10000" style=solid] |
427 | | // 0 -- 3 [ label = "16000" style=dashed, penwidth=3] |
428 | | // 1 -- 2 [ label = "14000" style=dashed, penwidth=3] |
429 | | // 1 -- 3 [ label = "12000" style=solid] |
430 | | // 2 -- 3 [ label = "15000" style=dashed, penwidth=3] |
431 | | // } |
432 | | |
433 | | // This would typically be written to a file: |
434 | | // std::fs::write("flight_network.dot", format!("{:?}", fancy_dot)).unwrap(); |
435 | | ``` |
436 | | |
437 | | # Crate features |
438 | | |
439 | | `petgraph` is built with these features enabled by default: |
440 | | |
441 | | * **graphmap** - |
442 | | Enables [`GraphMap`](./graphmap/struct.GraphMap.html). |
443 | | * **stable_graph** - |
444 | | Enables [`StableGraph`](./stable_graph/struct.StableGraph.html). |
445 | | * **matrix_graph** - |
446 | | Enables [`MatrixGraph`](./matrix_graph/struct.MatrixGraph.html). |
447 | | * **std** - |
448 | | Enables the Rust Standard Library. Disabling the `std` feature makes it possible to use `petgraph` in `no_std` contexts. |
449 | | |
450 | | Optionally, the following features can be enabled: |
451 | | |
452 | | * **serde-1** - |
453 | | Enables serialization for ``Graph, StableGraph, GraphMap`` using |
454 | | [`serde 1.0`](https://crates.io/crates/serde). May require a more recent version |
455 | | of Rust than petgraph alone. |
456 | | * **rayon** - |
457 | | Enables parallel versions of iterators and algorithms using |
458 | | [`rayon`](https://docs.rs/rayon/latest/rayon/) crate. Requires the `std` feature. |
459 | | * **dot_parser** - |
460 | | Enables building [`Graph`](./graph/struct.Graph.html) and [`StableGraph`](./stable_graph/struct.StableGraph.html) from [DOT/Graphviz](https://www.graphviz.org/doc/info/lang.html) descriptions. Imports can be made statically or dynamically (i.e. at compile time or at runtime). |
461 | | * **unstable** - |
462 | | Enables unstable crate features (currently only `generate`). |
463 | | * **generate** - |
464 | | Enables graph generators. The API of functionality behind this flag is subject to change at any time. |
465 | | */ |
466 | | #![doc(html_root_url = "https://docs.rs/petgraph/0.4/")] |
467 | | #![no_std] |
468 | | |
469 | | extern crate alloc; |
470 | | |
471 | | #[cfg(any(feature = "std", test))] |
472 | | extern crate std; |
473 | | |
474 | | extern crate fixedbitset; |
475 | | #[cfg(feature = "graphmap")] |
476 | | extern crate indexmap; |
477 | | |
478 | | #[cfg(feature = "serde-1")] |
479 | | extern crate serde; |
480 | | #[cfg(feature = "serde-1")] |
481 | | #[macro_use] |
482 | | extern crate serde_derive; |
483 | | |
484 | | #[cfg(all(feature = "serde-1", test))] |
485 | | extern crate itertools; |
486 | | |
487 | | #[doc(no_inline)] |
488 | | pub use crate::graph::Graph; |
489 | | |
490 | | pub use crate::Direction::{Incoming, Outgoing}; |
491 | | |
492 | | #[macro_use] |
493 | | mod macros; |
494 | | mod scored; |
495 | | |
496 | | // these modules define trait-implementing macros |
497 | | #[macro_use] |
498 | | pub mod visit; |
499 | | #[macro_use] |
500 | | pub mod data; |
501 | | |
502 | | pub mod acyclic; |
503 | | pub mod adj; |
504 | | pub mod algo; |
505 | | pub mod csr; |
506 | | pub mod dot; |
507 | | #[cfg(feature = "generate")] |
508 | | pub mod generate; |
509 | | pub mod graph6; |
510 | | mod graph_impl; |
511 | | #[cfg(feature = "graphmap")] |
512 | | pub mod graphmap; |
513 | | mod iter_format; |
514 | | mod iter_utils; |
515 | | #[cfg(feature = "matrix_graph")] |
516 | | pub mod matrix_graph; |
517 | | #[cfg(feature = "quickcheck")] |
518 | | mod quickcheck; |
519 | | #[cfg(feature = "serde-1")] |
520 | | mod serde_utils; |
521 | | mod traits_graph; |
522 | | pub mod unionfind; |
523 | | |
524 | | pub mod operator; |
525 | | pub mod prelude; |
526 | | |
527 | | /// `Graph<N, E, Ty, Ix>` is a graph datastructure using an adjacency list representation. |
528 | | pub mod graph { |
529 | | pub use crate::graph_impl::{ |
530 | | edge_index, node_index, DefaultIx, DiGraph, Edge, EdgeIndex, EdgeIndices, EdgeReference, |
531 | | EdgeReferences, EdgeWeightsMut, Edges, EdgesConnecting, Externals, Frozen, Graph, |
532 | | GraphError, GraphIndex, IndexType, Neighbors, Node, NodeIndex, NodeIndices, NodeReferences, |
533 | | NodeWeightsMut, UnGraph, WalkNeighbors, |
534 | | }; |
535 | | } |
536 | | |
537 | | #[cfg(feature = "stable_graph")] |
538 | | pub use crate::graph_impl::stable_graph; |
539 | | |
540 | | // Index into the NodeIndex and EdgeIndex arrays |
541 | | /// Edge direction. |
542 | | #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] |
543 | | #[repr(usize)] |
544 | | #[cfg_attr( |
545 | | feature = "serde-1", |
546 | | derive(serde_derive::Serialize, serde_derive::Deserialize) |
547 | | )] |
548 | | pub enum Direction { |
549 | | /// An `Outgoing` edge is an outward edge *from* the current node. |
550 | | Outgoing = 0, |
551 | | /// An `Incoming` edge is an inbound edge *to* the current node. |
552 | | Incoming = 1, |
553 | | } |
554 | | |
555 | | impl Direction { |
556 | | /// Return the opposite `Direction`. |
557 | | #[inline] |
558 | 0 | pub fn opposite(self) -> Direction { |
559 | 0 | match self { |
560 | 0 | Outgoing => Incoming, |
561 | 0 | Incoming => Outgoing, |
562 | | } |
563 | 0 | } |
564 | | |
565 | | /// Return `0` for `Outgoing` and `1` for `Incoming`. |
566 | | #[inline] |
567 | 0 | pub fn index(self) -> usize { |
568 | 0 | (self as usize) & 0x1 |
569 | 0 | } |
570 | | } |
571 | | |
572 | | #[doc(hidden)] |
573 | | pub use crate::Direction as EdgeDirection; |
574 | | |
575 | | /// Marker type for a directed graph. |
576 | | #[derive(Clone, Copy, Debug)] |
577 | | #[cfg_attr( |
578 | | feature = "serde-1", |
579 | | derive(serde_derive::Serialize, serde_derive::Deserialize) |
580 | | )] |
581 | | pub enum Directed {} |
582 | | |
583 | | /// Marker type for an undirected graph. |
584 | | #[derive(Clone, Copy, Debug)] |
585 | | #[cfg_attr( |
586 | | feature = "serde-1", |
587 | | derive(serde_derive::Serialize, serde_derive::Deserialize) |
588 | | )] |
589 | | pub enum Undirected {} |
590 | | |
591 | | /// A graph's edge type determines whether it has directed edges or not. |
592 | | pub trait EdgeType { |
593 | | fn is_directed() -> bool; |
594 | | } |
595 | | |
596 | | impl EdgeType for Directed { |
597 | | #[inline] |
598 | 802 | fn is_directed() -> bool { |
599 | 802 | true |
600 | 802 | } <petgraph::Directed as petgraph::EdgeType>::is_directed Line | Count | Source | 598 | 802 | fn is_directed() -> bool { | 599 | 802 | true | 600 | 802 | } |
Unexecuted instantiation: <petgraph::Directed as petgraph::EdgeType>::is_directed |
601 | | } |
602 | | |
603 | | impl EdgeType for Undirected { |
604 | | #[inline] |
605 | 0 | fn is_directed() -> bool { |
606 | 0 | false |
607 | 0 | } |
608 | | } |
609 | | |
610 | | /// Convert an element like `(i, j)` or `(i, j, w)` into |
611 | | /// a triple of source, target, edge weight. |
612 | | /// |
613 | | /// For `Graph::from_edges` and `GraphMap::from_edges`. |
614 | | pub trait IntoWeightedEdge<E> { |
615 | | type NodeId; |
616 | | fn into_weighted_edge(self) -> (Self::NodeId, Self::NodeId, E); |
617 | | } |
618 | | |
619 | | impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix) |
620 | | where |
621 | | E: Default, |
622 | | { |
623 | | type NodeId = Ix; |
624 | | |
625 | 0 | fn into_weighted_edge(self) -> (Ix, Ix, E) { |
626 | 0 | let (s, t) = self; |
627 | 0 | (s, t, E::default()) |
628 | 0 | } |
629 | | } |
630 | | |
631 | | impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix, E) { |
632 | | type NodeId = Ix; |
633 | 0 | fn into_weighted_edge(self) -> (Ix, Ix, E) { |
634 | 0 | self |
635 | 0 | } |
636 | | } |
637 | | |
638 | | impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix, &E) |
639 | | where |
640 | | E: Clone, |
641 | | { |
642 | | type NodeId = Ix; |
643 | 0 | fn into_weighted_edge(self) -> (Ix, Ix, E) { |
644 | 0 | let (a, b, c) = self; |
645 | 0 | (a, b, c.clone()) |
646 | 0 | } |
647 | | } |
648 | | |
649 | | impl<Ix, E> IntoWeightedEdge<E> for &(Ix, Ix) |
650 | | where |
651 | | Ix: Copy, |
652 | | E: Default, |
653 | | { |
654 | | type NodeId = Ix; |
655 | 0 | fn into_weighted_edge(self) -> (Ix, Ix, E) { |
656 | 0 | let (s, t) = *self; |
657 | 0 | (s, t, E::default()) |
658 | 0 | } |
659 | | } |
660 | | |
661 | | impl<Ix, E> IntoWeightedEdge<E> for &(Ix, Ix, E) |
662 | | where |
663 | | Ix: Copy, |
664 | | E: Clone, |
665 | | { |
666 | | type NodeId = Ix; |
667 | 0 | fn into_weighted_edge(self) -> (Ix, Ix, E) { |
668 | 0 | self.clone() |
669 | 0 | } |
670 | | } |