-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move complete_graph generator to rustworkx-core #772
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
89d3715
Initial complete graph
enavarro51 c8fa63d
Add tests
enavarro51 7ad15e5
Finish tests
enavarro51 854d7d0
Merge main
enavarro51 2c1a5a3
Fmt
enavarro51 68c4aa8
Merge branch 'main' into gen_complete_graph
enavarro51 0717ca6
Mesh calls complete
enavarro51 90fa539
Update tests
enavarro51 22dfc11
Fmt
enavarro51 7278f73
Merge branch 'main' into gen_complete_graph
enavarro51 af75626
Simplify mesh call
enavarro51 684ff59
Merge main
enavarro51 189bd30
Remove get_num_nodes from generators.rs
enavarro51 2170906
Merge branch 'main' into gen_complete_graph
enavarro51 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
// not use this file except in compliance with the License. You may obtain | ||
// a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations | ||
// under the License. | ||
|
||
use petgraph::data::{Build, Create}; | ||
use petgraph::visit::{Data, GraphProp, NodeIndexable}; | ||
|
||
use super::utils::get_num_nodes; | ||
use super::InvalidInputError; | ||
|
||
/// Generate a complete graph | ||
/// | ||
/// Arguments: | ||
/// | ||
/// * `num_nodes` - The number of nodes to create a complete graph for. Either this or | ||
/// `weights must be specified. If both this and `weights are specified, weights | ||
/// will take priorty and this argument will be ignored | ||
/// * `weights` - A `Vec` of node weight objects. | ||
/// * `default_node_weight` - A callable that will return the weight to use | ||
/// for newly created nodes. This is ignored if `weights` is specified, | ||
/// as the weights from that argument will be used instead. | ||
/// * `default_edge_weight` - A callable that will return the weight object | ||
/// to use for newly created edges. | ||
/// | ||
/// # Example | ||
/// ```rust | ||
/// use rustworkx_core::petgraph; | ||
/// use rustworkx_core::generators::complete_graph; | ||
/// use rustworkx_core::petgraph::visit::EdgeRef; | ||
/// | ||
/// let g: petgraph::graph::UnGraph<(), ()> = complete_graph( | ||
/// Some(4), | ||
/// None, | ||
/// || {()}, | ||
/// || {()}, | ||
/// ).unwrap(); | ||
/// assert_eq!( | ||
/// vec![(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], | ||
/// g.edge_references() | ||
/// .map(|edge| (edge.source().index(), edge.target().index())) | ||
/// .collect::<Vec<(usize, usize)>>(), | ||
/// ) | ||
/// ``` | ||
pub fn complete_graph<G, T, F, H, M>( | ||
num_nodes: Option<usize>, | ||
weights: Option<Vec<T>>, | ||
mut default_node_weight: F, | ||
mut default_edge_weight: H, | ||
) -> Result<G, InvalidInputError> | ||
where | ||
G: Build + Create + Data<NodeWeight = T, EdgeWeight = M> + NodeIndexable + GraphProp, | ||
F: FnMut() -> T, | ||
H: FnMut() -> M, | ||
{ | ||
if weights.is_none() && num_nodes.is_none() { | ||
return Err(InvalidInputError {}); | ||
} | ||
let node_len = get_num_nodes(&num_nodes, &weights); | ||
let mut graph = G::with_capacity(node_len, node_len); | ||
if node_len == 0 { | ||
return Ok(graph); | ||
} | ||
|
||
match weights { | ||
Some(weights) => { | ||
for weight in weights { | ||
graph.add_node(weight); | ||
} | ||
} | ||
None => { | ||
for _ in 0..node_len { | ||
graph.add_node(default_node_weight()); | ||
} | ||
} | ||
}; | ||
for i in 0..node_len - 1 { | ||
for j in i + 1..node_len { | ||
let node_i = graph.from_index(i); | ||
let node_j = graph.from_index(j); | ||
graph.add_edge(node_i, node_j, default_edge_weight()); | ||
if graph.is_directed() { | ||
graph.add_edge(node_j, node_i, default_edge_weight()); | ||
} | ||
} | ||
} | ||
Ok(graph) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::generators::complete_graph; | ||
use crate::generators::InvalidInputError; | ||
use crate::petgraph::graph::{DiGraph, NodeIndex, UnGraph}; | ||
use crate::petgraph::visit::EdgeRef; | ||
|
||
#[test] | ||
fn test_directed_complete_graph() { | ||
let g: DiGraph<(), ()> = complete_graph(Some(10), None, || (), || ()).unwrap(); | ||
assert_eq!(g.node_count(), 10); | ||
assert_eq!(g.edge_count(), 90); | ||
let mut elist = vec![]; | ||
for i in 0..10 { | ||
for j in i..10 { | ||
if i != j { | ||
elist.push((i, j)); | ||
elist.push((j, i)); | ||
} | ||
} | ||
} | ||
assert_eq!( | ||
elist, | ||
g.edge_references() | ||
.map(|edge| (edge.source().index(), edge.target().index())) | ||
.collect::<Vec<(usize, usize)>>(), | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_directed_complete_graph_weights() { | ||
let g: DiGraph<usize, ()> = | ||
complete_graph(None, Some(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), || 4, || ()).unwrap(); | ||
assert_eq!(g.node_count(), 10); | ||
assert_eq!(g.edge_count(), 90); | ||
let mut elist = vec![]; | ||
for i in 0..10 { | ||
for j in i..10 { | ||
if i != j { | ||
elist.push((i, j)); | ||
elist.push((j, i)); | ||
} | ||
} | ||
assert_eq!(*g.node_weight(NodeIndex::new(i)).unwrap(), i); | ||
} | ||
assert_eq!( | ||
elist, | ||
g.edge_references() | ||
.map(|edge| (edge.source().index(), edge.target().index())) | ||
.collect::<Vec<(usize, usize)>>(), | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_compete_graph_error() { | ||
match complete_graph::<DiGraph<(), ()>, (), _, _, ()>(None, None, || (), || ()) { | ||
Ok(_) => panic!("Returned a non-error"), | ||
Err(e) => assert_eq!(e, InvalidInputError), | ||
}; | ||
} | ||
|
||
#[test] | ||
fn test_complete_graph() { | ||
let g: UnGraph<(), ()> = complete_graph(Some(10), None, || (), || ()).unwrap(); | ||
assert_eq!(g.node_count(), 10); | ||
assert_eq!(g.edge_count(), 45); | ||
let mut elist = vec![]; | ||
for i in 0..10 { | ||
for j in i..10 { | ||
if i != j { | ||
elist.push((i, j)); | ||
} | ||
} | ||
} | ||
assert_eq!( | ||
elist, | ||
g.edge_references() | ||
.map(|edge| (edge.source().index(), edge.target().index())) | ||
.collect::<Vec<(usize, usize)>>(), | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_complete_graph_weights() { | ||
let g: UnGraph<usize, ()> = | ||
complete_graph(None, Some(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), || 4, || ()).unwrap(); | ||
assert_eq!(g.node_count(), 10); | ||
assert_eq!(g.edge_count(), 45); | ||
let mut elist = vec![]; | ||
for i in 0..10 { | ||
for j in i..10 { | ||
if i != j { | ||
elist.push((i, j)); | ||
} | ||
} | ||
assert_eq!(*g.node_weight(NodeIndex::new(i)).unwrap(), i); | ||
} | ||
assert_eq!( | ||
elist, | ||
g.edge_references() | ||
.map(|edge| (edge.source().index(), edge.target().index())) | ||
.collect::<Vec<(usize, usize)>>(), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same apllies here, I'd call
directed_mesh_graph(py, num_nodes, weights, multigraph)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in af75626.