1use std::cell::RefCell;
2use std::fs::File;
3use std::io::Write;
4use std::rc::Rc;
5use std::vec::Vec;
6
7use crate::rugraph::IGraph;
8use crate::rugraph::IMultiDiGraph;
9
10pub struct MultiDiGraph<T, E>
15where
16 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
17 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
18{
19 nodes: RefCell<Vec<Rc<MultiNode<T, E>>>>,
21}
22
23struct MultiNode<T, E>
25where
26 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
27 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
28{
29 elem: T,
30 neighbors: RefCell<Vec<Rc<Edge<T, E>>>>,
31}
32
33struct Edge<T, E>
34where
35 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
36 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
37{
38 node: Rc<MultiNode<T, E>>,
39 edge: E,
40}
41
42impl<T, E> MultiNode<T, E>
43where
44 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
45 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
46{
47 pub fn new(elem: T) -> Self {
48 MultiNode::<T, E> {
49 elem: elem,
50 neighbors: RefCell::new(Vec::new()),
51 }
52 }
53}
54
55impl<T, E> MultiDiGraph<T, E>
56where
57 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
58 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
59{
60 pub fn new() -> Self {
61 MultiDiGraph::<T, E> {
62 nodes: RefCell::new(vec![]),
63 }
64 }
65
66 fn get_index_by_node_id(&self, from: T) -> Result<usize, &'static str> {
67 let nodes = self.nodes.borrow();
68 let idx_from = nodes.iter().position(|r| r.elem == from);
69 match idx_from {
70 None => Err("Element not found"),
71 Some(value) => Ok(value),
72 }
73 }
74
75 fn dfs(
76 &self,
77 previous_from: T,
78 from: T,
79 to: T,
80 dst: T,
81 edge: E,
82 simple_path: &mut Vec<Vec<(T, T, E)>>,
83 current_path: &mut Vec<(T, T, E)>,
84 visited: &mut Vec<T>,
85 ) {
86 if visited.contains(&previous_from.clone()) {
87 return;
88 }
89 visited.push(previous_from.clone());
90 current_path.push((previous_from.clone(), dst.clone(), edge.clone()));
91 if from == to {
92 simple_path.push(current_path.clone());
93 if visited.contains(&previous_from.clone()) {
94 let index = visited
95 .iter()
96 .position(|x| x.clone() == previous_from.clone())
97 .unwrap();
98 visited.remove(index);
99 current_path.pop();
100 return;
101 }
102 }
103
104 let neighbors = self.get_neighbors(dst.clone());
105 for n in neighbors.iter() {
106 self.dfs(
107 dst.clone(),
108 n.0.clone(),
109 to.clone(),
110 n.0.clone(),
111 n.1.clone(),
112 simple_path,
113 current_path,
114 visited,
115 );
116 }
117
118 current_path.pop();
119 if visited.contains(&previous_from.clone()) {
120 let index = visited
121 .iter()
122 .position(|x| x.clone() == previous_from.clone())
123 .unwrap();
124 visited.remove(index);
125 }
126 }
127}
128
129impl<T, E> Drop for MultiDiGraph<T, E>
130where
131 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
132 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
133{
134 fn drop(&mut self) {
135 self.nodes.borrow_mut().clear();
136 }
137}
138
139impl<T, E> IGraph<T> for MultiDiGraph<T, E>
140where
141 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
142 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
143{
144 fn add_node(&mut self, elem: T) {
146 if self.node_exists(elem.clone()) {
147 return;
148 }
149
150 let mut nodes = self.nodes.borrow_mut();
151 let n = Rc::new(MultiNode::<T, E>::new(elem));
152
153 nodes.push(n);
154 }
155
156 fn node_exists(&self, from: T) -> bool {
157 let nodes = self.nodes.borrow();
158 let idx_from = nodes.iter().position(|r| r.elem == from);
159 match idx_from {
160 None => {
161 return false;
162 }
163 Some(_value) => {
164 return true;
165 }
166 }
167 }
168
169 fn is_directly_connected(&self, from: T, to: T) -> bool {
171 let nodes = self.nodes.borrow();
172 let ret_idx_from = self.get_index_by_node_id(from.clone());
173 let idx_from;
174 match ret_idx_from {
175 Ok(v) => idx_from = v,
176 Err(e) => {
177 println!("Error {}", e);
178 return false;
179 }
180 };
181
182 let ret_idx_to = self.get_index_by_node_id(to.clone());
183 let idx_to;
184 match ret_idx_to {
185 Ok(v) => idx_to = v,
186 Err(e) => {
187 println!("Error {}", e);
188 return false;
189 }
190 };
191
192 let n = &nodes[idx_from];
193 let m = nodes[idx_to].clone();
194 for e in n.neighbors.borrow().iter() {
195 if Rc::ptr_eq(&e.node, &m) {
196 return true;
198 }
199 }
200 return false;
202 }
203
204 fn is_connected(&self, from: T, to: T) -> bool {
206 let mut seen = Vec::<(T, E)>::new();
208 let mut to_process = Vec::<(T, E)>::new();
209
210 let neighbors = self.get_neighbors(from.clone());
211 for n in neighbors.iter() {
212 to_process.push(n.clone());
213 }
214 let mut end = false;
217 while !end {
218 let node = to_process.pop().unwrap().clone();
219 let node_id = node.0;
220
221 let neighbors = self.get_neighbors(node_id.clone());
222 let contains = neighbors.iter().any(|r| r.0 == to.clone());
224 if contains {
227 return true;
228 } else {
229 for n in neighbors.iter() {
230 if !seen.contains(n) {
231 to_process.push(n.clone());
232 seen.push(n.clone());
233 }
234 }
235 }
236
237 end = to_process.is_empty();
238 }
239
240 return false;
241 }
242
243 fn to_dot_file(&self, file: &mut File, graph_name: &str) {
247 let s = self.to_dot_string(graph_name);
248 file.write_all(s.as_bytes()).expect("Error writing file!");
249 }
250
251 fn to_dot_string(&self, graph_name: &str) -> String {
253 let mut s = String::from("digraph ") + graph_name + &String::from("{\n");
254 let nodes = self.nodes.borrow();
255 for n in nodes.iter() {
256 for m in n.neighbors.borrow().iter() {
257 s = s + &n.elem.to_string();
258 s = s
259 + &String::from(" -> ")
260 + &m.node.elem.to_string()
261 + &String::from(" [label=\"")
262 + &m.edge.to_string()
263 + &String::from("\"];\n");
264 }
265 }
266 s = s + &String::from("}\n");
267 return s;
268 }
269
270 fn is_empty(&self) -> bool {
271 return self.nodes.borrow().is_empty();
272 }
273
274 fn count_nodes(&self) -> usize {
275 return self.nodes.borrow().len();
276 }
277 fn get_nodes(&self) -> Vec<T> {
278 let mut ret = Vec::<T>::new();
279 for n in self.nodes.borrow().iter() {
280 ret.push(n.elem.clone());
281 }
282 return ret;
283 }
284}
285
286pub fn multidigraph_from_dot_string(
288 content: &String,
289) -> Result<MultiDiGraph<String, String>, &'static str> {
290 let mut graph = MultiDiGraph::<String, String>::new();
291 let idx1: usize;
292 let idx2: usize;
293 match content.chars().position(|c| c == '{') {
294 None => {
295 return Err("Dot file not correct. { not found.");
296 }
297 Some(i) => {
298 idx1 = i + 1;
299 }
300 }
301
302 match content.chars().position(|c| c == '}') {
303 None => {
304 return Err("Dot file not correct. } not found.");
305 }
306 Some(i) => {
307 idx2 = i - 1;
308 }
309 }
310
311 if idx2 < idx1 {
312 return Err("Dot file not correct. } before {");
313 }
314
315 let c = &content[idx1..idx2];
316 let v_c: Vec<&str> = c.split(';').collect();
318
319 for line in v_c.iter() {
320 if line.is_empty() {
321 continue;
322 }
323 let idx3 = match line.chars().position(|c| c == '[') {
326 None => {
327 return Err("Dot file not correct. [ not found.");
328 }
329 Some(i) => i - 1,
330 };
331
332 let l_nodes = line[0..idx3].trim();
333
334 let v_nodes: Vec<&str> = l_nodes.split("->").collect();
335
336 let n_from;
337 let n_to;
338 if v_nodes.len() == 2 {
339 n_from = v_nodes[0].trim().to_string();
340 n_to = v_nodes[1].trim().to_string();
341 graph.add_node(n_from.clone());
342 graph.add_node(n_to.clone());
343 } else {
344 return Err("Dot file not correct.");
345 }
346
347 let label = line[idx3..]
348 .replace("[label=\"", "")
349 .replace("\"]", "")
350 .trim()
351 .to_string();
352 graph.add_edge(n_from, n_to, label.to_string())
354 }
355
356 Ok(graph)
357}
358
359impl<T, E> IMultiDiGraph<T, E> for MultiDiGraph<T, E>
360where
361 T: Ord + Clone + std::fmt::Display + std::fmt::Debug,
362 E: Ord + Clone + std::fmt::Display + std::fmt::Debug,
363{
364 fn add_edge(&mut self, from: T, to: T, edge: E) {
367 if !self.node_exists(from.clone())
368 || !self.node_exists(to.clone())
369 || self.is_directly_connected_by(from.clone(), to.clone(), edge.clone())
370 {
371 return;
372 }
373
374 let nodes = self.nodes.borrow_mut();
375
376 let idx_from = nodes.iter().position(|r| r.elem == from).unwrap();
377 let idx_to = nodes.iter().position(|r| r.elem == to).unwrap();
378
379 let n = &nodes[idx_from];
380 let m = nodes[idx_to].clone();
381
382 n.neighbors.borrow_mut().push(Rc::new(Edge {
383 node: m.clone(),
384 edge: edge,
385 }));
386 }
387
388 fn is_directly_connected_by(&self, from: T, to: T, edge: E) -> bool {
390 let nodes = self.nodes.borrow();
391 let ret_idx_from = self.get_index_by_node_id(from.clone());
392 let idx_from;
393 match ret_idx_from {
394 Ok(v) => idx_from = v,
395 Err(e) => {
396 println!("Error {}", e);
397 return false;
398 }
399 };
400
401 let ret_idx_to = self.get_index_by_node_id(to.clone());
402 let idx_to;
403 match ret_idx_to {
404 Ok(v) => idx_to = v,
405 Err(e) => {
406 println!("Error {}", e);
407 return false;
408 }
409 };
410
411 let n = &nodes[idx_from];
412 let m = nodes[idx_to].clone();
413 for e in n.neighbors.borrow().iter() {
414 if Rc::ptr_eq(&e.node, &m) && (e.edge == edge) {
415 return true;
417 }
418 }
419 return false;
421 }
422
423 fn all_simple_paths(&self, from: T, to: T) -> Vec<Vec<(T, T, E)>> {
426 let mut ret = Vec::<Vec<(T, T, E)>>::new();
427 let mut current_path = Vec::<(T, T, E)>::new();
428 let mut visited = Vec::<T>::new();
429 let neighbors = self.get_neighbors(from.clone());
430 if neighbors.len() == 0 {
431 return ret;
432 }
433 for n in neighbors.iter() {
434 self.dfs(
435 from.clone(),
436 n.0.clone(),
437 to.clone(),
438 n.0.clone(),
439 n.1.clone(),
440 &mut ret,
441 &mut current_path,
442 &mut visited,
443 );
444 }
445 return ret;
446 }
447
448 fn get_neighbors(&self, from: T) -> Vec<(T, E)> {
449 let mut neighbors = Vec::<(T, E)>::new();
450
451 if !self.node_exists(from.clone()) {
452 return neighbors;
453 }
454
455 let nodes = self.nodes.borrow();
456
457 let idx_from = nodes.iter().position(|r| r.elem == from).unwrap();
458
459 let n = &nodes[idx_from];
460
461 for e in n.neighbors.borrow().iter() {
463 neighbors.push((e.node.elem.clone(), e.edge.clone()));
464 }
465
466 return neighbors;
467 }
468}
469
470#[cfg(test)]
471mod tests {
472 use super::MultiDiGraph;
473 use crate::multidigraph::multidigraph_from_dot_string;
474 use crate::multidigraph::File;
475 use crate::rugraph::IGraph;
476 use crate::rugraph::IMultiDiGraph;
477
478 #[test]
479 fn multidigraph_test1() {
480 let mut graph = MultiDiGraph::<i32, i32>::new();
481 graph.add_node(1);
482
483 let exists = graph.node_exists(1);
484 assert_eq!(exists, true);
485 let exists = graph.node_exists(99);
486 assert_eq!(exists, false);
487
488 graph.add_node(2);
489 graph.add_node(3);
490 graph.add_node(4);
491 graph.add_node(5);
492 graph.add_node(6);
493 graph.add_node(7);
494 graph.add_edge(1, 2, 0);
495 graph.add_edge(1, 2, 1);
496 graph.add_edge(2, 3, 0);
497 graph.add_edge(2, 4, 0);
498 graph.add_edge(2, 5, 1);
499 graph.add_edge(5, 7, 0);
500
501 let ret = graph.is_directly_connected(1, 2);
502 assert_eq!(ret, true);
503
504 let ret = graph.is_directly_connected(1, 3);
505 assert_eq!(ret, false);
506
507 let s = graph.get_neighbors(2);
508 assert_eq!(s, [(3, 0), (4, 0), (5, 1)]);
509
510 let ret = graph.is_connected(1, 7);
511 assert_eq!(ret, true);
512
513 let ret = graph.is_connected(1, 6);
514 assert_eq!(ret, false);
515 }
516
517 #[test]
518 fn multidigraph_generics() {
519 let mut graph = MultiDiGraph::<String, String>::new();
520 graph.add_node("a".to_string());
521 graph.add_node("b".to_string());
522 graph.add_node("c".to_string());
523 graph.add_node("d".to_string());
524 graph.add_edge("a".to_string(), "b".to_string(), "ab".to_string());
525 graph.add_edge("b".to_string(), "c".to_string(), "bc".to_string());
526 graph.add_edge("c".to_string(), "d".to_string(), "cd".to_string());
527 graph.add_edge("a".to_string(), "d".to_string(), "ad".to_string());
528
529 println!("From a to d");
530 let paths = graph.all_simple_paths("a".to_string(), "d".to_string());
531 println!("{:?}", paths);
532 assert_eq!(
534 paths,
535 vec![
536 vec![
537 ("a".to_string(), "b".to_string(), "ab".to_string()),
538 ("b".to_string(), "c".to_string(), "bc".to_string()),
539 ("c".to_string(), "d".to_string(), "cd".to_string())
540 ],
541 vec![("a".to_string(), "d".to_string(), "ad".to_string())]
542 ]
543 );
544
545 let s = graph.to_dot_string(&String::from("to_dot_multidigraph_test"));
546 println!("Dot:\n{}", s);
547 assert_eq!(s.is_empty(), false);
548 }
549
550 #[test]
551 fn multidigraph_from_dot_str() {
552 let content =
553 String::from("digraph multidigraph_from_dot_str{\na -> b [label=\"ab\"];\na -> d [label=\"ad\"];\nb -> c [label=\"bc\"];\nc -> d [label=\"cd\"];\n}");
554
555 let graph = match multidigraph_from_dot_string(&content) {
556 Ok(v) => v,
557 Err(e) => {
558 println!("Error {}", e);
559 MultiDiGraph::<String, String>::new()
560 }
561 };
562
563 assert_eq!(graph.count_nodes(), 4);
564 let s = graph.to_dot_string(&String::from("multidigraph_from_dot_str"));
565 println!("{}", s);
566 }
568
569 #[test]
570 fn all_paths() {
571 let mut graph = MultiDiGraph::<String, String>::new();
572 graph.add_node("a".to_string());
573 graph.add_node("b".to_string());
574 graph.add_node("c".to_string());
575 graph.add_node("d".to_string());
576 graph.add_node("e".to_string());
577 graph.add_node("f".to_string());
578
579 graph.add_edge("a".to_string(), "b".to_string(), "ab0".to_string());
580 graph.add_edge("a".to_string(), "b".to_string(), "ab1".to_string());
581 graph.add_edge("b".to_string(), "c".to_string(), "bc0".to_string());
582 graph.add_edge("b".to_string(), "c".to_string(), "bc1".to_string());
583 graph.add_edge("c".to_string(), "d".to_string(), "cd".to_string());
584 graph.add_edge("d".to_string(), "e".to_string(), "de".to_string());
585 graph.add_edge("d".to_string(), "a".to_string(), "da".to_string());
586 graph.add_edge("c".to_string(), "e".to_string(), "ce".to_string());
587 graph.add_edge("e".to_string(), "f".to_string(), "ef".to_string());
588 graph.add_edge("a".to_string(), "d".to_string(), "ad".to_string());
589
590 println!("From a to d");
591 let paths = graph.all_simple_paths("a".to_string(), "f".to_string());
592 println!("Len {} {:?}", paths.len(), paths);
593
594 assert_eq!(
595 paths,
596 vec![
597 vec![
598 ("a".to_string(), "b".to_string(), "ab0".to_string()),
599 ("b".to_string(), "c".to_string(), "bc0".to_string()),
600 ("c".to_string(), "d".to_string(), "cd".to_string()),
601 ("d".to_string(), "e".to_string(), "de".to_string()),
602 ("e".to_string(), "f".to_string(), "ef".to_string())
603 ],
604 vec![
605 ("a".to_string(), "b".to_string(), "ab0".to_string()),
606 ("b".to_string(), "c".to_string(), "bc0".to_string()),
607 ("c".to_string(), "e".to_string(), "ce".to_string()),
608 ("e".to_string(), "f".to_string(), "ef".to_string())
609 ],
610 vec![
611 ("a".to_string(), "b".to_string(), "ab0".to_string()),
612 ("b".to_string(), "c".to_string(), "bc1".to_string()),
613 ("c".to_string(), "d".to_string(), "cd".to_string()),
614 ("d".to_string(), "e".to_string(), "de".to_string()),
615 ("e".to_string(), "f".to_string(), "ef".to_string())
616 ],
617 vec![
618 ("a".to_string(), "b".to_string(), "ab0".to_string()),
619 ("b".to_string(), "c".to_string(), "bc1".to_string()),
620 ("c".to_string(), "e".to_string(), "ce".to_string()),
621 ("e".to_string(), "f".to_string(), "ef".to_string())
622 ],
623 vec![
624 ("a".to_string(), "b".to_string(), "ab1".to_string()),
625 ("b".to_string(), "c".to_string(), "bc0".to_string()),
626 ("c".to_string(), "d".to_string(), "cd".to_string()),
627 ("d".to_string(), "e".to_string(), "de".to_string()),
628 ("e".to_string(), "f".to_string(), "ef".to_string())
629 ],
630 vec![
631 ("a".to_string(), "b".to_string(), "ab1".to_string()),
632 ("b".to_string(), "c".to_string(), "bc0".to_string()),
633 ("c".to_string(), "e".to_string(), "ce".to_string()),
634 ("e".to_string(), "f".to_string(), "ef".to_string())
635 ],
636 vec![
637 ("a".to_string(), "b".to_string(), "ab1".to_string()),
638 ("b".to_string(), "c".to_string(), "bc1".to_string()),
639 ("c".to_string(), "d".to_string(), "cd".to_string()),
640 ("d".to_string(), "e".to_string(), "de".to_string()),
641 ("e".to_string(), "f".to_string(), "ef".to_string())
642 ],
643 vec![
644 ("a".to_string(), "b".to_string(), "ab1".to_string()),
645 ("b".to_string(), "c".to_string(), "bc1".to_string()),
646 ("c".to_string(), "e".to_string(), "ce".to_string()),
647 ("e".to_string(), "f".to_string(), "ef".to_string())
648 ],
649 vec![
650 ("a".to_string(), "d".to_string(), "ad".to_string()),
651 ("d".to_string(), "e".to_string(), "de".to_string()),
652 ("e".to_string(), "f".to_string(), "ef".to_string())
653 ]
654 ]
655 );
656
657 println!("-----");
754 for p in paths {
755 println!("{:?}", p)
756 }
757
758 let s = graph.to_dot_string(&String::from("to_dot_multidigraph_test"));
759 println!("Dot:\n{}", s);
760 assert_eq!(s.is_empty(), false);
761 let mut fd = File::create("test_multidirected.dot").expect("error creating file");
762 graph.to_dot_file(&mut fd, &String::from("paths_test"));
763 }
764}