Data Structure Diagram (5) - Shortest Path

For a network graph, the shortest path refers to the path with the least sum of weights on the edges passing between two vertices, and we call the first vertex on the path the source point and the last vertex the end point. The non-net graph can be completely understood as a network with all edges having a weight of 1.

The shortest path problem from a source point to other vertices - Dijkstra's algorithm

This is an algorithm that produces the shortest paths in order of increasing path length. It does not find the shortest path from the source point to the end point at once, but finds the shortest path of the vertices between them step by step. The process is based on the shortest path that has been found, and the further vertices are found. The shortest path to get the result you want in the end.

code show as below:
#include "stdio.h"    
#include "stdlib.h"   
#include "io.h"  
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXEDGE 20
#define MAXVEX 20
#define INFINITY 65535

typedef int Status; /* Status is the type of the function, and its value is the function result status code, such as OK, etc.*/


typedef struct
{
	int vexs[MAXVEX];
	int arc[MAXVEX][MAXVEX];
	int numVertexes, numEdges;
}MGraph;

typedef int Patharc[MAXVEX]; /* Array for storing shortest path indices*/
typedef int ShortPathTable[MAXVEX];/* used to store the weight and the shortest path to each point */

/* component diagram */
void CreateMGraph(MGraph *G)
{
	int i, j;

	/* printf("Please enter the number of edges and vertices:"); */
	G->numEdges=16;
	G->numVertexes=9;

	for (i = 0; i < G->numVertexes; i++)/* initialize graph*/
	{
		G->vexs[i]=i;
	}

	for (i = 0; i < G->numVertexes; i++)/* initialize graph*/
	{
		for ( j = 0; j < G->numVertexes; j++)
		{
			if (i==j)
				G->arc[i][j]=0;
			else
				G->arc[i][j] = G->arc[j][i] = INFINITY;
		}
	}

	G->arc[0][1]=1;
	G->arc[0][2]=5;
	G->arc[1][2]=3;
	G->arc[1][3]=7;
	G->arc[1][4]=5;

	G->arc[2][4]=1;
	G->arc[2][5]=7;
	G->arc[3][4]=2;
	G->arc[3][6]=3;
	G->arc[4][5]=3;

	G->arc[4][6]=6;
	G->arc[4][7]=9;
	G->arc[5][7]=5;
	G->arc[6][7]=2;
	G->arc[6][8]=7;

	G->arc[7][8]=4;


	for(i = 0; i < G->numVertexes; i++)
	{
		for(j = i; j < G->numVertexes; j++)
		{
			G->arc[j][i] =G->arc[i][j];
		}
	}

}

/* Dijkstra's algorithm, find the shortest path P[v] and the weighted length D[v] from the v0 vertex of the directed network G to the remaining vertex v */    
/* The value of P[v] is the index of the predecessor vertex, D[v] represents the shortest path length from v0 to v and */  
void ShortestPath_Dijkstra(MGraph G, int v0, Patharc *P, ShortPathTable *D)
{    
	int v, w, k, min;    
	int final[MAXVEX];/* final[w]=1 means to find the shortest path from vertex v0 to vw*/
	for(v=0; v<G.numVertexes; v++) /* Initialize data*/
	{        
		final[v] = 0; /* all vertices are initialized to unknown shortest path state */
		(*D)[v] = G.arc[v0][v];/* Add weights to vertices connected to v0*/
		(*P)[v] = -1; /* Initialize the path array P to -1 */       
	}

	(*D)[v0] = 0; /* v0 to v0 path is 0 */  
	final[v0] = 1; /* v0 to v0 do not need to find the path*/        
	/* Start the main loop and find the shortest path from v0 to a v vertex each time */   
	for(v=1; v<G.numVertexes; v++)   
	{
		min=INFINITY; /* The closest distance to the v0 vertex currently known*/        
		for(w=0; w<G.numVertexes; w++) /* Find the closest vertex to v0*/    
		{            
			if(!final[w] && (*D)[w]<min)             
			{                   
				k=w;                    
				min = (*D)[w]; /* w vertex is closer to v0 vertex */            
			}        
		}        
		final[k] = 1; /* set the closest vertex found so far to 1 */
		for(w=0; w<G.numVertexes; w++) /* Correct the current shortest path and distance*/
		{
			/* If the path through the v vertex is shorter than the current length of the path */
			if(!final[w] && (min+G.arc[k][w]<(*D)[w]))   
			{ /* Indicate that a shorter path was found, modify D[w] and P[w] */
				(*D)[w] = min + G.arc[k][w]; /* Modify the current path length*/               
				(*P)[w]=k;        
			}       
		}   
	}
}

