Advertisement
Cinestra

Incomplete Restructuring for A* Algorithm

Aug 4th, 2023
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.62 KB | None | 0 0
  1. #include "MyMap.h"
  2. #include "Provided.h"
  3. #include "Support.h"
  4.  
  5. #include <string>
  6. #include <vector>
  7. #include <queue>
  8. #include <list>
  9. #include <iostream>
  10. #include <algorithm>
  11.  
  12. using namespace std;
  13.  
  14. struct Node {
  15. GeoCoord coord;
  16. double g_cost; // Distance from starting point
  17. double h_cost; // Distance from end point
  18. double f_cost; // Total cost (g_cost + h_cost)
  19. string name;
  20.  
  21. // Reverse operators because we want to be ordered with min distance at the top
  22. bool operator <(const Node& other) const
  23. {
  24. return f_cost > other.f_cost;
  25. }
  26. };
  27.  
  28. class NavigatorImpl {
  29. public:
  30. NavigatorImpl();
  31. ~NavigatorImpl();
  32. bool load_map_data(string map_file);
  33. NavResult navigate(string start, string end, vector<NavSegment>& directions) const;
  34. private:
  35. MapLoader map_load_;
  36. AttractionMapper attr_map_;
  37. SegmentMapper seg_map_;
  38. string direction(double angle) const;
  39. };
  40.  
  41. string NavigatorImpl::direction(double angle) const
  42. {
  43. if (0 <= angle && angle <= 22.5) return "east";
  44. else if (22.5 <= angle && angle <= 67.5) return "northeast";
  45. else if (67.5 <= angle && angle <= 112.5) return "north";
  46. else if (112.5 <= angle && angle <= 157.5) return "northwest";
  47. else if (157.5 <= angle && angle <= 202.5) return "west";
  48. else if (202.5 <= angle && angle <= 247.5) return "southwest";
  49. else if (247.5 <= angle && angle <= 292.5) return "south";
  50. else return "east";
  51. }
  52.  
  53. NavigatorImpl::NavigatorImpl()
  54. {
  55.  
  56. }
  57.  
  58. NavigatorImpl::~NavigatorImpl()
  59. {
  60.  
  61. }
  62.  
  63. bool NavigatorImpl::load_map_data(string map_file)
  64. {
  65. // This statement actually checks to see if the map file is loaded already and if not it loads it
  66. if (!map_load_.load(map_file)) return false;
  67.  
  68. attr_map_.init(map_load_);
  69. seg_map_.init(map_load_);
  70. return true;
  71. }
  72.  
  73. NavResult NavigatorImpl::navigate(string start, string end, vector<NavSegment>& directions) const
  74. {
  75. if (start == end) return NAV_SUCCESS;
  76.  
  77. bool found = false;
  78. Node start_node, end_node;
  79.  
  80. // We are actually getting the geocoord of the start and storing it in start_point.coord
  81. // If the inputted start doesn't actually have corresponding start geocoord, return bad source
  82. if (!attr_map_.getGeoCoord(start, start_node.coord)) return NAV_BAD_SOURCE;
  83. if (!attr_map_.getGeoCoord(end, end_node.coord)) return NAV_BAD_DESTINATION;
  84.  
  85. start_node.g_cost = 0;
  86. start_node.h_cost = distanceEarthMiles(start_node.coord, end_node.coord);
  87. start_node.f_cost = start_node.g_cost + start_node.h_cost;
  88.  
  89. // In case the start or end is on an intersection
  90. vector<StreetSegment> segs_associated_with_start = seg_map_.getSegments(start_node.coord);
  91. vector<StreetSegment> segs_associated_with_end = seg_map_.getSegments(end_node.coord);
  92.  
  93. MyMap<GeoCoord, double> geocoord_and_f_cost; // Used for priority
  94. MyMap<GeoCoord, GeoCoord> came_from; // Keep track of path
  95. priority_queue<Node> prio_queue_of_node;
  96.  
  97. geocoord_and_f_cost.associate(start_node.coord, start_node.f_cost);
  98. came_from.associate(start_node.coord, start_node.coord);
  99. prio_queue_of_node.push(start_node);
  100.  
  101. while (!prio_queue_of_node.empty())
  102. {
  103. // The very first time we enter this while loop, we input the start_node
  104. // We initialized the start_point.coord earlier
  105. Node current_node = prio_queue_of_node.top();
  106. prio_queue_of_node.pop();
  107.  
  108. vector<StreetSegment> segs_associated_with_current = seg_map_.getSegments(current_node.coord);
  109. for (int i = 0; i < segs_associated_with_current.size(); i++) {
  110. for (int j = 0; j < segs_associated_with_end.size(); j++) {
  111. if (segs_associated_with_current[i] == segs_associated_with_end[j]) {
  112. found = true;
  113. came_from.associate(end_node.coord, current_node.coord);
  114. }
  115. }
  116. }
  117. if (found) break;
  118.  
  119. // If it is NOT found still, we will check neighboring segments on the Geocoord
  120. Node next_node;
  121. for (int k = 0; k < segs_associated_with_current.size(); k++) {
  122. const StreetSegment next_street_seg = segs_associated_with_current[k];
  123. const GeoSegment next_geo_seg = next_street_seg.segment;
  124.  
  125. // If our current node is at the start of a geoseg, we need to also explore its end
  126. // Likewise if the current node is at the end, we need to explore its start
  127. if (next_geo_seg.start == current_node.coord || next_geo_seg.end == current_node.coord) {
  128. if (next_geo_seg.start == current_node.coord) next_node.coord = next_geo_seg.end;
  129. else next_node.coord = next_geo_seg.start;
  130.  
  131. // Check if where it's coming from originally isn't the same as the next coord
  132. //if (came_from.find(current_coord) != nullptr && *(came_from.find(current_coord)) != next_coord) {
  133. if (*(came_from.find(current_node.coord)) != next_node.coord) {
  134. const double potential_g_cost = current_node.g_cost + distanceEarthMiles(current_node.coord, next_node.coord);
  135. const double potential_h_cost = distanceEarthMiles(next_node.coord, end_node.coord);
  136. const double potential_f_cost = potential_g_cost + potential_h_cost;
  137.  
  138. // We will see if a cost for the next coord already exists
  139. // If it doesn't, we will just associate it or if it has one but the new cost is smaller, we will update it
  140. if (geocoord_and_f_cost.find(next_node.coord) == nullptr || *(geocoord_and_f_cost.find(next_node.coord)) > potential_f_cost) {
  141. next_node.g_cost = potential_g_cost;
  142. next_node.h_cost = potential_h_cost;
  143. next_node.f_cost = potential_f_cost;
  144.  
  145. geocoord_and_f_cost.associate(next_node.coord, next_node.f_cost);
  146. prio_queue_of_node.push(next_node);
  147. came_from.associate(next_node.coord, current_node.coord);
  148. }
  149. }
  150. }
  151.  
  152. // If our current node is in the middle of a geosegment
  153. else {
  154. Node start_geo_seg, end_geo_seg;
  155. start_geo_seg.coord = next_geo_seg.start;
  156. end_geo_seg.coord = next_geo_seg.end;
  157.  
  158. const double potential_start_g_cost = current_node.g_cost + distanceEarthMiles(current_node.coord, start_geo_seg.coord);
  159. const double potential_start_h_cost = distanceEarthMiles(start_geo_seg.coord, end_node.coord);
  160. const double potential_start_f_cost = potential_start_g_cost + potential_start_f_cost;
  161. const double potential_end_g_cost = current_node.g_cost + distanceEarthMiles(current_node.coord, end_geo_seg.coord);
  162. const double potential_end_h_cost = distanceEarthMiles(end_geo_seg.coord, end_node.coord);
  163. const double potential_end_f_cost = potential_start_g_cost + potential_start_f_cost;
  164.  
  165. // if (geocoord_and_f_cost.find(start_geo_seg) == nullptr || *(geocoord_and_f_cost.find(next_node.coord)) > potential_f_cost) {
  166. if (geocoord_and_f_cost.find(start_geo_seg.coord) != nullptr || *(geocoord_and_f_cost.find(start_geo_seg.coord)) > potential_start_f_cost) {
  167.  
  168. }
  169. }
  170. }
  171. }
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement