Introduction to the shortest path algorithm

Don't talk nonsense here, just look at the code directly to implement the Dijsk shortest path algorithm. Why is there this blog? Because I found that when the number of path connections increases, many template class methods are not easy to use. Although this code uses macro definitions, it is super fast and guarantees the correct results!

#include <iostream>
#include <limits>
#include <vector>
using namespace std;

#define MAXV 10000
///计算路径并返回
void getPathList(int ptform,int ptend,std::vector<int>&pathList,int &distance);

class EdgeNode{
    public:
        int key;
        int weight;
        EdgeNode *next;
        EdgeNode(int, int);
};

EdgeNode::EdgeNode(int key, int weight){
    this->key = key;
    this->weight = weight;
    this->next = NULL;
}

class Graph{
    bool directed;
    public:
        EdgeNode *edges[MAXV + 1];
        Graph(bool);
        ~Graph();
        void insert_edge(int, int, int, bool);
        void print();
};

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, int 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){
            cout << "Vertex " << v << " has neighbors: " << endl;
            EdgeNode *curr = this->edges[v];
            while(curr != NULL){
                cout << curr->key << endl;
                curr = curr->next;
            }
        }
    }
}

void init_vars(bool discovered[], int distance[], int parent[]){
    for(int i = 1; i < (MAXV + 1); i ++){
        discovered[i] = false;
        distance[i] = std::numeric_limits<int>::max();
        parent[i] = -1;
    }
}

void dijkstra_shortest_path(Graph *g, int parent[], int distance[], int start){

    bool discovered[MAXV + 1];
    EdgeNode *curr;
    int v_curr;
    int v_neighbor;
    int weight;
    int 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<int>::max();
        for(int i = 1; i < (MAXV + 1); i ++){
            if(!discovered[i] && (distance[i] < smallest_dist)){
                v_curr = i;
                smallest_dist = distance[i];
            }
        }
    }
}

void print_shortest_path(int v, int parent[]){
    if(v > 0 && v < (MAXV + 1) && parent[v] != -1){
        cout << parent[v] << " ";
        print_shortest_path(parent[v], parent);
    }
}
///获取路径节点
void get_shortest_path(int v, int parent[],std::vector<int>&pathlist){
    if(v > 0 && v < (MAXV + 1) && parent[v] != -1)
	{
        cout << parent[v] << " ";
		pathlist.push_back(parent[v]);
        get_shortest_path(parent[v], parent,pathlist);
    }
}
int get_distances(int target, int distance[]){
  
	if(target>MAXV||target<0){
		 cout << "目标地不存在!错误 ";
		return 0;
	}

	 if(distance[target] != std::numeric_limits<int>::max())
	 {
		  cout << "到达目标点 : "<<target<<" 距离:"<<distance[target];
		 return distance[target] ;
	 }
	 return 0;

}
void print_distances(int start, int distance[]){
    for(int i = 1; i < (MAXV + 1); i ++){
        if(distance[i] != std::numeric_limits<int>::max()){
            cout << "Shortest distance from " << start << " to " << i << " is: " << distance[i] << endl;
        }
    }
}

void getPathList(int ptform,int ptend,std::vector<int>&pathList,int &distance)
{



}


int main(){

    Graph *g = new Graph(false);
    int parent[MAXV + 1];
    int distance[MAXV + 1];
    int start = 3482;


	string dataFile="Linklines";
	 int count = 0;  
    FILE* pfData = fopen(dataFile.c_str(), "r");  

    if (pfData == NULL)  
    {  
        cout<<"DataFile does not exist!!!"<<endl;  
        return false;  
    }   
    else  
    {  
	
		int  ptsid,pteid;
		int weight;
			
        while (!feof(pfData))  
        {  
            fscanf(pfData, "%d", &ptsid); 
            fscanf(pfData, "%d", &pteid);  
            fscanf(pfData, "%d", &weight);  
        g->insert_edge(ptsid, pteid, weight, false);
            count++;  
        }  
        fclose(pfData); 

		std::cout<<" 读取树结构路径文件并构建成功! size:"<<count <<std::endl;
    }  




 /* g->insert_edge(1, 2, 4, false);
    g->insert_edge(1, 3, 1, false);
    g->insert_edge(3, 2, 1, false);
    g->insert_edge(3, 4, 5, false);
    g->insert_edge(2, 4, 3, false);
    g->insert_edge(2, 5, 1, false);
    g->insert_edge(4, 5, 2, false);*/

    dijkstra_shortest_path(g, parent, distance, start);
    //print shortest path from vertex 1 to 5
    print_shortest_path(3483, parent);
    print_distances(start, distance);




    delete g;
    return 0;
}


What? Want to see the effect?

Give you a picture! Although both methods are possible, you know that the connection relationship here is very complicated. For example, the number of nodes in it is 3842, and the connection relationship is 18,324. For these many connection relationships, the general template algorithm calculation fails. . . This algorithm works fine!

Figure 1. Dijsk algorithm pathfinding results

 

 

Figure 2 A* algorithm pathfinding results

 

 

Guess you like

Origin blog.csdn.net/sun19890716/article/details/108126966