Crate hypergraph[−][src]
Expand description
Hypergraph is data structure library to generate directed hypergraphs.
A hypergraph is a generalization of a graph in which a hyperedge can join any number of vertices.
Features
This library enables you to:
- represent non-simple hypergraphs with two or more hyperedges - with different weights - containing the exact same set of vertices
- represent self-loops - i.e., hyperedges containing vertices directed to themselves one or more times
- represent unaries - i.e., hyperedges containing a unique vertex
Additional features:
- Safe Rust implementation
- Proper error handling
- Stable indexes assigned for each hyperedge and each vertex
Example
Please notice that the hyperedges and the vertices must implement the HyperedgeTrait and the VertexTrait respectively.
use hypergraph::{HyperedgeIndex, Hypergraph, VertexIndex};
use std::fmt::{Display, Formatter, Result};
// Create a new struct to represent a vertex.
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub struct Vertex<'a> {
name: &'a str,
}
impl<'a> Vertex<'a> {
pub fn new(name: &'a str) -> Self {
Vertex { name }
}
}
impl<'a> Display for Vertex<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self)
}
}
// Create a new struct to represent a hyperedge.
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub struct Hyperedge<'a> {
cost: usize,
name: &'a str,
}
impl<'a> Hyperedge<'a> {
pub fn new(name: &'a str, cost: usize) -> Self {
Hyperedge { cost, name }
}
}
impl<'a> Display for Hyperedge<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self)
}
}
impl<'a> Into<usize> for Hyperedge<'a> {
fn into(self) -> usize {
self.cost
}
}
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let mut graph = Hypergraph::<Vertex, Hyperedge>::new();
// Add some vertices to the graph.
let ava = graph.add_vertex(Vertex::new("Ava"))?;
let bianca = graph.add_vertex(Vertex::new("Bianca"))?;
let charles = graph.add_vertex(Vertex::new("Charles"))?;
let daena = graph.add_vertex(Vertex::new("Daena"))?;
let ewan = graph.add_vertex(Vertex::new("Ewan"))?;
let faarooq = graph.add_vertex(Vertex::new("Faarooq"))?;
let ghanda = graph.add_vertex(Vertex::new("Ghanda"))?;
// Each vertex gets a unique index by insertion order.
assert_eq!(ava, VertexIndex(0));
assert_eq!(ghanda, VertexIndex(6));
// Get the weight of a vertex.
assert_eq!(graph.get_vertex_weight(VertexIndex(0)), Ok(Vertex::new("Ava")));
// The hypergraph has 7 vertices.
assert_eq!(graph.count_vertices(), 7);
// Add some hyperedges to the graph.
let first_hyperedge = graph.add_hyperedge(vec![faarooq, ava, ghanda], Hyperedge::new("share a viral video with a cat", 1))?;
let second_hyperedge = graph.add_hyperedge(vec![faarooq, ava, ghanda], Hyperedge::new("share a viral video with a dog", 1))?;
let third_hyperedge = graph.add_hyperedge(vec![ewan, ava, bianca], Hyperedge::new("share a viral video with a beaver", 1))?;
let fourth_hyperedge = graph.add_hyperedge(vec![daena], Hyperedge::new("play online", 1))?;
let fifth_hyperedge = graph.add_hyperedge(vec![ewan, charles, bianca, bianca, ewan], Hyperedge::new("pass the ball", 1))?;
// Each hyperedge gets a unique index by insertion order.
assert_eq!(first_hyperedge, HyperedgeIndex(0));
assert_eq!(fifth_hyperedge, HyperedgeIndex(4));
// Get the weight of a hyperedge.
assert_eq!(graph.get_hyperedge_weight(HyperedgeIndex(0)), Ok(Hyperedge::new("share a viral video with a cat", 1)));
// Get the vertices of a hyperedge.
assert_eq!(graph.get_hyperedge_vertices(HyperedgeIndex(0)), Ok(vec![faarooq, ava, ghanda]));
// The hypergraph has 5 hyperedges.
assert_eq!(graph.count_hyperedges(), 5);
// Get the hypergedges of a vertex.
assert_eq!(graph.get_vertex_hyperedges(VertexIndex(0)), Ok(vec![first_hyperedge, second_hyperedge, third_hyperedge]));
assert_eq!(graph.get_full_vertex_hyperedges(VertexIndex(0)), Ok(vec![vec![faarooq, ava, ghanda], vec![faarooq, ava, ghanda], vec![ewan, ava, bianca]]));
// Get the intersection of some hyperedges.
assert_eq!(graph.get_hyperedges_intersections(vec![second_hyperedge, third_hyperedge]), Ok(vec![ava]));
// Find a hyperedge containing a connection between two vertices.
assert_eq!(graph.get_hyperedges_connecting(bianca, bianca), Ok(vec![fifth_hyperedge]));
// Get the adjacent vertices from a vertex.
assert_eq!(graph.get_adjacent_vertices_from(VertexIndex(0)), Ok(vec![bianca, ghanda]));
// Get the adjacent vertices to a vertex.
assert_eq!(graph.get_adjacent_vertices_to(VertexIndex(0)), Ok(vec![ewan, faarooq]));
// Find the shortest paths between some vertices.
assert_eq!(graph.get_dijkstra_connections(faarooq, bianca), Ok(vec![(faarooq, None), (ava, Some(first_hyperedge)), (bianca, Some(third_hyperedge))]));
// Update the weight of a vertex.
graph.update_vertex_weight(ava, Vertex::new("Avā"))?;
// Update the weight of a hyperedge.
graph.update_hyperedge_weight(third_hyperedge, Hyperedge::new("share a viral video with a capybara", 1))?;
// Update the vertices of a hyperedge.
graph.update_hyperedge_vertices(third_hyperedge, vec![ewan, ava, daena])?;
// Remove a hyperedge.
graph.remove_hyperedge(first_hyperedge)?;
// Remove a vertex.
graph.remove_vertex(ewan)?;
// Reverse a hyperedge.
graph.reverse_hyperedge(fifth_hyperedge)?;
// Get the in-degree of a vertex.
assert_eq!(graph.get_vertex_degree_in(ava), Ok(1));
// Get the out-degree of a vertex.
assert_eq!(graph.get_vertex_degree_out(ghanda), Ok(0));
// Contract a hyperedge's vertices.
graph.contract_hyperedge_vertices(fifth_hyperedge, vec![bianca, charles], bianca)?;
// Clear the hyperedges.
graph.clear_hyperedges()?;
// Clear the whole hypergraph.
graph.clear();
Ok(())
}
Modules
Public API.
Structs
Hyperedge stable index representation as usize.
A HyperedgeKey is a representation of both the vertices and the weight of a hyperedge, used as a key in the hyperedges set. In a non-simple hypergraph, since the same vertices can be shared by different hyperedges, the weight is also included in the key to keep it unique.
A directed hypergraph composed of generic vertices and hyperedges.
Vertex stable index representation as usize. Uses the newtype index pattern. https://matklad.github.io/2018/06/04/newtype-index-pattern.html
Traits
Shared Trait for the hyperedges. Must be implemented to use the library.
Shared Trait for the vertices. Must be implemented to use the library.