// // Created by zx on 22-11-29. // #include "dijkstra.h" #include EdgeNode::EdgeNode(int key, float weight){ this->key = key; this->weight = weight; this->next = NULL; } Graph::Graph(bool directed){ this->directed = directed; for(int i = 1; i < (MAXV + 1); i ++){ this->edges[i] = NULL; } } Graph::~Graph(){ //to do } void Graph::insert_edge(int x, int y, float weight, bool directed){ if(x > 0 && x < (MAXV + 1) && y > 0 && y < (MAXV + 1)){ EdgeNode *edge = new EdgeNode(y, weight); edge->next = this->edges[x]; this->edges[x] = edge; if(!directed){ insert_edge(y, x, weight, true); } } } void Graph::print(){ for(int v = 1; v < (MAXV + 1); v ++){ if(this->edges[v] != NULL){ std::cout << "Vertex " << v << " has neighbors: " << std::endl; EdgeNode *curr = this->edges[v]; while(curr != NULL){ std::cout << curr->key << std::endl; curr = curr->next; } } } } void init_vars(bool discovered[], float distance[], int parent[]){ for(int i = 1; i < (MAXV + 1); i ++){ discovered[i] = false; distance[i] = std::numeric_limits::max(); parent[i] = -1; } } void dijkstra_shortest_path(Graph *g, int parent[], float distance[], int start){ bool discovered[MAXV + 1]; EdgeNode *curr; int v_curr; int v_neighbor; float weight; float smallest_dist; init_vars(discovered, distance, parent); distance[start] = 0; v_curr = start; while(discovered[v_curr] == false){ discovered[v_curr] = true; curr = g->edges[v_curr]; while(curr != NULL){ v_neighbor = curr->key; weight = curr->weight; if((distance[v_curr] + weight) < distance[v_neighbor]){ distance[v_neighbor] = distance[v_curr] + weight; parent[v_neighbor] = v_curr; } curr = curr->next; } //set the next current vertex to the vertex with the smallest distance smallest_dist = std::numeric_limits::max(); for(int i = 1; i < (MAXV + 1); i ++){ if(!discovered[i] && (distance[i] < smallest_dist)){ v_curr = i; smallest_dist = distance[i]; } } } } void get_shortest_path(int v, int parent[],std::vector& path){ if(v > 0 && v < (MAXV + 1) && parent[v] != -1){ path.push_back( parent[v]) ; get_shortest_path(parent[v], parent,path); } } void print_distances(int start, float distance[]){ for(int i = 1; i < (MAXV + 1); i ++){ if(distance[i] != std::numeric_limits::max()){ std::cout << "Shortest distance from " << start << " to " << i << " is: " << distance[i] << std::endl; } } } PathMap::PathMap(){ grapher_ = new Graph(false); } PathMap::~PathMap() { delete grapher_; } void PathMap::AddVertex(int id,float x,float y) { node_[id]={x,y}; printf(" Add node %f,%f nodes :%d\n",x,y,node_.size()); } bool PathMap::AddEdge(int id1,int id2,bool directed) { if(node_.find(id1)!=node_.end() && node_.find(id2)!=node_.end()) { float x1=node_[id1].x; float y1=node_[id1].y; float x2=node_[id2].x; float y2=node_[id2].y; float distance=sqrt(pow(x2-x1,2)+pow(y2-y1,2))+EXP; grapher_->insert_edge(id1, id2, distance, directed); edge_.push_back({id1,id2,directed}); printf(" Add edge %d-%d \n",id1,id2); return true; } return false; } bool PathMap::GetShortestPath(int id1,int id2,std::vector& path,float& shortest_distance) { if(id1==id2) return false; if(node_.find(id1)!=node_.end() && node_.find(id2)!=node_.end()) { dijkstra_shortest_path(grapher_, parent_, distance_, id1); get_shortest_path(id2, parent_, path); shortest_distance=distance_[id2]; return true; } return false; } bool PathMap::GetVertexPos(int id,float& x,float& y) { if(node_.find(id)!=node_.end()) { x=node_[id].x; y=node_[id].y; return true; } return false; }