深度优先搜索

  1. use std::collections::HashSet;
  2. use std::collections::VecDeque;
  3. // Perform a Depth First Search Algorithm to find a element in a graph
  4. //
  5. // Return a Optional with a vector with history of vertex visiteds
  6. // or a None if the element not exists on the graph
  7. pub fn depth_first_search(graph: &Graph, root: Vertex, objective: Vertex) -> Option<Vec<u32>> {
  8. let mut visited: HashSet<Vertex> = HashSet::new();
  9. let mut history: Vec<u32> = Vec::new();
  10. let mut queue = VecDeque::new();
  11. queue.push_back(root);
  12. // While there is an element in the queue
  13. // get the first element of the vertex queue
  14. while let Some(current_vertex) = queue.pop_front() {
  15. // Added current vertex in the history of visiteds vertex
  16. history.push(current_vertex.value());
  17. // Verify if this vertex is the objective
  18. if current_vertex == objective {
  19. // Return the Optional with the history of visiteds vertex
  20. return Some(history);
  21. }
  22. // For each over the neighbors of current vertex
  23. for neighbor in current_vertex.neighbors(graph).into_iter().rev() {
  24. // Insert in the HashSet of visiteds if this value not exist yet
  25. if visited.insert(neighbor) {
  26. // Add the neighbor on front of queue
  27. queue.push_front(neighbor);
  28. }
  29. }
  30. }
  31. // If all vertex is visited and the objective is not found
  32. // return a Optional with None value
  33. None
  34. }
  35. // Data Structures
  36. #[derive(Copy, Clone, PartialEq, Eq, Hash)]
  37. pub struct Vertex(u32);
  38. #[derive(Copy, Clone, PartialEq, Eq, Hash)]
  39. pub struct Edge(u32, u32);
  40. #[derive(Clone)]
  41. pub struct Graph {
  42. vertices: Vec<Vertex>,
  43. edges: Vec<Edge>,
  44. }
  45. impl Graph {
  46. pub fn new(vertices: Vec<Vertex>, edges: Vec<Edge>) -> Self {
  47. Graph { vertices, edges }
  48. }
  49. }
  50. impl From<u32> for Vertex {
  51. fn from(item: u32) -> Self {
  52. Vertex(item)
  53. }
  54. }
  55. impl Vertex {
  56. pub fn value(&self) -> u32 {
  57. self.0
  58. }
  59. pub fn neighbors(&self, graph: &Graph) -> VecDeque<Vertex> {
  60. graph
  61. .edges
  62. .iter()
  63. .filter(|e| e.0 == self.0)
  64. .map(|e| e.1.into())
  65. .collect()
  66. }
  67. }
  68. impl From<(u32, u32)> for Edge {
  69. fn from(item: (u32, u32)) -> Self {
  70. Edge(item.0, item.1)
  71. }
  72. }
  73. #[cfg(test)]
  74. mod tests {
  75. use super::*;
  76. #[test]
  77. fn find_1_fail() {
  78. let vertices = vec![1, 2, 3, 4, 5, 6, 7];
  79. let edges = vec![(1, 2), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)];
  80. let root = 1;
  81. let objective = 99;
  82. let graph = Graph::new(
  83. vertices.into_iter().map(|v| v.into()).collect(),
  84. edges.into_iter().map(|e| e.into()).collect(),
  85. );
  86. assert_eq!(
  87. depth_first_search(&graph, root.into(), objective.into()),
  88. None
  89. );
  90. }
  91. #[test]
  92. fn find_1_sucess() {
  93. let vertices = vec![1, 2, 3, 4, 5, 6, 7];
  94. let edges = vec![(1, 2), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)];
  95. let root = 1;
  96. let objective = 7;
  97. let correct_path = vec![1, 2, 4, 5, 3, 6, 7];
  98. let graph = Graph::new(
  99. vertices.into_iter().map(|v| v.into()).collect(),
  100. edges.into_iter().map(|e| e.into()).collect(),
  101. );
  102. assert_eq!(
  103. depth_first_search(&graph, root.into(), objective.into()),
  104. Some(correct_path)
  105. );
  106. }
  107. #[test]
  108. fn find_2_sucess() {
  109. let vertices = vec![0, 1, 2, 3, 4, 5, 6, 7];
  110. let edges = vec![
  111. (0, 1),
  112. (1, 3),
  113. (3, 2),
  114. (2, 1),
  115. (3, 4),
  116. (4, 5),
  117. (5, 7),
  118. (7, 6),
  119. (6, 4),
  120. ];
  121. let root = 0;
  122. let objective = 6;
  123. let correct_path = vec![0, 1, 3, 2, 4, 5, 7, 6];
  124. let graph = Graph::new(
  125. vertices.into_iter().map(|v| v.into()).collect(),
  126. edges.into_iter().map(|e| e.into()).collect(),
  127. );
  128. assert_eq!(
  129. depth_first_search(&graph, root.into(), objective.into()),
  130. Some(correct_path)
  131. );
  132. }
  133. #[test]
  134. fn find_3_sucess() {
  135. let vertices = vec![0, 1, 2, 3, 4, 5, 6, 7];
  136. let edges = vec![
  137. (0, 1),
  138. (1, 3),
  139. (3, 2),
  140. (2, 1),
  141. (3, 4),
  142. (4, 5),
  143. (5, 7),
  144. (7, 6),
  145. (6, 4),
  146. ];
  147. let root = 0;
  148. let objective = 4;
  149. let correct_path = vec![0, 1, 3, 2, 4];
  150. let graph = Graph::new(
  151. vertices.into_iter().map(|v| v.into()).collect(),
  152. edges.into_iter().map(|e| e.into()).collect(),
  153. );
  154. assert_eq!(
  155. depth_first_search(&graph, root.into(), objective.into()),
  156. Some(correct_path)
  157. );
  158. }
  159. }