pub(crate) mod bi_hash_map;
#[doc(hidden)]
pub mod errors;
#[doc(hidden)]
pub mod hyperedges;
mod indexes;
#[doc(hidden)]
pub mod iterator;
mod shared;
#[doc(hidden)]
mod types;
mod utils;
#[doc(hidden)]
pub mod vertices;
use std::{
fmt::{
Debug,
Display,
Formatter,
Result,
},
hash::Hash,
ops::Deref,
};
use bi_hash_map::BiHashMap;
use types::{
AIndexSet,
ARandomState,
};
pub use crate::core::indexes::{
HyperedgeIndex,
VertexIndex,
};
pub use crate::core::iterator::{
HypergraphBorrowingIterator,
HypergraphIterator,
};
pub trait VertexTrait: Copy + Debug + Display + Eq + Hash + Send + Sync {}
impl<T> VertexTrait for T where T: Copy + Debug + Display + Eq + Hash + Send + Sync {}
pub trait HyperedgeTrait: VertexTrait + Into<usize> {}
impl<T> HyperedgeTrait for T where T: VertexTrait + Into<usize> {}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct HyperedgeKey<HE> {
vertices: Vec<usize>,
weight: HE,
}
impl<HE> HyperedgeKey<HE> {
pub(crate) fn new(vertices: Vec<usize>, weight: HE) -> HyperedgeKey<HE> {
Self { vertices, weight }
}
}
impl<HE> Deref for HyperedgeKey<HE> {
type Target = HE;
fn deref(&self) -> &HE {
&self.weight
}
}
#[derive(Clone)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound(
serialize = "V: serde::Serialize, HE: serde::Serialize",
deserialize = "V: serde::Deserialize<'de>, HE: serde::Deserialize<'de> + Eq + std::hash::Hash"
))
)]
pub struct Hypergraph<V, HE> {
vertices: Vec<(V, AIndexSet<usize>)>,
hyperedges: AIndexSet<HyperedgeKey<HE>>,
hyperedges_mapping: BiHashMap<HyperedgeIndex>,
vertices_mapping: BiHashMap<VertexIndex>,
hyperedges_count: usize,
vertices_count: usize,
}
impl<V, HE> Debug for Hypergraph<V, HE>
where
V: Debug,
HE: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_struct("Hypergraph")
.field("vertices", &self.vertices)
.field("hyperedges", &self.hyperedges)
.finish_non_exhaustive()
}
}
impl<V, HE> Display for Hypergraph<V, HE>
where
V: VertexTrait,
HE: HyperedgeTrait,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
let mut vertices: Vec<(VertexIndex, &V)> = self.vertices_iter().collect();
vertices.sort_by_key(|(idx, _)| *idx);
write!(f, "Hypergraph {{ vertices: [")?;
for (i, (idx, weight)) in vertices.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}: {}", idx.0, weight)?;
}
write!(f, "], hyperedges: [")?;
let mut hyperedges: Vec<(HyperedgeIndex, &HE)> = self.hyperedges_iter().collect();
hyperedges.sort_by_key(|(idx, _)| *idx);
for (i, (idx, weight)) in hyperedges.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}: {} [", idx.0, weight)?;
if let Ok(vertex_indexes) = self.get_hyperedge_vertices(*idx) {
for (j, v_idx) in vertex_indexes.iter().enumerate() {
if j > 0 {
write!(f, " → ")?;
}
if let Ok(v_weight) = self.get_vertex_weight(*v_idx) {
write!(f, "{v_weight}")?;
}
}
}
write!(f, "]")?;
}
write!(f, "] }}")
}
}
impl<V, HE> Default for Hypergraph<V, HE>
where
V: VertexTrait,
HE: HyperedgeTrait,
{
fn default() -> Self {
Hypergraph::new()
}
}
impl<V, HE> Hypergraph<V, HE>
where
V: VertexTrait,
HE: HyperedgeTrait,
{
#[must_use]
pub fn is_empty(&self) -> bool {
self.vertices.is_empty()
}
pub fn clear(&mut self) {
self.hyperedges.clear();
self.vertices.clear();
self.hyperedges_mapping = BiHashMap::default();
self.vertices_mapping = BiHashMap::default();
self.hyperedges_count = 0;
self.vertices_count = 0;
}
#[must_use]
pub fn new() -> Self {
Hypergraph::with_capacity(0, 0)
}
#[must_use]
pub fn with_capacity(vertices: usize, hyperedges: usize) -> Self {
Hypergraph {
hyperedges_count: 0,
hyperedges_mapping: BiHashMap::default(),
hyperedges: AIndexSet::with_capacity_and_hasher(hyperedges, ARandomState::default()),
vertices_count: 0,
vertices_mapping: BiHashMap::default(),
vertices: Vec::with_capacity(vertices),
}
}
}