dijkstra.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // Created by zx on 22-11-29.
  3. //
  4. #include "dijkstra.h"
  5. #include <math.h>
  6. EdgeNode::EdgeNode(int key, float weight){
  7. this->key = key;
  8. this->weight = weight;
  9. this->next = NULL;
  10. }
  11. Graph::Graph(bool directed){
  12. this->directed = directed;
  13. for(int i = 1; i < (MAXV + 1); i ++){
  14. this->edges[i] = NULL;
  15. }
  16. }
  17. Graph::~Graph(){
  18. //to do
  19. }
  20. void Graph::insert_edge(int x, int y, float weight, bool directed){
  21. if(x > 0 && x < (MAXV + 1) && y > 0 && y < (MAXV + 1)){
  22. EdgeNode *edge = new EdgeNode(y, weight);
  23. edge->next = this->edges[x];
  24. this->edges[x] = edge;
  25. if(!directed){
  26. insert_edge(y, x, weight, true);
  27. }
  28. }
  29. }
  30. void Graph::print(){
  31. for(int v = 1; v < (MAXV + 1); v ++){
  32. if(this->edges[v] != NULL){
  33. std::cout << "Vertex " << v << " has neighbors: " << std::endl;
  34. EdgeNode *curr = this->edges[v];
  35. while(curr != NULL){
  36. std::cout << curr->key << std::endl;
  37. curr = curr->next;
  38. }
  39. }
  40. }
  41. }
  42. void init_vars(bool discovered[], float distance[], int parent[]){
  43. for(int i = 1; i < (MAXV + 1); i ++){
  44. discovered[i] = false;
  45. distance[i] = std::numeric_limits<float>::max();
  46. parent[i] = -1;
  47. }
  48. }
  49. void dijkstra_shortest_path(Graph *g, int parent[], float distance[], int start){
  50. bool discovered[MAXV + 1];
  51. EdgeNode *curr;
  52. int v_curr;
  53. int v_neighbor;
  54. float weight;
  55. float smallest_dist;
  56. init_vars(discovered, distance, parent);
  57. distance[start] = 0;
  58. v_curr = start;
  59. while(discovered[v_curr] == false){
  60. discovered[v_curr] = true;
  61. curr = g->edges[v_curr];
  62. while(curr != NULL){
  63. v_neighbor = curr->key;
  64. weight = curr->weight;
  65. if((distance[v_curr] + weight) < distance[v_neighbor]){
  66. distance[v_neighbor] = distance[v_curr] + weight;
  67. parent[v_neighbor] = v_curr;
  68. }
  69. curr = curr->next;
  70. }
  71. //set the next current vertex to the vertex with the smallest distance
  72. smallest_dist = std::numeric_limits<float>::max();
  73. for(int i = 1; i < (MAXV + 1); i ++){
  74. if(!discovered[i] && (distance[i] < smallest_dist)){
  75. v_curr = i;
  76. smallest_dist = distance[i];
  77. }
  78. }
  79. }
  80. }
  81. void get_shortest_path(int v, int parent[],std::vector<int>& path){
  82. if(v > 0 && v < (MAXV + 1) && parent[v] != -1){
  83. path.push_back( parent[v]) ;
  84. get_shortest_path(parent[v], parent,path);
  85. }
  86. }
  87. void print_distances(int start, float distance[]){
  88. for(int i = 1; i < (MAXV + 1); i ++){
  89. if(distance[i] != std::numeric_limits<float>::max()){
  90. std::cout << "Shortest distance from " << start << " to " << i << " is: " << distance[i] << std::endl;
  91. }
  92. }
  93. }
  94. PathMap::PathMap(){
  95. grapher_ = new Graph(false);
  96. }
  97. PathMap::~PathMap()
  98. {
  99. delete grapher_;
  100. }
  101. void PathMap::AddVertex(int id,float x,float y)
  102. {
  103. node_[id]={x,y};
  104. printf(" Add node %f,%f nodes :%d\n",x,y,node_.size());
  105. }
  106. bool PathMap::AddEdge(int id1,int id2,bool directed)
  107. {
  108. if(node_.find(id1)!=node_.end() && node_.find(id2)!=node_.end())
  109. {
  110. float x1=node_[id1].x;
  111. float y1=node_[id1].y;
  112. float x2=node_[id2].x;
  113. float y2=node_[id2].y;
  114. float distance=sqrt(pow(x2-x1,2)+pow(y2-y1,2))+EXP;
  115. grapher_->insert_edge(id1, id2, distance, directed);
  116. edge_.push_back({id1,id2,directed});
  117. printf(" Add edge %d-%d \n",id1,id2);
  118. return true;
  119. }
  120. return false;
  121. }
  122. bool PathMap::GetShortestPath(int id1,int id2,std::vector<int>& path,float& shortest_distance)
  123. {
  124. if(id1==id2)
  125. return false;
  126. if(node_.find(id1)!=node_.end() && node_.find(id2)!=node_.end())
  127. {
  128. dijkstra_shortest_path(grapher_, parent_, distance_, id1);
  129. get_shortest_path(id2, parent_, path);
  130. shortest_distance=distance_[id2];
  131. return true;
  132. }
  133. return false;
  134. }
  135. bool PathMap::GetVertexPos(int id,float& x,float& y)
  136. {
  137. if(node_.find(id)!=node_.end())
  138. {
  139. x=node_[id].x;
  140. y=node_[id].y;
  141. return true;
  142. }
  143. return false;
  144. }