The concept of shortest path for the shortest path Dijkstra (Dijkstra) algorithm diagram for C/+ + graphs:
A traveler from city A to City B, he wants to choose a route with the fewest number of connections on the way. Assuming that you need to change every station on the way, this problem is reflected in the figure to find a path with the fewest number of edges from vertex a to B. We just go from vertex a to the breadth-first traversal of the graph, and terminate when we encounter Vertex B. From the resulting breadth-first spanning tree, the path from root vertex A to vertex B is the path with the least number of relays. But this is just the shortest path problem of the simplest kind of graph. Sometimes, for the traveler, it may be more of a concern to save on transportation costs, and for drivers, mileage and speed are the information they are interested in. In order to represent the relevant information on the graph, we can assign weights to the edges, and the weights can represent the distance between two cities, or the time required on the way, or transportation costs. The measure of the path length is no longer the number of the top edge of the path, but the sum of the top weights of the path.
Implementation ideas:
- Create 2 auxiliary int* Arrays Dist path,1 BOOL Array s
- Dist the shortest distance from the target vertex to each vertex
- Path holds the destination vertex to each vertex
- S has been looked up for the vertex set to true, otherwise false
1, assuming the target vertex is a, first from a to find the weights of each vertex,
|
A |
B |
C |
D |
E |
Dist |
0 |
10 |
Infinity |
30 |
100 |
Path |
-1 |
0 |
0 |
0 |
0 |
S |
True |
False |
False |
False |
False |
Path meaning: For example path[1]=0, represents the vertex from subscript 0 (a vertex) to the B vertex
2, from Dist to find the minimum value s is false, that is, the value of dist[1] 10, subscript 1 is the vertex b, and then start from B to find the weights of each vertex, update dist and path, and set B to True
|
A |
B |
C |
D |
E |
Dist |
0 |
10 |
60 |
30 |
100 |
Path |
-1 |
0 |
1 |
0 |
0 |
S |
True |
True |
False |
False |
False |
3, found in dist s is the minimum value, that is, the value of dist[3] 30, subscript 3 is the vertex D, and then start from D to find the weights of each vertex, update dist and path, and set D to True
|
A |
B |
C |
D |
E |
Dist |
0 |
10 |
50 |
30 |
90 |
Path |
-1 |
0 |
3 |
0 |
3 |
S |
True |
True |
False |
True |
False |
4, found in dist s is the minimum value of false, that is, dist[2] the value of 50, subscript 2 is the vertex c, and then start from C to find the weights of each vertex, update dist and path, and set C to True
|
A |
B |
C |
D |
E |
Dist |
0 |
10 |
50 |
30 |
60 |
Path |
-1 |
0 |
3 |
0 |
2 |
S |
True |
True |
True |
True |
False |
5, found in dist S is the lowest value of false, that is, the value of dist[4] 60, subscript 4 is the vertex e, and then starting from E to find the weights of each vertex, update dist and path, and set E to True
|
A |
B |
C |
D |
E |
Dist |
0 |
10 |
50 |
30 |
60 |
Path |
-1 |
0 |
3 |
0 |
2 |
S |
True |
True |
True |
True |
True |
Figure is
Here are two images to help understand
Dijkstra.h
#ifndef __mixspantree__#define __mixspantree__#include <stdio.h>#include <malloc.h>#include <assert.h>#include <memory.h>#include <stdlib.h>#include <stdbool.h>#define Default_vertex_size 20#define T char//dai biao ding dian de lei xing#define E int#define MAX_COST 0x7FFFFFFFtypedef struct GraphMtx{ int MaxVertices;//zui da ding dian shu liang] int NumVertices;//shi ji ding dian shu liang int NumEdges;//bian de shu lian T* VerticesList;//ding dian list int** Edge;//bian de lian jie xin xi, bu shi 0 jiu shi 1}GraphMtx;//chu shi hua tuvoid init_graph(GraphMtx* gm);//打印二维数组void show_graph(GraphMtx* gm);//插入顶点void insert_vertex(GraphMtx* gm, T v);//添加顶点间的线void insert_edge(GraphMtx* gm, T v1, T v2, E cost);//最短路径void short_path(GraphMtx* g,T v,E* dist, int* path);#endif
Dijkstra.c
#include "dijkstra.h" void Init_graph (graphmtx* gm) {gm->maxvertices = default_vertex_size; gm->numedges = gm->numvertices = 0; Kai Pi ding dian de nei cun kong Jian gm->verticeslist = (t*) malloc (sizeof (T) * (gm->maxvertices)); ASSERT (NULL! = gm->verticeslist); Create a two-dimensional array//give an int a level two pointer to an array with 8 int first-level pointers//open up a memory space that can hold gm->maxvertices int-level pointers Gm->edge = (int**) malloc ( sizeof (int*) * (gm->maxvertices)); ASSERT (NULL! = Gm->edge); Open Gm->maxvertices Group, can hold gm->maxvertices int's memory space for (int i = 0; i < gm->maxvertices; ++i) {Gm->edge[i] = (int*) malloc (sizeof (int) * gm->maxvertices); }//Initialize a two-dimensional array//Let the relationship between each vertex be unconnected for (int i = 0; i < gm->maxvertices; ++i) {for (int j = 0; J < Gm->maxver Tices; ++J) {if (i = = j) Gm->edge[i][j] = 0; else gm->edge[i][j] = max_cost; }}}//prints a two-dimensional array of void Show_graph (graphmtx* gm) {printf (""); for (int i = 0; i < gm->numvertices; ++i) {printf ("%3c", Gm->vErticeslist[i]); } printf ("\ n"); for (int i = 0; i < gm->numvertices; ++i) {//At the beginning of the line, print out the name of the vertex printf ("%c:", Gm->verticeslist[i]); for (int j = 0; J < gm->numvertices; ++j) {if (gm->edge[i][j] = = max_cost) {printf ("%3c", ' * '); } else{printf ("%3d", Gm->edge[i][j]); }} printf ("\ n"); } printf ("\ n");} Insert vertex void Insert_vertex (graphmtx* gm, T v) {//Vertex space is full, no more vertices can be inserted if (gm->numvertices >= gm->maxvertices) {retur N } gm->verticeslist[gm->numvertices++] = V;} int Getvertexindex (graphmtx* gm, T v) {for (int i = 0; i < gm->numvertices; ++i) {if (gm->verticeslist[i] = = v) return i; } return-1;} Add line void Insert_edge between vertices (graphmtx* gm, T v1, T v2, E cost) {if (V1 = = v2) return; find subscript Int J = Getvertexindex (GM, v1) of 2 vertices; int k = Getvertexindex (GM, V2); The description finds vertices, and there is no line between the dots if (j! =-1 && k! =-1) {//Because there is a direction, so update 1 values gm->edge[j][k] = cost; Number of sides plus a gm->numedges++; }}//gets the 2 vertices between theWeight e getweight (graphmtx* g, int v1, int v2) {if (V1 = =-1 | | v2 =-1) return max_cost; return G->EDGE[V1][V2];} Shortest path void Short_path (graphmtx* g,t v,e* Dist, int* path) {int n = g->numvertices; bool* s = (bool*) malloc (sizeof (BOOL) * n); ASSERT (NULL! = s); int VI = Getvertexindex (g, v); for (int i = 0; i < n; ++i) {//Get the weights between each vertex and the target vertex dist[i] = getweight (g, vi, I); S[i] = false; if (i! = VI && Dist[i] < Max_cost) {path[i] = VI; } else{Path[i] =-1; }} S[vi] = true; int min; int W; for (int i = 0; i < n-1; ++i) {min = Max_cost; U is the subscript int u = VI for the shortest path vertex; for (int j = 0; J < N; ++j) {if (!s[j] && dist[j] < min) {u = j; min = Dist[j]; }}//Add u to s set s[u] = true; Update the weights for the next point to all points for (int k = 0; k < n; ++k) {w = Getweight (g, u, K); if (!s[k] && W < max_cost && Dist[u] + W < dist[k]) {dist[k] = Dist[u] + W; Path[k] = u; } } }}
Dijkstramain.c
#include "dijkstra.h"int main(){ GraphMtx gm; //初始化图 init_graph(&gm); //插入顶点 insert_vertex(&gm, ‘A‘); insert_vertex(&gm, ‘B‘); insert_vertex(&gm, ‘C‘); insert_vertex(&gm, ‘D‘); insert_vertex(&gm, ‘E‘); //添加连线 insert_edge(&gm, ‘A‘, ‘B‘, 10); insert_edge(&gm, ‘A‘, ‘D‘, 30); insert_edge(&gm, ‘A‘, ‘E‘, 100); insert_edge(&gm, ‘B‘, ‘C‘, 50); insert_edge(&gm, ‘C‘, ‘E‘, 10); insert_edge(&gm, ‘D‘, ‘C‘, 20); insert_edge(&gm, ‘D‘, ‘E‘, 60); //打印图 show_graph(&gm); int n = gm.NumVertices; E* dist = (E*)malloc(sizeof(E) * n); int* path = (int*)malloc(sizeof(int) * n); assert(NULL != dist && NULL != path); //最短路径 short_path(&gm, ‘A‘, dist, path);}
Full code
Compilation method: Gcc-g dijkstra.c dijkstramain.c
Dijkstra (Dijkstra) algorithm for the shortest path of a/C + + graph