int main(void)
{   
	int i,j,v0;
	MGraph G;    
	Patharc P;    
	ShortPathTable D; /* Find the shortest path from a point to other points*/   
	v0 = 0;
	
	CreateMGraph(&G);
	
	ShortestPath_Dijkstra(G, v0, &P, &D);  

	printf("The shortest path is reversed as follows:\n");    
	for(i=1;i<G.numVertexes;++i)   
	{       
		printf("v%d - v%d : ",v0,i);
		j=i;
		while(P[j]!=-1)
		{
			printf("%d ",P[j]);
			j=P[j];
		}
		printf("\n");
	}    
	printf("\nThe length of the shortest path from the source point to each vertex is:\n");  
	for(i=1;i<G.numVertexes;++i)        
		printf("v%d - v%d : %d \n",G.vexs[0],G.vexs[i],D[i]);     
	return 0;
}
The time complexity of Dijkstra's algorithm is O(n^2).
If you want to find the shortest path from any vertex to all other vertices, the simple way is to run Dijkstra's algorithm once for each vertex as the source point. At this time, the time complexity of the entire algorithm is O(n^3).

Shortest path from all vertices to all vertices - Floyd's algorithm


#include "stdio.h"    
#include "stdlib.h"   
#include "io.h"  
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXEDGE 20
#define MAXVEX 20
#define INFINITY 65535

typedef int Status; /* Status is the type of the function, and its value is the function result status code, such as OK, etc.*/

typedef struct
{
	int vexs[MAXVEX];
	int arc[MAXVEX][MAXVEX];
	int numVertexes, numEdges;
}MGraph;

typedef int Patharc[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];

/* component diagram */
void CreateMGraph(MGraph *G)
{
	int i, j;

	/* printf("Please enter the number of edges and vertices:"); */
	G->numEdges=16;
	G->numVertexes=9;

	for (i = 0; i < G->numVertexes; i++)/* initialize graph*/
	{
		G->vexs[i]=i;
	}

	for (i = 0; i < G->numVertexes; i++)/* initialize graph*/
	{
		for ( j = 0; j < G->numVertexes; j++)
		{
			if (i==j)
				G->arc[i][j]=0;
			else
				G->arc[i][j] = G->arc[j][i] = INFINITY;
		}
	}

	G->arc[0][1]=1;
	G->arc[0][2]=5;
	G->arc[1][2]=3;
	G->arc[1][3]=7;
	G->arc[1][4]=5;

	G->arc[2][4]=1;
	G->arc[2][5]=7;
	G->arc[3][4]=2;
	G->arc[3][6]=3;
	G->arc[4][5]=3;

	G->arc[4][6]=6;
	G->arc[4][7]=9;
	G->arc[5][7]=5;
	G->arc[6][7]=2;
	G->arc[6][8]=7;

	G->arc[7][8]=4;


	for(i = 0; i < G->numVertexes; i++)
	{
		for(j = i; j < G->numVertexes; j++)
		{
			G->arc[j][i] =G->arc[i][j];
		}
	}

}

/* Floyd's algorithm, find the shortest path P[v][w] and the weighted length D[v][w] from each vertex v to the rest of the vertex w in the network graph G. */    
void ShortestPath_Floyd(MGraph G, Patharc *P, ShortPathTable *D)
{    
	int v,w,k;    
	for(v=0; v<G.numVertexes; ++v) /* Initialize D and P */  
	{        
		for(w=0; w<G.numVertexes; ++w)  
		{
			(*D)[v][w]=G.arc[v][w]; /* D[v][w] value is the weight between corresponding points*/
			(*P)[v][w]=w; /* Initialize P */
		}
	}
	for(k=0; k<G.numVertexes; ++k)   
	{
		for(v=0; v<G.numVertexes; ++v)  
		{        
			for(w=0; w<G.numVertexes; ++w)    
			{
				if ((*D)[v][w]>(*D)[v][k]+(*D)[k][w])
				{/* If the path through the subscript k vertex is shorter than the path between the original two points */
					(*D)[v][w]=(*D)[v][k]+(*D)[k][w];/* Set the current weight between two points to the smaller one*/
					(*P)[v][w]=(*P)[v][k];/* The path is set to go through the vertex with index k*/
				}
			}
		}
	}
}

int main(void)
{    
	int v,w,k;  
	MGraph G;    
	
	Patharc P;    
	ShortPathTable D; /* Find the shortest path from a point to other points*/   
	
	CreateMGraph(&G);
	
	ShortestPath_Floyd(G,&P,&D);  

	printf("The shortest path between vertices is as follows:\n");    
	for(v=0; v<G.numVertexes; ++v)   
	{        
		for(w=v+1; w<G.numVertexes; w++)  
		{
			printf("v%d-v%d weight: %d ",v,w,D[v][w]);
			k=P[v][w]; /* Get the first path vertex index */
			printf(" path: %d",v); /* print the source point*/
			while(k!=w) /* if the path vertex index is not the end point */
			{
				printf(" -> %d",k); /* print path vertices*/
				k=P[k][w]; /* Get the next path vertex index */
			}
			printf(" -> %d\n",w); /* print end point*/
		}
		printf("\n");
	}

	printf("Shortest path D\n");
	for(v=0; v<G.numVertexes; ++v)  
	{        
		for(w=0; w<G.numVertexes; ++w)    
		{
			printf("%d\t",D[v][w]);
		}
		printf("\n");
	}
	printf("Shortest path P\n");
	for(v=0; v<G.numVertexes; ++v)  
	{        
		for(w=0; w<G.numVertexes; ++w)    
		{
			printf("%d ",P[v][w]);
		}
		printf("\n");
	}

	return 0;
}
Freud time complexity is O(n^3).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325713649&siteId=291194637