diff --git a/src/graphmap.rs b/src/graphmap.rs index 3d047424a..04a682989 100644 --- a/src/graphmap.rs +++ b/src/graphmap.rs @@ -477,6 +477,37 @@ where } gr } + + /// Creates a `GraphMap` that corresponds to the given `Graph`. + /// + /// **Warning**: Nodes with the same weight are merged and only the last parallel edge + /// is kept. Node and edge indices of the `Graph` are lost. Only use this function + /// if the node weights are distinct and there are no parallel edges. + /// + /// Computes in **O(|V| + |E|)** time (average). + pub fn from_graph(graph: Graph) -> Self + where + Ix: crate::graph::IndexType, + E: Clone, + { + let mut new_graph: GraphMap = + GraphMap::with_capacity(graph.node_count(), graph.edge_count()); + + for node in graph.raw_nodes() { + new_graph.add_node(node.weight); + } + + for edge in graph.edge_indices() { + let (a, b) = graph.edge_endpoints(edge).unwrap(); + new_graph.add_edge( + *graph.node_weight(a).unwrap(), + *graph.node_weight(b).unwrap(), + graph.edge_weight(edge).unwrap().clone(), + ); + } + + new_graph + } } /// Create a new `GraphMap` from an iterable of edges. diff --git a/tests/graphmap.rs b/tests/graphmap.rs index 42b9e2aa5..cc023258a 100644 --- a/tests/graphmap.rs +++ b/tests/graphmap.rs @@ -325,6 +325,26 @@ fn test_into_graph() { } } +#[test] +fn test_from_graph() { + let mut gr: Graph = Graph::new(); + let node_a = gr.add_node(12); + let node_b = gr.add_node(13); + let node_c = gr.add_node(14); + gr.add_edge(node_a, node_b, 1000); + gr.add_edge(node_b, node_c, 999); + gr.add_edge(node_c, node_a, 1111); + gr.add_node(42); + let gr = gr; + + let graph: GraphMap = GraphMap::from_graph(gr.clone()); + println!("{}", Dot::new(&gr)); + println!("{}", Dot::new(&graph)); + + assert!(petgraph::algo::is_isomorphic(&gr, &graph)); + assert_eq!(graph[(12, 13)], 1000); +} + #[test] fn test_all_edges_mut() { // graph with edge weights equal to in+out