diff --git a/README.md b/README.md index cd7d030..7a67540 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,69 @@ the data subgraph must also exist in the query graph.  +# Usage + +Create your query and data graphs with [petgraph](https://github.com/petgraph/petgraph) +or any library that implements the `Graph` trait. Then, call one of the following +functions based on the problem type. + +| Problem type | Call | +|-------------------------------|---------------------------------| +| Graph isomorphisms | `isomorphisms` | +| Subgraph isomorphisms | `subgraph_isomorphisms` | +| Induced subgraph isomorphisms | `induced_subgraph_isomorphisms` | + +These return a `Vf2Builder` with the algorithm configured. +Next, call one of the following on the builder to enumerate the isomorphisms. + +| Desired output | Call | +|--------------------------|---------| +| First isomorphism | `first` | +| Vector of isomorphisms | `vec` | +| Iterator of isomorphisms | `iter` | + +Filling a vector can consume a significant amount of memory. +Use the iterator to inspect isomorphisms as they are found. +For the best performance, call `next_ref` +on the iterator +instead of `next` +to avoid cloning each isomorphism. + +You can configure the node and edge equality functions on the builder +with `node_eq` and `edge_eq`, +respectively. + +# Example + +This example shows how to find subgraph isomorphisms. + +```rust +use petgraph::data::{Element, FromElements}; +use petgraph::graph::DiGraph; + +fn main() { + // Create query graph. + let query = DiGraph::<i32, ()>::from_elements([ + Element::Node { weight: 0 }, + Element::Node { weight: 1 }, + Element::Edge { source: 0, target: 1, weight: () }, + ]); + + // Create data graph. + let data = DiGraph::<i32, ()>::from_elements([ + Element::Node { weight: 0 }, + Element::Node { weight: 1 }, + Element::Node { weight: 2 }, + Element::Edge { source: 0, target: 1, weight: () }, + Element::Edge { source: 1, target: 2, weight: () }, + ]); + + // Find subgraph isomorphisms. + let isomorphisms = vf2::subgraph_isomorphisms(&query, &data).vec(); + assert_eq!(isomorphisms, vec![vec![0, 1], vec![1, 2]]); +} +``` + # Remaining work - [ ] Implement VF2 cutting rules diff --git a/src/lib.rs b/src/lib.rs index 77c9756..24b58e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,24 +7,34 @@ //! //! See the [repository](https://github.com/OwenTrokeBillard/vf2) for more information. //! -//! # Instructions +//! # Usage //! //! Create your query and data graphs with [petgraph](https://github.com/petgraph/petgraph) //! or any library that implements the [`Graph`] trait. Then, call one of the following -//! functions based on the problem type: -//! - Graph isomorphisms: [`isomorphisms`]. -//! - Subgraph isomorphisms: [`subgraph_isomorphisms`]. -//! - Induced subgraph isomorphisms: [`induced_subgraph_isomorphisms`]. +//! functions based on the problem type. //! +//! | Problem type | Call | +//! |-------------------------------|-----------------------------------| +//! | Graph isomorphisms | [`isomorphisms`] | +//! | Subgraph isomorphisms | [`subgraph_isomorphisms`] | +//! | Induced subgraph isomorphisms | [`induced_subgraph_isomorphisms`] | +//! +//! \ //! These return a [`Vf2Builder`] with the algorithm configured. -//! Next, call one of the following to enumerate the isomorphisms: -//! - First isomorphism: [`first`](Vf2Builder::first). -//! - Vector of isomorphisms: [`vec`](Vf2Builder::vec). -//! - Iterator of isomorphisms: [`iter`](Vf2Builder::iter). +//! Next, call one of the following on the builder to enumerate the isomorphisms. //! +//! | Desired output | Call | +//! |--------------------------|------------------------------| +//! | First isomorphism | [`first`](Vf2Builder::first) | +//! | Vector of isomorphisms | [`vec`](Vf2Builder::vec) | +//! | Iterator of isomorphisms | [`iter`](Vf2Builder::iter) | +//! +//! \ //! Filling a vector can consume a significant amount of memory. //! Use the iterator to inspect isomorphisms as they are found. -//! For even better performance, call [`next_ref`](IsomorphismIter::next_ref) +//! For the best performance, call [`next_ref`](IsomorphismIter::next_ref) +//! on the iterator +//! instead of [`next`](IsomorphismIter::next) //! to avoid cloning each isomorphism. //! //! You can configure the node and edge equality functions on the builder