graph_base/interfaces/
hypergraph.rs1use std::{collections::HashMap, fmt::Display};
2use crate::interfaces::graph::SingleId;
3use crate::interfaces::edge::Hyperedge;
4
5use super::{edge::DirectedHyperedge, vertex::Vertex};
6
7pub trait IdVector {
8 fn id(&self) -> Vec<usize>;
9}
10
11pub trait Hypergraph<'a> {
12 type Node: Vertex;
13 type Edge: Hyperedge;
14 fn new() -> Self;
15 fn nodes(&'a self) -> impl Iterator<Item = &'a Self::Node>;
16 fn hyperedges(&'a self) -> impl Iterator<Item = &'a Self::Edge>;
17 fn get_hyperedges_vector(&'a self) -> impl Iterator<Item = Vec<&'a Self::Node>> {
18 let id_map: HashMap<_, _> = HashMap::from_iter(self.nodes().map(|node| (node.id(), node)));
19 self.hyperedges().map(move |edge| edge.id().iter().map(|id| id_map.get(id).unwrap()).cloned().collect::<Vec<_>>()).collect::<Vec<_>>().into_iter()
20 }
21 fn get_hyperedges_vector_with_edge(&'a self) -> impl Iterator<Item = (&'a Self::Edge, Vec<&'a Self::Node>)> {
22 let id_map: HashMap<_, _> = HashMap::from_iter(self.nodes().map(|node| (node.id(), node)));
23 self.hyperedges().map(move |edge| (edge, edge.id().iter().map(|id| id_map.get(id).unwrap()).cloned().collect::<Vec<_>>())).collect::<Vec<_>>().into_iter()
24 }
25 fn add_node(&mut self, node: Self::Node);
26 fn add_hyperedge(&mut self, edge: Self::Edge);
27}
28
29
30pub struct AdjacencyList<'a, T: Hypergraph<'a>>(HashMap<&'a T::Node, Vec<&'a T::Node>>);
31
32impl<'a, T> Display for AdjacencyList<'a, T>
33where
34 T: Hypergraph<'a> {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 let mut s = String::new();
37 for (node, adj) in self.0.iter() {
38
39 let s1 = format!("{}", node);
40 let mut s2 = String::new();
41 for node in adj {
42 s2.push_str(format!("{}, ", node).as_str());
43 }
44
45 s.push_str(format!("Node {} -> {{{}}}\n", s1, s2).as_str());
46 }
47 write!(f, "{}", s)
48 }
49}
50
51pub trait DirectedHypergraph<'a>: Hypergraph<'a> + Sized
52where
53 Self::Edge: DirectedHyperedge {}
54
55pub trait Neighbor<'a>: Hypergraph<'a> + Sized {
56 fn get_neighbors(&'a self) -> AdjacencyList<'a, Self> {
57 let mut adj = HashMap::new();
58 for node in self.nodes() {
59 adj.insert(node, Vec::new());
60 }
61 for edge in self.hyperedges() {
62 let nodes = edge.id();
63 for i in 0..nodes.len() {
64 for j in (i + 1)..nodes.len() {
65 let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
66 let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
67 adj.get_mut(node1).unwrap().push(node2);
68 adj.get_mut(node2).unwrap().push(node1);
69 }
70 }
71 }
72 AdjacencyList(adj)
73 }
74
75 fn neighbors(&'a self, adj: &AdjacencyList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Node> {
76 adj.0.get(node).unwrap().iter().cloned()
77 }
78}
79
80pub trait Precursor<'a>: DirectedHypergraph<'a>
81where
82 Self::Edge: DirectedHyperedge, {
83 fn get_precursor(&'a self) -> AdjacencyList<'a, Self> {
84 let mut adj = HashMap::new();
85 for node in self.nodes() {
86 adj.insert(node, Vec::new());
87 }
88 for edge in self.hyperedges() {
89 let nodes = edge.id();
90 for i in 0..nodes.len() {
91 for j in (i + 1)..nodes.len() {
92 let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
93 let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
94 adj.get_mut(node2).unwrap().push(node1);
95 }
96 }
97 }
98 AdjacencyList(adj)
99 }
100}
101
102pub trait Successor<'a>: DirectedHypergraph<'a>
103where
104 Self::Edge: DirectedHyperedge, {
105 fn get_postcursor(&'a self) -> AdjacencyList<'a, Self> {
106 let mut adj = HashMap::new();
107 for node in self.nodes() {
108 adj.insert(node, Vec::new());
109 }
110 for edge in self.hyperedges() {
111 let nodes = edge.id();
112 for i in 0..nodes.len() {
113 for j in (i + 1)..nodes.len() {
114 let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
115 let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
116 adj.get_mut(node1).unwrap().push(node2);
117 }
118 }
119 }
120 AdjacencyList(adj)
121 }
122}
123
124pub struct HyperedgeList<'a, T: Hypergraph<'a>>(HashMap<&'a T::Node, Vec<&'a T::Edge>>);
125
126impl<'a, T> Display for HyperedgeList<'a, T>
127where
128 T: Hypergraph<'a> {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 let mut s = String::new();
131 for (node, edges) in self.0.iter() {
132
133 let s1 = format!("{}", node);
134 let mut s2 = String::new();
135 for edge in edges {
136 }
138
139 s.push_str(format!("Node {} -> {{{}}}\n", s1, s2).as_str());
140 }
141 write!(f, "{}", s)
142 }
143}
144
145pub trait ContainedHyperedge<'a>: Hypergraph<'a> + Sized {
146 fn get_hyperedges_list(&'a self) -> HyperedgeList<'a, Self> {
147 let mut adj = HashMap::new();
148 for node in self.nodes() {
149 adj.insert(node, Vec::new());
150 }
151 for edge in self.hyperedges() {
152 let nodes = edge.id();
153 for i in 0..nodes.len() {
154 let node = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
155 adj.get_mut(node).unwrap().push(edge);
156 }
157 }
158 HyperedgeList(adj)
159 }
160
161 fn contained_hyperedges(&'a self, adj: &HyperedgeList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Edge> {
162 adj.0.get(node).unwrap().iter().cloned()
163 }
164}
165pub trait ContainedDirectedHyperedge<'a>: DirectedHypergraph<'a> + Sized
166where
167 Self::Edge: DirectedHyperedge {
168 fn contained_hyperedges(&'a self, adj: &HyperedgeList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Edge> {
169 adj.0.get(node).unwrap().iter().cloned()
170 }
171
172 fn get_hyperedges_src(&'a self) -> HyperedgeList<'a, Self> {
173 let mut adj = HashMap::new();
174 for node in self.nodes() {
175 adj.insert(node, Vec::new());
176 }
177 for edge in self.hyperedges() {
178 for id in edge.src() {
179 let node = self.nodes().find(|node| node.id() == id).unwrap();
180 adj.get_mut(node).unwrap().push(edge);
181 }
182 }
183 HyperedgeList(adj)
184 }
185 fn get_hyperedges_dst(&'a self) -> HyperedgeList<'a, Self> {
186 let mut adj = HashMap::new();
187 for node in self.nodes() {
188 adj.insert(node, Vec::new());
189 }
190 for edge in self.hyperedges() {
191 for id in edge.dst() {
192 let node = self.nodes().find(|node| node.id() == id).unwrap();
193 adj.get_mut(node).unwrap().push(edge);
194 }
195 }
196 HyperedgeList(adj)
197 }
198
199}