From b6591597cad25722ce85cfb5d5079ce7f885f990 Mon Sep 17 00:00:00 2001 From: Edwin Navarro Date: Sat, 4 Feb 2023 12:00:24 -0800 Subject: [PATCH] Docs and consistency cleanup for rustworkx-core generators (#784) * Initial r-ary * Complete tests * Lint and name change * Clippy * Code and docs consistency * Docs changes to generators.rs * Reorder graphs in generators.rs * Switch binomial tree to update_edge * Update bidirectional docs * Cleanup rest of docs and return find_edge in binomial tree * Second round on heavy docs * Minor doc change * Make core utils and cleanup docs * Fmt * Text and PyGraph fixes --- .../src/generators/barbell_graph.rs | 23 +- .../src/generators/binomial_tree_graph.rs | 9 +- .../src/generators/complete_graph.rs | 5 +- rustworkx-core/src/generators/cycle_graph.rs | 9 +- .../src/generators/full_rary_tree_graph.rs | 13 +- rustworkx-core/src/generators/grid_graph.rs | 7 +- .../src/generators/heavy_hex_graph.rs | 78 +- .../src/generators/heavy_square_graph.rs | 56 +- .../src/generators/hexagonal_lattice_graph.rs | 7 +- .../src/generators/lollipop_graph.rs | 29 +- rustworkx-core/src/generators/path_graph.rs | 9 +- .../src/generators/petersen_graph.rs | 15 +- rustworkx-core/src/generators/star_graph.rs | 9 +- rustworkx-core/src/generators/utils.rs | 10 - rustworkx-core/src/lib.rs | 1 + rustworkx-core/src/utils.rs | 21 + src/generators.rs | 1062 +++++++++-------- src/steiner_tree.rs | 2 +- 18 files changed, 686 insertions(+), 679 deletions(-) create mode 100644 rustworkx-core/src/utils.rs diff --git a/rustworkx-core/src/generators/barbell_graph.rs b/rustworkx-core/src/generators/barbell_graph.rs index e7383f5af..74d6f56f1 100644 --- a/rustworkx-core/src/generators/barbell_graph.rs +++ b/rustworkx-core/src/generators/barbell_graph.rs @@ -16,36 +16,33 @@ use petgraph::data::{Build, Create}; use petgraph::visit::{Data, NodeIndexable, NodeRef}; use super::utils::get_num_nodes; -use super::utils::pairwise; use super::InvalidInputError; +use crate::utils::pairwise; -/// Generate an undirected barbell graph where two identical mesh graphs are +/// Generate a barbell graph where two identical complete graphs are /// connected by a path. /// -/// .. note:: -/// -/// If neither `num_path_nodes` nor `path_weights` (described below) is not specified -/// then this is equivalent to two mesh graphs joined together. +/// If neither `num_path_nodes` nor `path_weights` (described below) are +/// specified, then this is equivalent to two complete graphs joined together. /// /// Arguments: /// /// * `num_mesh_nodes` - The number of nodes to generate the mesh graph /// with. Node weights will be None if this is specified. If both -/// `num_mesh_nodes` and `mesh_weights` are set this will be ignored and +/// `num_mesh_nodes` and `mesh_weights` are set, this will be ignored and /// `mesh_weights` will be used. /// * `num_path_nodes` - The number of nodes to generate the path /// with. Node weights will be None if this is specified. If both -/// `num_path_nodes` and `path_weights` are set this will be ignored and +/// `num_path_nodes` and `path_weights` are set, this will be ignored and /// `path_weights` will be used. /// * `mesh_weights` - A list of node weights for the mesh graph. If both -/// `num_mesh_nodes` and `mesh_weights` are set `num_mesh_nodes` will +/// `num_mesh_nodes` and `mesh_weights` are set, `num_mesh_nodes` will /// be ignored and `mesh_weights` will be used. /// * `path_weights` - A list of node weights for the path. If both -/// `num_path_nodes` and `path_weights` are set `num_path_nodes` will +/// `num_path_nodes` and `path_weights` are set, `num_path_nodes` will /// be ignored and `path_weights` will be used. /// * `default_node_weight` - A callable that will return the weight to use -/// for newly created nodes. This is ignored if weights are specified, -/// as the weights from that argument will be used instead. +/// for newly created nodes. This is ignored if node weights are specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. /// @@ -147,7 +144,7 @@ where } }; let pathlen = path_nodes.len(); - if pathlen > 0 { + if !path_nodes.is_empty() { graph.add_edge( graph.from_index(meshlen - 1), graph.from_index(meshlen), diff --git a/rustworkx-core/src/generators/binomial_tree_graph.rs b/rustworkx-core/src/generators/binomial_tree_graph.rs index 27837be99..4ee04b47d 100644 --- a/rustworkx-core/src/generators/binomial_tree_graph.rs +++ b/rustworkx-core/src/generators/binomial_tree_graph.rs @@ -21,15 +21,14 @@ use super::InvalidInputError; /// /// * `order` - The order of the binomial tree. /// * `weights` - A `Vec` of node weight objects. If the number of weights is -/// less than 2**order extra nodes with None will be appended. +/// less than 2**order, extra nodes with None will be appended. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/complete_graph.rs b/rustworkx-core/src/generators/complete_graph.rs index 0aa7753c1..c07f4ee3d 100644 --- a/rustworkx-core/src/generators/complete_graph.rs +++ b/rustworkx-core/src/generators/complete_graph.rs @@ -21,12 +21,11 @@ use super::InvalidInputError; /// 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 +/// `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. /// diff --git a/rustworkx-core/src/generators/cycle_graph.rs b/rustworkx-core/src/generators/cycle_graph.rs index f8b14838f..0cc603d8b 100644 --- a/rustworkx-core/src/generators/cycle_graph.rs +++ b/rustworkx-core/src/generators/cycle_graph.rs @@ -21,17 +21,16 @@ use super::InvalidInputError; /// Arguments: /// /// * `num_nodes` - The number of nodes to create a cycle graph for. Either this or -/// `weights must be specified. If both this and `weights are specified, weights +/// `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/full_rary_tree_graph.rs b/rustworkx-core/src/generators/full_rary_tree_graph.rs index 181491ddb..932038ea7 100644 --- a/rustworkx-core/src/generators/full_rary_tree_graph.rs +++ b/rustworkx-core/src/generators/full_rary_tree_graph.rs @@ -18,21 +18,22 @@ use petgraph::visit::{Data, NodeIndexable}; use super::InvalidInputError; -/// Creates a full r-ary tree of `n` nodes. +/// Generate a full r-ary tree of `n` nodes. /// Sometimes called a k-ary, n-ary, or m-ary tree. /// +/// Arguments: +/// /// * `branching factor` - The number of children at each node. /// * `num_nodes` - The number of nodes in the graph. /// * `weights` - A list of node weights. If the number of weights is -/// less than n, extra nodes with with None weight will be appended. +/// less than n, extra nodes with None weight will be appended. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/grid_graph.rs b/rustworkx-core/src/generators/grid_graph.rs index 2fdeb3ee7..9444367f4 100644 --- a/rustworkx-core/src/generators/grid_graph.rs +++ b/rustworkx-core/src/generators/grid_graph.rs @@ -21,7 +21,7 @@ use super::InvalidInputError; /// /// * `rows` - The number of rows to generate the graph with. /// If specified, cols also need to be specified. -/// * `cols`: The number of rows to generate the graph with. +/// * `cols`: The number of columns to generate the graph with. /// If specified, rows also need to be specified. rows*cols /// defines the number of nodes in the graph. /// * `weights`: A `Vec` of node weights. Nodes are filled row wise. @@ -32,11 +32,10 @@ use super::InvalidInputError; /// If number of nodes(rows*cols) is greater than length of /// weights list, extra nodes with None weight are appended. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. /// If the graph is undirected this will result in a parallel edge. /// diff --git a/rustworkx-core/src/generators/heavy_hex_graph.rs b/rustworkx-core/src/generators/heavy_hex_graph.rs index 2d2821d8b..abe3a3203 100644 --- a/rustworkx-core/src/generators/heavy_hex_graph.rs +++ b/rustworkx-core/src/generators/heavy_hex_graph.rs @@ -17,53 +17,53 @@ use petgraph::visit::{Data, NodeIndexable}; use super::InvalidInputError; -/// Generate an undirected heavy hex graph. Fig. 2 of -/// https://arxiv.org/abs/1907.09528 -/// An ASCII diagram of the graph is given by: -/// -/// .. note:: +/// Generate a heavy hex graph. /// +/// Fig. 2 of +/// An ASCII diagram of the graph is given by: +/// ```text /// ... D-S-D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ... D D-S-D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ... D D-S-D ... +///``` /// +/// Arguments: /// -/// * `d` - Distance of the code. If ``d`` is set to ``1`` a graph with a -/// single node will be returned. d must be an odd number. +/// * `d` - Distance of the code. If `d` is set to `1` a graph with a +/// single node will be returned. `d` must be an odd number. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/heavy_square_graph.rs b/rustworkx-core/src/generators/heavy_square_graph.rs index 05e19632c..52777f8ea 100644 --- a/rustworkx-core/src/generators/heavy_square_graph.rs +++ b/rustworkx-core/src/generators/heavy_square_graph.rs @@ -17,38 +17,42 @@ use petgraph::visit::{Data, NodeIndexable}; use super::InvalidInputError; -/// Generate an directed heavy square graph. Fig. 6 of -/// https://arxiv.org/abs/1907.09528. -/// An ASCII diagram of the graph is given by: -/// -/// .. note:: +/// Generate a heavy square graph. /// +/// Fig. 6 of +/// An ASCII diagram of the graph is given by: +/// ```text /// ... S ... /// \ / \ -/// ... D D D ... -/// | | | -/// ... F-S-F-S-F-... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F-S-F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// \ / \ -/// ... S ... -/// +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// \ / \ +/// ... S ... +/// ``` /// NOTE: This function generates the four-frequency variant of the heavy square code. -/// This function implements Fig 10.b left of the `paper `_. +/// This function implements Fig 10.b left of the paper . /// This function doesn't support the variant Fig 10.b right. /// -/// :param int d: distance of the code. If ``d`` is set to ``1`` a -/// :class:`~rustworkx.PyDiGraph` with a single node will be returned. -/// :param bool multigraph: When set to False the output -/// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead -/// calls which would create a parallel edge will update the existing edge. +/// Arguments: +/// +/// * `d` - Distance of the code. If `d` is set to `1` a graph with a +/// single node will be returned. `d` must be an odd number. +/// * `default_node_weight` - A callable that will return the weight to use +/// for newly created nodes. This is ignored if `weights` is specified. +/// * `default_edge_weight` - A callable that will return the weight object +/// to use for newly created edges. +/// * `bidirectional` - Whether edges are added bidirectionally. If set to +/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/hexagonal_lattice_graph.rs b/rustworkx-core/src/generators/hexagonal_lattice_graph.rs index 56f4f58dd..7adbba201 100644 --- a/rustworkx-core/src/generators/hexagonal_lattice_graph.rs +++ b/rustworkx-core/src/generators/hexagonal_lattice_graph.rs @@ -24,13 +24,12 @@ use super::InvalidInputError; /// * `rows` - The number of rows to generate the graph with. /// * `cols` - The number of columns to generate the graph with. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/lollipop_graph.rs b/rustworkx-core/src/generators/lollipop_graph.rs index afbdfc69e..dee8a7a7f 100644 --- a/rustworkx-core/src/generators/lollipop_graph.rs +++ b/rustworkx-core/src/generators/lollipop_graph.rs @@ -15,19 +15,16 @@ use std::hash::Hash; use petgraph::data::{Build, Create}; use petgraph::visit::{Data, GraphProp, NodeIndexable}; -use super::utils::pairwise; +use super::utils::get_num_nodes; use super::InvalidInputError; +use crate::utils::pairwise; -/// Generate a lollipop graph +/// Generate a lollipop graph where a complete graph is connected to a path. /// -/// Arguments: -/// -/// Generate an undirected lollipop graph where a mesh graph is connected to a -/// path. +/// If neither `num_path_nodes` nor `path_weights` (described below) are +/// specified, then this is equivalent to a complete graph. /// -/// If neither `num_path_nodes` nor `path_weights` (both described -/// below) are specified then this is equivalent to -/// :func:`~rustworkx.generators.mesh_graph` +/// Arguments: /// /// * `num_mesh_nodes` - The number of nodes to generate the mesh graph /// with. Node weights will be None if this is specified. If both @@ -44,8 +41,7 @@ use super::InvalidInputError; /// `num_path_nodes` and `path_weights` are set `num_path_nodes` will /// be ignored and `path_weights` will be used. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. /// @@ -98,12 +94,7 @@ where if num_mesh_nodes.is_none() && mesh_weights.is_none() { return Err(InvalidInputError {}); } - let num_nodes: usize; - if let Some(mesh_nodes) = num_mesh_nodes { - num_nodes = mesh_nodes; - } else { - num_nodes = mesh_weights.as_ref().unwrap().len(); - } + let num_nodes = get_num_nodes(&num_mesh_nodes, &mesh_weights); let num_edges = (num_nodes * (num_nodes - 1)) / 2; let mut graph = G::with_capacity(num_nodes, num_edges); @@ -138,8 +129,7 @@ where } } }; - let pathlen = path_nodes.len(); - if pathlen > 0 { + if !path_nodes.is_empty() { graph.add_edge( graph.from_index(meshlen - 1), graph.from_index(meshlen), @@ -160,6 +150,7 @@ mod tests { use crate::generators::lollipop_graph; use crate::generators::InvalidInputError; use crate::petgraph::visit::EdgeRef; + #[test] fn test_lollipop_mesh_path() { let expected_edge_list = vec![ diff --git a/rustworkx-core/src/generators/path_graph.rs b/rustworkx-core/src/generators/path_graph.rs index 2317e47e8..7aff79d7b 100644 --- a/rustworkx-core/src/generators/path_graph.rs +++ b/rustworkx-core/src/generators/path_graph.rs @@ -21,17 +21,16 @@ use super::InvalidInputError; /// Arguments: /// /// * `num_nodes` - The number of nodes to create a path graph for. Either this or -/// `weights must be specified. If both this and `weights are specified, weights +/// `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/petersen_graph.rs b/rustworkx-core/src/generators/petersen_graph.rs index 905d2fb0d..170894e30 100644 --- a/rustworkx-core/src/generators/petersen_graph.rs +++ b/rustworkx-core/src/generators/petersen_graph.rs @@ -17,24 +17,21 @@ use petgraph::visit::{Data, NodeIndexable}; use super::InvalidInputError; -/// Generate a generalized Petersen graph :math:`G(n, k)` with :math:`2n` -/// nodes and :math:`3n` edges. See Watkins [1]_ for more details. +/// Generate a generalized Petersen graph `G(n, k)` with `2n` +/// nodes and `3n` edges. /// -/// .. note:: -/// -/// The Petersen graph itself is denoted :math:`G(5, 2)` +/// The Petersen graph itself is denoted `G(5, 2)` /// /// * `n` - Number of nodes in the internal star and external regular polygon. /// n > 2. /// * `k` - Shift that changes the internal star graph. k > 0 and 2 * k < n. /// * `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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. -/// If the graph is undirected this will result in a pallel edge. +/// If the graph is undirected this will result in a parallel edge. /// /// # Example /// ```rust diff --git a/rustworkx-core/src/generators/star_graph.rs b/rustworkx-core/src/generators/star_graph.rs index a185a943a..4fea65d27 100644 --- a/rustworkx-core/src/generators/star_graph.rs +++ b/rustworkx-core/src/generators/star_graph.rs @@ -20,19 +20,18 @@ use super::InvalidInputError; /// /// Arguments: /// -/// * `num_nodes` - The number of nodes to create a path graph for. Either this or +/// * `num_nodes` - The number of nodes to create a star 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. +/// for newly created nodes. This is ignored if `weights` is specified. /// * `default_edge_weight` - A callable that will return the weight object /// to use for newly created edges. -/// * inward: If set `true` the nodes will be directed towards the +/// * `inward` - If set `true` the nodes will be directed towards the /// center node. This parameter is ignored if `bidirectional` is set to /// `true`. -/// * `bidirectional` - Whether edges are added bidirectionally, if set to +/// * `bidirectional` - Whether edges are added bidirectionally. If set to /// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added. /// If the graph is undirected this will result in a parallel edge. diff --git a/rustworkx-core/src/generators/utils.rs b/rustworkx-core/src/generators/utils.rs index 3eb178fb5..b63ab7043 100644 --- a/rustworkx-core/src/generators/utils.rs +++ b/rustworkx-core/src/generators/utils.rs @@ -10,8 +10,6 @@ // License for the specific language governing permissions and limitations // under the License. -use std::iter; - #[inline] pub fn get_num_nodes(num_nodes: &Option, weights: &Option>) -> usize { if weights.is_some() { @@ -20,11 +18,3 @@ pub fn get_num_nodes(num_nodes: &Option, weights: &Option>) -> num_nodes.unwrap() } } - -pub fn pairwise(right: I) -> impl Iterator, I::Item)> -where - I: IntoIterator + Clone, -{ - let left = iter::once(None).chain(right.clone().into_iter().map(Some)); - left.zip(right) -} diff --git a/rustworkx-core/src/lib.rs b/rustworkx-core/src/lib.rs index 2dc7f7b8c..4da244f5c 100644 --- a/rustworkx-core/src/lib.rs +++ b/rustworkx-core/src/lib.rs @@ -82,6 +82,7 @@ pub mod traversal; pub mod dictmap; pub mod distancemap; mod min_scored; +pub mod utils; // re-export petgraph so there is a consistent version available to users and // then only need to require rustworkx-core in their dependencies diff --git a/rustworkx-core/src/utils.rs b/rustworkx-core/src/utils.rs new file mode 100644 index 000000000..d8a4f300d --- /dev/null +++ b/rustworkx-core/src/utils.rs @@ -0,0 +1,21 @@ +// 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 std::iter; + +pub fn pairwise(right: I) -> impl Iterator, I::Item)> +where + I: IntoIterator + Clone, +{ + let left = iter::once(None).chain(right.clone().into_iter().map(Some)); + left.zip(right) +} diff --git a/src/generators.rs b/src/generators.rs index 6bb8085dd..f8168d0c7 100644 --- a/src/generators.rs +++ b/src/generators.rs @@ -10,8 +10,6 @@ // License for the specific language governing permissions and limitations // under the License. -use std::iter; - use petgraph::algo; use petgraph::prelude::*; use petgraph::Undirected; @@ -24,25 +22,71 @@ use pyo3::Python; use super::{digraph, graph, StablePyGraph}; use rustworkx_core::generators as core_generators; -pub fn pairwise(right: I) -> impl Iterator, I::Item)> -where - I: IntoIterator + Clone, -{ - let left = iter::once(None).chain(right.clone().into_iter().map(Some)); - left.zip(right) +/// Generate an undirected cycle graph +/// +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and +/// ``weights`` are set this will be ignored and ``weights`` will be used. +/// :param list weights: A list of node weights, the first element in the list +/// will be the center node of the cycle graph. If both ``num_nodes`` and +/// ``weights`` are set this will be ignored and ``weights`` will be used. +/// :param bool multigraph: When set to ``False`` the output +/// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and +/// won't allow parallel edges to be added. Instead +/// calls which would create a parallel edge will update the existing edge. +/// +/// :returns: The generated cycle graph +/// :rtype: PyGraph +/// :raises IndexError: If neither ``num_nodes`` or ``weights`` are specified +/// +/// .. jupyter-execute:: +/// +/// import rustworkx.generators +/// from rustworkx.visualization import mpl_draw +/// +/// graph = rustworkx.generators.cycle_graph(5) +/// mpl_draw(graph) +/// +#[pyfunction] +#[pyo3( + signature=(num_nodes=None, weights=None, multigraph=true), + text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" +)] +pub fn cycle_graph( + py: Python, + num_nodes: Option, + weights: Option>, + multigraph: bool, +) -> PyResult { + let default_fn = || py.None(); + let graph: StablePyGraph = + match core_generators::cycle_graph(num_nodes, weights, default_fn, default_fn, false) { + Ok(graph) => graph, + Err(_) => { + return Err(PyIndexError::new_err( + "num_nodes and weights list not specified", + )) + } + }; + Ok(graph::PyGraph { + graph, + node_removed: false, + multigraph, + attrs: py.None(), + }) } -/// Generate a cycle graph +/// Generate a directed cycle graph /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the cycle graph. If both ``num_node`` and +/// will be the center node of the cycle graph. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param bool bidirectional: Adds edges in both directions between two nodes /// if set to ``True``. Default value is ``False`` -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -96,20 +140,20 @@ pub fn directed_cycle_graph( }) } -/// Generate an undirected cycle graph +/// Generate an undirected path graph /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the cycle graph. If both ``num_node`` and +/// will be the center node of the path graph. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: The generated cycle graph +/// :returns: The generated path graph /// :rtype: PyGraph /// :raises IndexError: If neither ``num_nodes`` or ``weights`` are specified /// @@ -118,7 +162,7 @@ pub fn directed_cycle_graph( /// import rustworkx.generators /// from rustworkx.visualization import mpl_draw /// -/// graph = rustworkx.generators.cycle_graph(5) +/// graph = rustworkx.generators.path_graph(10) /// mpl_draw(graph) /// #[pyfunction] @@ -126,7 +170,7 @@ pub fn directed_cycle_graph( signature=(num_nodes=None, weights=None, multigraph=true), text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] -pub fn cycle_graph( +pub fn path_graph( py: Python, num_nodes: Option, weights: Option>, @@ -134,7 +178,7 @@ pub fn cycle_graph( ) -> PyResult { let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::cycle_graph(num_nodes, weights, default_fn, default_fn, false) { + match core_generators::path_graph(num_nodes, weights, default_fn, default_fn, false) { Ok(graph) => graph, Err(_) => { return Err(PyIndexError::new_err( @@ -152,15 +196,15 @@ pub fn cycle_graph( /// Generate a directed path graph /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the path graph. If both ``num_node`` and +/// will be the center node of the path graph. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param bool bidirectional: Adds edges in both directions between two nodes /// if set to ``True``. Default value is ``False`` -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -214,20 +258,21 @@ pub fn directed_path_graph( }) } -/// Generate an undirected path graph +/// Generate an undirected star graph /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the path graph. If both ``num_node`` and +/// will be the center node of the star graph. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: The generated path graph +/// +/// :returns: The generated star graph /// :rtype: PyGraph /// :raises IndexError: If neither ``num_nodes`` or ``weights`` are specified /// @@ -236,7 +281,7 @@ pub fn directed_path_graph( /// import rustworkx.generators /// from rustworkx.visualization import mpl_draw /// -/// graph = rustworkx.generators.path_graph(10) +/// graph = rustworkx.generators.star_graph(10) /// mpl_draw(graph) /// #[pyfunction] @@ -244,7 +289,7 @@ pub fn directed_path_graph( signature=(num_nodes=None, weights=None, multigraph=true), text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] -pub fn path_graph( +pub fn star_graph( py: Python, num_nodes: Option, weights: Option>, @@ -252,7 +297,8 @@ pub fn path_graph( ) -> PyResult { let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::path_graph(num_nodes, weights, default_fn, default_fn, false) { + match core_generators::star_graph(num_nodes, weights, default_fn, default_fn, false, false) + { Ok(graph) => graph, Err(_) => { return Err(PyIndexError::new_err( @@ -270,18 +316,18 @@ pub fn path_graph( /// Generate a directed star graph /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the star graph. If both ``num_node`` and +/// will be the center node of the star graph. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. /// :param bool inward: If set ``True`` the nodes will be directed towards the /// center node. This parameter is ignored if ``bidirectional`` is set to /// ``True``. /// :param bool bidirectional: Adds edges in both directions between two nodes /// if set to ``True``. Default value is ``False``. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -345,72 +391,16 @@ pub fn directed_star_graph( }) } -/// Generate an undirected star graph -/// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and -/// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param list weights: A list of node weights, the first element in the list -/// will be the center node of the star graph. If both ``num_node`` and -/// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output -/// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead -/// calls which would create a parallel edge will update the existing edge. -/// -/// -/// :returns: The generated star graph -/// :rtype: PyGraph -/// :raises IndexError: If neither ``num_nodes`` or ``weights`` are specified -/// -/// .. jupyter-execute:: -/// -/// import rustworkx.generators -/// from rustworkx.visualization import mpl_draw -/// -/// graph = rustworkx.generators.star_graph(10) -/// mpl_draw(graph) -/// -#[pyfunction] -#[pyo3( - signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" -)] -pub fn star_graph( - py: Python, - num_nodes: Option, - weights: Option>, - multigraph: bool, -) -> PyResult { - let default_fn = || py.None(); - let graph: StablePyGraph = - match core_generators::star_graph(num_nodes, weights, default_fn, default_fn, false, false) - { - Ok(graph) => graph, - Err(_) => { - return Err(PyIndexError::new_err( - "num_nodes and weights list not specified", - )) - } - }; - Ok(graph::PyGraph { - graph, - node_removed: false, - multigraph, - attrs: py.None(), - }) -} - -/// Generate an undirected mesh graph where every node is connected to every other +/// Generate an undirected mesh (complete) graph where every node is connected to every other /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param list weights: A list of node weights. If both ``num_node`` and +/// :param list weights: A list of node weights. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// /// :returns: The generated mesh graph @@ -439,14 +429,14 @@ pub fn mesh_graph( complete_graph(py, num_nodes, weights, multigraph) } -/// Generate a directed mesh graph where every node is connected to every other +/// Generate a directed mesh (complete) graph where every node is connected to every other /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param list weights: A list of node weights. If both ``num_node`` and +/// :param list weights: A list of node weights. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -480,9 +470,9 @@ pub fn directed_mesh_graph( /// Generate an undirected grid graph. /// /// :param int rows: The number of rows to generate the graph with. -/// If specified, cols also need to be specified +/// If specified, ``cols`` also need to be specified /// :param int cols: The number of cols to generate the graph with. -/// If specified, rows also need to be specified. rows*cols +/// If specified, ``rows`` also need to be specified. rows*cols /// defines the number of nodes in the graph /// :param list weights: A list of node weights. Nodes are filled row wise. /// If rows and cols are not specified, then a linear graph containing @@ -491,9 +481,9 @@ pub fn directed_mesh_graph( /// weights list, the trailing weights are ignored. /// If number of nodes(rows*cols) is greater than length of /// weights list, extra nodes with None weight are appended. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// /// :returns: The generated grid graph @@ -535,13 +525,14 @@ pub fn grid_graph( }) } -/// Generate a directed grid graph. The edges propagate towards right and -/// bottom direction if ``bidirectional`` is ``false`` +/// Generate a directed grid graph. +/// +/// The edges propagate towards right and bottom direction if ``bidirectional`` is ``False`` /// /// :param int rows: The number of rows to generate the graph with. -/// If specified, cols also need to be specified. +/// If specified, ``cols`` also need to be specified. /// :param int cols: The number of cols to generate the graph with. -/// If specified, rows also need to be specified. rows*cols +/// If specified, ``rows`` also need to be specified. rows*cols /// defines the number of nodes in the graph. /// :param list weights: A list of node weights. Nodes are filled row wise. /// If rows and cols are not specified, then a linear graph containing @@ -551,8 +542,8 @@ pub fn grid_graph( /// If number of nodes(rows*cols) is greater than length of /// weights list, extra nodes with None weight are appended. /// :param bidirectional: A parameter to indicate if edges should exist in -/// both directions between nodes -/// :param bool multigraph: When set to False the output +/// both directions between nodes. Defaults to ``False``. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -605,65 +596,71 @@ pub fn directed_grid_graph( }) } -// MAX_ORDER is determined based on the pointer width of the target platform -#[cfg(target_pointer_width = "64")] -const MAX_ORDER: u32 = 60; -#[cfg(not(target_pointer_width = "64"))] -const MAX_ORDER: u32 = 29; - -/// Generate an undirected binomial tree of order n recursively. +/// Generate an undirected heavy square graph. /// -/// :param int order: Order of the binomial tree. The maximum allowed value -/// for order on the platform your running on. If it's a 64bit platform -/// the max value is 59 and on 32bit systems the max value is 29. Any order -/// value above these will raise a ``OverflowError``. -/// :param list weights: A list of node weights. If the number of weights is -/// less than 2**order extra nodes with with None will be appended. -/// :param bool multigraph: When set to False the output +/// Fig. 6 of https://arxiv.org/abs/1907.09528. +/// An ASCII diagram of the graph is given by: +/// +/// .. code-block:: console +/// +/// ... S ... +/// \ / \ +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// \ / \ +/// ... S ... +/// +/// +/// .. note:: +/// +/// This function generates the four-frequency variant of the heavy square code. +/// This function implements Fig 10.b left of the `paper `_. +/// This function doesn't support the variant Fig 10.b right. +/// +/// Note that if ``d`` is set to ``1`` a :class:`~rustworkx.PyGraph` with a +/// single node will be returned. +/// +/// :param int d: distance of the code. If ``d`` is set to ``1`` a +/// :class:`~rustworkx.PyGraph` with a single node will be returned. ``d`` must be +/// an odd number. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: A binomial tree with 2^n vertices and 2^n - 1 edges. +/// :returns: The generated heavy square graph /// :rtype: PyGraph -/// :raises IndexError: If the length of ``weights`` is greater that 2^n -/// :raises OverflowError: If the input order exceeds the maximum value for the -/// current platform. +/// :raises IndexError: If d is even. /// /// .. jupyter-execute:: /// /// import rustworkx.generators -/// from rustworkx.visualization import mpl_draw +/// from rustworkx.visualization import graphviz_draw /// -/// graph = rustworkx.generators.binomial_tree_graph(4) -/// mpl_draw(graph) +/// graph = rustworkx.generators.heavy_square_graph(3) +/// graphviz_draw(graph, lambda node: dict( +/// color='black', fillcolor='lightblue', style='filled')) /// #[pyfunction] #[pyo3( - signature=(order, weights=None, multigraph=true), - text_signature = "(order, /, weights=None, multigraph=True)" + signature=(d, multigraph=true), + text_signature = "(d, /, multigraph=True)" )] -pub fn binomial_tree_graph( - py: Python, - order: u32, - weights: Option>, - multigraph: bool, -) -> PyResult { - if order >= MAX_ORDER { - return Err(PyOverflowError::new_err(format!( - "An order of {} exceeds the max allowable size", - order - ))); - } +pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult { let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::binomial_tree_graph(order, weights, default_fn, default_fn, false) { + match core_generators::heavy_square_graph(d, default_fn, default_fn, false) { Ok(graph) => graph, - Err(_) => { - return Err(PyIndexError::new_err( - "num_nodes and weights list not specified", - )) - } + Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), }; Ok(graph::PyGraph { graph, @@ -673,69 +670,76 @@ pub fn binomial_tree_graph( }) } -/// Generate a directed binomial tree of order n recursively. -/// The edges propagate towards right and bottom direction if ``bidirectional`` is ``false`` +/// Generate an directed heavy square graph. /// -/// :param int order: Order of the binomial tree. The maximum allowed value -/// for order on the platform your running on. If it's a 64bit platform -/// the max value is 59 and on 32bit systems the max value is 29. Any order -/// value above these will raise a ``OverflowError``. -/// :param list weights: A list of node weights. If the number of weights is -/// less than 2**order extra nodes with None will be appended. +/// Fig. 6 of https://arxiv.org/abs/1907.09528. +/// An ASCII diagram of the graph is given by: +/// +/// .. code-block:: console +/// +/// ... S ... +/// \ / \ +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F-S-F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// \ / \ +/// ... S ... +/// +/// +/// .. note:: +/// +/// This function generates the four-frequency variant of the heavy square code. +/// This function implements Fig 10.b left of the `paper `_. +/// This function doesn't support the variant Fig 10.b right. +/// +/// :param int d: distance of the code. If ``d`` is set to ``1`` a +/// :class:`~rustworkx.PyDiGraph` with a single node will be returned. ``d`` must be +/// an odd number. /// :param bidirectional: A parameter to indicate if edges should exist in -/// both directions between nodes -/// :param bool multigraph: When set to False the output +/// both directions between nodes. Defaults to ``False``. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: A directed binomial tree with 2^n vertices and 2^n - 1 edges. +/// :returns: The generated directed heavy square graph /// :rtype: PyDiGraph -/// :raises IndexError: If the lenght of ``weights`` is greater that 2^n -/// :raises OverflowError: If the input order exceeds the maximum value for the -/// current platform. +/// :raises IndexError: If d is even. /// /// .. jupyter-execute:: /// /// import rustworkx.generators -/// from rustworkx.visualization import mpl_draw +/// from rustworkx.visualization import graphviz_draw /// -/// graph = rustworkx.generators.directed_binomial_tree_graph(4) -/// mpl_draw(graph) +/// graph = rustworkx.generators.directed_heavy_square_graph(3) +/// graphviz_draw(graph, lambda node: dict( +/// color='black', fillcolor='lightblue', style='filled')) /// #[pyfunction] #[pyo3( - signature=(order, weights=None, bidirectional=false, multigraph=true), - text_signature = "(order, /, weights=None, bidirectional=False, multigraph=True)" + signature=(d, bidirectional=false, multigraph=true), + text_signature = "(d, /, bidirectional=False, multigraph=True)" )] -pub fn directed_binomial_tree_graph( +pub fn directed_heavy_square_graph( py: Python, - order: u32, - weights: Option>, + d: usize, bidirectional: bool, multigraph: bool, ) -> PyResult { - if order >= MAX_ORDER { - return Err(PyOverflowError::new_err(format!( - "An order of {} exceeds the max allowable size", - order - ))); - } let default_fn = || py.None(); - let graph: StablePyGraph = match core_generators::binomial_tree_graph( - order, - weights, - default_fn, - default_fn, - bidirectional, - ) { - Ok(graph) => graph, - Err(_) => { - return Err(PyIndexError::new_err( - "order and weights list not specified", - )) - } - }; + let graph: StablePyGraph = + match core_generators::heavy_square_graph(d, default_fn, default_fn, bidirectional) { + Ok(graph) => graph, + Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), + }; Ok(digraph::PyDiGraph { graph, node_removed: false, @@ -746,103 +750,55 @@ pub fn directed_binomial_tree_graph( }) } -/// Creates a full r-ary tree of `n` nodes. -/// Sometimes called a k-ary, n-ary, or m-ary tree. -/// -/// :param int branching factor: The number of children at each node. -/// :param int num_nodes: The number of nodes in the graph. -/// :param list weights: A list of node weights. If the number of weights is -/// less than num_nodes, extra nodes with with None will be appended. The -/// number of weights cannot exceed num_nodes. -/// :param bool multigraph: When set to False the output -/// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead -/// calls which would create a parallel edge will update the existing edge. -/// -/// :returns: A r-ary tree. -/// :rtype: PyGraph -/// :raises IndexError: If the lenght of ``weights`` is greater that n -/// -/// .. jupyter-execute:: -/// -/// import rustworkx.generators -/// from rustworkx.visualization import mpl_draw +/// Generate an undirected heavy hex graph. /// -/// graph = rustworkx.generators.full_rary_tree(5, 15) -/// mpl_draw(graph) -/// -#[pyfunction] -#[pyo3( - signature=(branching_factor, num_nodes, weights=None, multigraph=true), - text_signature = "(branching_factor, num_nodes, /, weights=None, multigraph=True)" -)] -pub fn full_rary_tree( - py: Python, - branching_factor: usize, - num_nodes: usize, - weights: Option>, - multigraph: bool, -) -> PyResult { - let default_fn = || py.None(); - let graph: StablePyGraph = match core_generators::full_rary_tree_graph( - branching_factor, - num_nodes, - weights, - default_fn, - default_fn, - ) { - Ok(graph) => graph, - Err(_) => { - return Err(PyIndexError::new_err( - "The number of weights cannot exceed num_nodes.", - )) - } - }; - Ok(graph::PyGraph { - graph, - node_removed: false, - multigraph, - attrs: py.None(), - }) -} - -/// Generate an undirected heavy square graph. Fig. 6 of -/// https://arxiv.org/abs/1907.09528. +/// Fig. 2 of https://arxiv.org/abs/1907.09528 /// An ASCII diagram of the graph is given by: /// -/// .. code-block:: console -/// -/// ... S ... -/// \ / \ -/// ... D D D ... -/// | | | -/// ... F-S-F-S-F-... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F-S-F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// \ / \ -/// ... S ... +/// .. code-block:: text /// -/// NOTE: This function generates the four-frequency variant of the heavy square code. -/// This function implements Fig 10.b left of the `paper `_. -/// This function doesn't support the variant Fig 10.b right. +/// ... D-S-D D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ......... +/// | | | +/// ... D D D ... +/// | | | +/// ...-F F-S-F ... +/// | | | +/// ... D D D ... +/// | | | +/// ... F-S-F F-... +/// | | | +/// ... D D-S-D ... /// -/// Note that if ``d`` is set to ``1`` a :class:`~rustworkx.PyGraph` with a -/// single node will be returned. /// /// :param int d: distance of the code. If ``d`` is set to ``1`` a /// :class:`~rustworkx.PyGraph` with a single node will be returned. -/// :param bool multigraph: When set to False the output +/// ``d`` must be an odd number. +/// :param bidirectional: A parameter to indicate if edges should exist in +/// both directions between nodes. Defaults to ``False``. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: The generated heavy square graph +/// :returns: The generated heavy hex graph /// :rtype: PyGraph /// :raises IndexError: If d is even. /// @@ -851,7 +807,7 @@ pub fn full_rary_tree( /// import rustworkx.generators /// from rustworkx.visualization import graphviz_draw /// -/// graph = rustworkx.generators.heavy_square_graph(3) +/// graph = rustworkx.generators.heavy_hex_graph(3) /// graphviz_draw(graph, lambda node: dict( /// color='black', fillcolor='lightblue', style='filled')) /// @@ -860,10 +816,10 @@ pub fn full_rary_tree( signature=(d, multigraph=true), text_signature = "(d, /, multigraph=True)" )] -pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult { +pub fn heavy_hex_graph(py: Python, d: usize, multigraph: bool) -> PyResult { let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::heavy_square_graph(d, default_fn, default_fn, false) { + match core_generators::heavy_hex_graph(d, default_fn, default_fn, false) { Ok(graph) => graph, Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), }; @@ -875,40 +831,53 @@ pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult`_. -/// This function doesn't support the variant Fig 10.b right. /// /// :param int d: distance of the code. If ``d`` is set to ``1`` a /// :class:`~rustworkx.PyDiGraph` with a single node will be returned. -/// :param bool multigraph: When set to False the output +/// ``d`` must be an odd number. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: The generated directed heavy square graph +/// :returns: The generated heavy hex directed graph /// :rtype: PyDiGraph /// :raises IndexError: If d is even. /// @@ -917,7 +886,7 @@ pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult PyResult PyResult { let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::heavy_square_graph(d, default_fn, default_fn, bidirectional) { + match core_generators::heavy_hex_graph(d, default_fn, default_fn, bidirectional) { Ok(graph) => graph, Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), }; @@ -948,74 +917,65 @@ pub fn directed_heavy_square_graph( }) } -/// Generate an undirected heavy hex graph. Fig. 2 of -/// https://arxiv.org/abs/1907.09528 -/// An ASCII diagram of the graph is given by: -/// -/// .. code-block:: text -/// -/// ... D-S-D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ......... -/// | | | -/// ... D D D ... -/// | | | -/// ...-F F-S-F ... -/// | | | -/// ... D D D ... -/// | | | -/// ... F-S-F F-... -/// | | | -/// ... D D-S-D ... -/// +// MAX_ORDER is determined based on the pointer width of the target platform +#[cfg(target_pointer_width = "64")] +const MAX_ORDER: u32 = 60; +#[cfg(not(target_pointer_width = "64"))] +const MAX_ORDER: u32 = 29; + +/// Generate an undirected binomial tree of order n recursively. /// -/// :param int d: distance of the code. If ``d`` is set to ``1`` a -/// :class:`~rustworkx.PyGraph` with a single node will be returned. -/// :param bool multigraph: When set to False the output +/// :param int order: Order of the binomial tree. The maximum allowed value +/// for order on the platform your running on. If it's a 64bit platform +/// the max value is 60 and on 32bit systems the max value is 29. Any order +/// value above these will raise an ``OverflowError``. +/// :param list weights: A list of node weights. If the number of weights is +/// less than 2**order, extra nodes with None will be appended. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead -/// calls which would create a parallel edge will update the existing edge. +/// won't allow parallel edges to be added. Instead calls which would +/// create a parallel edge will update the existing edge. /// -/// :returns: The generated heavy hex graph +/// :returns: A binomial tree with 2^n vertices and 2^n - 1 edges. /// :rtype: PyGraph -/// :raises IndexError: If d is even. +/// :raises IndexError: If the length of ``weights`` is greater that 2^n +/// :raises OverflowError: If the input order exceeds the maximum value for the +/// current platform. /// /// .. jupyter-execute:: /// /// import rustworkx.generators -/// from rustworkx.visualization import graphviz_draw +/// from rustworkx.visualization import mpl_draw /// -/// graph = rustworkx.generators.heavy_hex_graph(3) -/// graphviz_draw(graph, lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) +/// graph = rustworkx.generators.binomial_tree_graph(4) +/// mpl_draw(graph) /// #[pyfunction] #[pyo3( - signature=(d, multigraph=true), - text_signature = "(d, /, multigraph=True)" + signature=(order, weights=None, multigraph=true), + text_signature = "(order, /, weights=None, multigraph=True)" )] -pub fn heavy_hex_graph(py: Python, d: usize, multigraph: bool) -> PyResult { +pub fn binomial_tree_graph( + py: Python, + order: u32, + weights: Option>, + multigraph: bool, +) -> PyResult { + if order >= MAX_ORDER { + return Err(PyOverflowError::new_err(format!( + "An order of {} exceeds the max allowable size", + order + ))); + } let default_fn = || py.None(); let graph: StablePyGraph = - match core_generators::heavy_hex_graph(d, default_fn, default_fn, false) { + match core_generators::binomial_tree_graph(order, weights, default_fn, default_fn, false) { Ok(graph) => graph, - Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), + Err(_) => { + return Err(PyIndexError::new_err( + "num_nodes and weights list not specified", + )) + } }; Ok(graph::PyGraph { graph, @@ -1025,85 +985,136 @@ pub fn heavy_hex_graph(py: Python, d: usize, multigraph: bool) -> PyResult>, + bidirectional: bool, + multigraph: bool, +) -> PyResult { + if order >= MAX_ORDER { + return Err(PyOverflowError::new_err(format!( + "An order of {} exceeds the max allowable size", + order + ))); + } + let default_fn = || py.None(); + let graph: StablePyGraph = match core_generators::binomial_tree_graph( + order, + weights, + default_fn, + default_fn, + bidirectional, + ) { + Ok(graph) => graph, + Err(_) => { + return Err(PyIndexError::new_err( + "order and weights list not specified", + )) + } + }; + Ok(digraph::PyDiGraph { + graph, + node_removed: false, + check_cycle: false, + cycle_state: algo::DfsSpace::default(), + multigraph, + attrs: py.None(), + }) +} + +/// Creates a full r-ary tree of `n` nodes. /// +/// Sometimes called a k-ary, n-ary, or m-ary tree. /// -/// :param int d: distance of the code. If ``d`` is set to ``1`` a -/// :class:`~rustworkx.PyDiGraph` with a single node will be returned. -/// :param bool multigraph: When set to False the output +/// :param int branching factor: The number of children at each node. +/// :param int num_nodes: The number of nodes in the graph. +/// :param list weights: A list of node weights. If the number of weights is +/// less than ``num_nodes``, extra nodes with None will be appended. The +/// number of weights cannot exceed num_nodes. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// -/// :returns: The generated heavy hex directed graph -/// :rtype: PyDiGraph -/// :raises IndexError: If d is even. +/// :returns: A r-ary tree. +/// :rtype: PyGraph +/// :raises IndexError: If the lenght of ``weights`` is greater that n /// /// .. jupyter-execute:: /// /// import rustworkx.generators -/// from rustworkx.visualization import graphviz_draw +/// from rustworkx.visualization import mpl_draw /// -/// graph = rustworkx.generators.directed_heavy_hex_graph(3) -/// graphviz_draw(graph, lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) +/// graph = rustworkx.generators.full_rary_tree(5, 15) +/// mpl_draw(graph) /// #[pyfunction] #[pyo3( - signature=(d, bidirectional=false, multigraph=true), - text_signature = "(d, /, bidirectional=False, multigraph=True)" + signature=(branching_factor, num_nodes, weights=None, multigraph=true), + text_signature = "(branching_factor, num_nodes, /, weights=None, multigraph=True)" )] -pub fn directed_heavy_hex_graph( +pub fn full_rary_tree( py: Python, - d: usize, - bidirectional: bool, + branching_factor: usize, + num_nodes: usize, + weights: Option>, multigraph: bool, -) -> PyResult { +) -> PyResult { let default_fn = || py.None(); - let graph: StablePyGraph = - match core_generators::heavy_hex_graph(d, default_fn, default_fn, bidirectional) { - Ok(graph) => graph, - Err(_) => return Err(PyIndexError::new_err("d must be an odd number.")), - }; - Ok(digraph::PyDiGraph { + let graph: StablePyGraph = match core_generators::full_rary_tree_graph( + branching_factor, + num_nodes, + weights, + default_fn, + default_fn, + ) { + Ok(graph) => graph, + Err(_) => { + return Err(PyIndexError::new_err( + "The number of weights cannot exceed num_nodes.", + )) + } + }; + Ok(graph::PyGraph { graph, node_removed: false, - check_cycle: false, - cycle_state: algo::DfsSpace::default(), multigraph, attrs: py.None(), }) @@ -1113,9 +1124,9 @@ pub fn directed_heavy_hex_graph( /// /// :param int rows: The number of rows to generate the graph with. /// :param int cols: The number of columns to generate the graph with. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// /// :returns: The generated hexagonal lattice graph. @@ -1157,14 +1168,15 @@ pub fn hexagonal_lattice_graph( }) } -/// Generate a directed hexagonal lattice graph. The edges propagate towards -/// right and bottom direction if ``bidirectional`` is ``false`` +/// Generate a directed hexagonal lattice graph. +/// +/// The edges propagate towards right and bottom direction if ``bidirectional`` is ``False`` /// /// :param int rows: The number of rows to generate the graph with. /// :param int cols: The number of rows to generate the graph with. /// :param bidirectional: A parameter to indicate if edges should exist in -/// both directions between nodes -/// :param bool multigraph: When set to False the output +/// both directions between nodes. Defaults to ``False``. +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -1216,12 +1228,12 @@ pub fn directed_hexagonal_lattice_graph( }) } -/// Generate an undirected lollipop graph where a mesh graph is connected to a +/// Generate an undirected lollipop graph where a mesh (complete) graph is connected to a /// path. /// /// If neither ``num_path_nodes`` nor ``path_weights`` (both described /// below) are specified then this is equivalent to -/// :func:`~rustworkx.generators.mesh_graph` +/// :func:`~rustworkx.generators.complete_graph` /// /// :param int num_mesh_nodes: The number of nodes to generate the mesh graph /// with. Node weights will be None if this is specified. If both @@ -1237,9 +1249,9 @@ pub fn directed_hexagonal_lattice_graph( /// :param list path_weights: A list of node weights for the path. If both /// ``num_path_nodes`` and ``path_weights`` are set ``num_path_nodes`` will /// be ignored and ``path_weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// /// :returns: The generated lollipop graph @@ -1291,6 +1303,79 @@ pub fn lollipop_graph( }) } +/// Generate an undirected barbell graph where two identical complete graphs are +/// connected by a path. +/// +/// If ``num_path_nodes`` (described below) is not specified then this is +/// equivalent to two complete graphs joined together. +/// +/// :param int num_mesh_nodes: The number of nodes to generate the mesh graphs +/// with. Node weights will be None if this is specified. If both +/// ``num_mesh_nodes`` and ``mesh_weights`` are set this will be ignored and +/// ``mesh_weights`` will be used. +/// :param int num_path_nodes: The number of nodes to generate the path +/// with. Node weights will be None if this is specified. If both +/// ``num_path_nodes`` and ``path_weights`` are set this will be ignored and +/// ``path_weights`` will be used. +/// :param bool multigraph: When set to ``False`` the output +/// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and +/// won't allow parallel edges to be added. Instead +/// calls which would create a parallel edge will update the existing edge. +/// :param list mesh_weights: A list of node weights for the mesh graph. If both +/// ``num_mesh_nodes`` and ``mesh_weights`` are set ``num_mesh_nodes`` will +/// be ignored and ``mesh_weights`` will be used. +/// :param list path_weights: A list of node weights for the path. If both +/// ``num_path_nodes`` and ``path_weights`` are set ``num_path_nodes`` will +/// be ignored and ``path_weights`` will be used. +/// +/// :returns: The generated barbell graph +/// :rtype: PyGraph +/// :raises IndexError: If ``num_mesh_nodes`` is not specified +/// +/// .. jupyter-execute:: +/// +/// import rustworkx.generators +/// from rustworkx.visualization import mpl_draw +/// +/// graph = rustworkx.generators.barbell_graph(4, 2) +/// mpl_draw(graph) +/// +#[pyfunction] +#[pyo3( + signature=(num_mesh_nodes=None, num_path_nodes=None, multigraph=true, mesh_weights=None, path_weights=None) +)] +pub fn barbell_graph( + py: Python, + num_mesh_nodes: Option, + num_path_nodes: Option, + multigraph: bool, + mesh_weights: Option>, + path_weights: Option>, +) -> PyResult { + let default_fn = || py.None(); + let graph: StablePyGraph = match core_generators::barbell_graph( + num_mesh_nodes, + num_path_nodes, + mesh_weights, + path_weights, + default_fn, + default_fn, + ) { + Ok(graph) => graph, + Err(_) => { + return Err(PyIndexError::new_err( + "num_nodes and weights list not specified", + )) + } + }; + Ok(graph::PyGraph { + graph, + node_removed: false, + multigraph, + attrs: py.None(), + }) +} + /// Generate a generalized Petersen graph :math:`G(n, k)` with :math:`2n` /// nodes and :math:`3n` edges. See Watkins [1]_ for more details. /// @@ -1300,7 +1385,7 @@ pub fn lollipop_graph( /// /// :param int n: number of nodes in the internal star and external regular polygon. /// :param int k: shift that changes the internal star graph. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -1366,79 +1451,6 @@ pub fn generalized_petersen_graph( }) } -/// Generate an undirected barbell graph where two identical mesh graphs are -/// connected by a path. -/// -/// If ``num_path_nodes`` (described below) is not specified then this is -/// equivalent to two mesh graphs joined together. -/// -/// :param int num_mesh_nodes: The number of nodes to generate the mesh graphs -/// with. Node weights will be None if this is specified. If both -/// ``num_mesh_nodes`` and ``mesh_weights`` are set this will be ignored and -/// ``mesh_weights`` will be used. -/// :param int num_path_nodes: The number of nodes to generate the path -/// with. Node weights will be None if this is specified. If both -/// ``num_path_nodes`` and ``path_weights`` are set this will be ignored and -/// ``path_weights`` will be used. -/// :param bool multigraph: When set to False the output -/// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead -/// calls which would create a parallel edge will update the existing edge. -/// :param list mesh_weights: A list of node weights for the mesh graph. If both -/// ``num_mesh_nodes`` and ``mesh_weights`` are set ``num_mesh_nodes`` will -/// be ignored and ``mesh_weights`` will be used. -/// :param list path_weights: A list of node weights for the path. If both -/// ``num_path_nodes`` and ``path_weights`` are set ``num_path_nodes`` will -/// be ignored and ``path_weights`` will be used. -/// -/// :returns: The generated barbell graph -/// :rtype: PyGraph -/// :raises IndexError: If ``num_mesh_nodes`` is not specified -/// -/// .. jupyter-execute:: -/// -/// import rustworkx.generators -/// from rustworkx.visualization import mpl_draw -/// -/// graph = rustworkx.generators.barbell_graph(4, 2) -/// mpl_draw(graph) -/// -#[pyfunction] -#[pyo3( - signature=(num_mesh_nodes=None, num_path_nodes=None, multigraph=true, mesh_weights=None, path_weights=None) -)] -pub fn barbell_graph( - py: Python, - num_mesh_nodes: Option, - num_path_nodes: Option, - multigraph: bool, - mesh_weights: Option>, - path_weights: Option>, -) -> PyResult { - let default_fn = || py.None(); - let graph: StablePyGraph = match core_generators::barbell_graph( - num_mesh_nodes, - num_path_nodes, - mesh_weights, - path_weights, - default_fn, - default_fn, - ) { - Ok(graph) => graph, - Err(_) => { - return Err(PyIndexError::new_err( - "num_nodes and weights list not specified", - )) - } - }; - Ok(graph::PyGraph { - graph, - node_removed: false, - multigraph, - attrs: py.None(), - }) -} - /// Generate an undirected empty graph with ``n`` nodes and no edges. /// /// :param int n: The number of nodes to generate the graph with. @@ -1519,14 +1531,14 @@ pub fn directed_empty_graph( /// ``{0, 1, ..., n-1}`` and the set of edges ``{(i, j) : i < j, 0 <= i < n, 0 <= j < n}``. /// The number of edges in the complete graph is ``n*(n-1)/2``. /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param list weights: A list of node weights. If both ``num_node`` and +/// :param list weights: A list of node weights. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyGraph` object will not be not be a multigraph and -/// won't allow parallel edges to be added. Instead +/// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. /// /// :returns: The generated complete graph @@ -1578,12 +1590,12 @@ pub fn complete_graph( /// ``{0, 1, ..., n-1}`` and the set of edges ``{(i, j) : 0 <= i < n, 0 <= j < n}``. /// The number of edges in the directed complete graph is ``n*(n-1)``. /// -/// :param int num_node: The number of nodes to generate the graph with. Node -/// weights will be None if this is specified. If both ``num_node`` and +/// :param int num_nodes: The number of nodes to generate the graph with. Node +/// weights will be None if this is specified. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param list weights: A list of node weights. If both ``num_node`` and +/// :param list weights: A list of node weights. If both ``num_nodes`` and /// ``weights`` are set this will be ignored and ``weights`` will be used. -/// :param bool multigraph: When set to False the output +/// :param bool multigraph: When set to ``False`` the output /// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and /// won't allow parallel edges to be added. Instead /// calls which would create a parallel edge will update the existing edge. @@ -1649,12 +1661,12 @@ pub fn generators(_py: Python, m: &PyModule) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(directed_heavy_hex_graph))?; m.add_wrapped(wrap_pyfunction!(binomial_tree_graph))?; m.add_wrapped(wrap_pyfunction!(directed_binomial_tree_graph))?; + m.add_wrapped(wrap_pyfunction!(full_rary_tree))?; m.add_wrapped(wrap_pyfunction!(hexagonal_lattice_graph))?; m.add_wrapped(wrap_pyfunction!(directed_hexagonal_lattice_graph))?; m.add_wrapped(wrap_pyfunction!(lollipop_graph))?; - m.add_wrapped(wrap_pyfunction!(full_rary_tree))?; - m.add_wrapped(wrap_pyfunction!(generalized_petersen_graph))?; m.add_wrapped(wrap_pyfunction!(barbell_graph))?; + m.add_wrapped(wrap_pyfunction!(generalized_petersen_graph))?; m.add_wrapped(wrap_pyfunction!(empty_graph))?; m.add_wrapped(wrap_pyfunction!(directed_empty_graph))?; m.add_wrapped(wrap_pyfunction!(complete_graph))?; diff --git a/src/steiner_tree.rs b/src/steiner_tree.rs index 018d5bbbf..4c3fde3ff 100644 --- a/src/steiner_tree.rs +++ b/src/steiner_tree.rs @@ -23,13 +23,13 @@ use petgraph::stable_graph::{EdgeIndex, EdgeReference, NodeIndex}; use petgraph::unionfind::UnionFind; use petgraph::visit::{EdgeRef, IntoEdgeReferences, NodeIndexable}; -use crate::generators::pairwise; use crate::graph; use crate::is_valid_weight; use crate::shortest_path::all_pairs_dijkstra::all_pairs_dijkstra_shortest_paths; use rustworkx_core::dictmap::*; use rustworkx_core::shortest_path::dijkstra; +use rustworkx_core::utils::pairwise; struct MetricClosureEdge { source: usize,