Algoritmo de Dijkstra en lenguaje C para encontrar la ruta más corta explicación detallada

preparar un mapa

Robar una foto de un amigo desconocido, je, je.inserte la descripción de la imagen aquí

Descripción del ejemplo de algoritmo

Propósito: encontrar el camino más corto entre el punto A y el punto B en un mapa (de hecho, cada operación del algoritmo encontrará el camino más corto entre el punto A y el otro punto).
Proceso:
1) Toma el ejemplo del punto 1 al punto 4.
2) Marque la ubicación 1. (La función de marcar se realizará más adelante. Cuando todas las ubicaciones estén marcadas, ¡se encontrará el camino más corto!), En este momento, dibuje en el borrador (99 significa inaccesible)

线路  距离总和
1->2  2
1->3  5
1->4  99
1->5  99
1->6  99
1->7  99

3) A través de la comparación, podemos obtener que la distancia 1->2 es la más corta, luego marcamos la ubicación No. 2 en este momento para indicar que hemos encontrado la distancia más corta del No. 1 al No. 2. Entonces, en este momento, ¿podemos acortar la distancia del No. 1 a lugares distintos al No. 2? Comparando 1->3 y 1->2->3, podemos ver que la distancia de 1->2->3 es 4, que es más corto Modifique 1 La ruta y la distancia del No. 3 al No. 3, y luego compare las rutas restantes del sitio sin marcar a su vez. Luego revisa el borrador

线路  		距离总和
1->2  		2
1->2->3  	4
1->2->4  	6
1->2->5  	8
1->6  		99
1->7  		99

4) En comparación, podemos obtener la distancia más corta entre los lugares no marcados entre el n.° 1 y el n.° 3. Se puede ver que también se ha concluido el camino más corto entre el n.° 1 y el n.° 3. Luego marque el No. 3. En este momento, la distancia desde el No. 1 hasta la ubicación sin marcar está más cerca de la ruta original, o vaya primero al No. 3, y acérquese desde el No. 3 y compare. Toma como ejemplo el número 4. En la última conclusión, 1->2->4=6, ahora 1->2->3->4=5, que es más corto, modifica la ruta, luego compara los números 1 a 5 a su vez, del No. 1 al No. 6, y del No. 1 al No. 7. La distancia más corta se puede modificar para que sea más corta.

线路  			距离总和
1->2  			2
1->2->3  		4
1->2->3->4  	5
1->2->5  		8
1->2->3->6  	7
1->7  			99

5) De acuerdo con las reglas anteriores, marque el No. 4 en este momento, compare y modifique para obtener las ubicaciones No. 5, 6 y 7 con distancias más cortas

线路  			距离总和
1->2  			2
1->2->3  		4
1->2->3->4  	5
1->2->5  		8
1->2->3->4->6  	6
1->2->3->4->7  	9

6) De acuerdo con las reglas anteriores, marque el No. 6 en este momento, compare y modifique para obtener las ubicaciones No. 5 y No. 7 con distancias más cortas

线路  				距离总和
1->2  				2
1->2->3  			4
1->2->3->4  		5
1->2->5  			8
1->2->3->4->6  		6
1->2->3->4->6->7  	8

7) De acuerdo con las reglas anteriores, marque el No. 5 en este momento (las dos distancias son iguales, elija una al azar), compare y modifique para obtener la ubicación No. 7 con una distancia más corta

线路  				距离总和
1->2  				2
1->2->3  			4
1->2->3->4  		5
1->2->5  			8
1->2->3->4->6  		6
1->2->3->4->6->7  	8

8) Marque la ubicación No. 7, y no hay ubicaciones sin marcar en este momento, lo que significa que todas las ubicaciones han encontrado el camino más corto desde el No. 1 hasta allí. Finaliza el algoritmo.

Resumen del algoritmo

Encuentre la ruta más corta de A a B
1. En el mapa de conjunto de ubicaciones, marque A primero.
2. Guarde la ruta y la distancia de A a otros lugares directamente, elija la más corta, asumiendo que es A->C, luego marque C en este momento, indicando que se ha encontrado la ruta más corta de A a C, y compare A ->otras distancias Para la distancia desde A->C->Otro, si la ruta que pasa por C es relativamente corta, modifique A->Otro a A->C->Otro, y actualice su distancia actual más corta en el tiempo.
3. Repita el paso 2 hasta que todas las ubicaciones estén marcadas.
4. Ruta A->…->B y distancia en el resultado de salida (… significa 0 a múltiples puntos intermedios).

Código

Guardar el mapa con una estructura de mapa

//最大地点数 
#define MAXCOUNT 20
//不可能距离值(两地点无直接线路时) 
#define MAXDISTANCE 99
//地图结构 
typedef struct map
{
    
    
	//地点数量 
	int nodeCount;
	//地点标识 
	int id[MAXCOUNT];
	//各地点间距离 distance[i][j]=distance[j][i],表示i地点和j地点的距离 
	int distance[MAXCOUNT][MAXCOUNT]; 
}Map; 

Dado que hay muchas líneas en el mapa, aquí se usa el método de lectura de archivos para escribir map.txt, y el formato es el
número de ubicaciones n1
el número de líneas n2
n2 (la identificación de la ubicación a, la distancia entre la identificación a y b de ubicación b)

7
12
1 2 2
1 3 5
2 3 2
2 5 6
2 4 4
4 3 1
3 6 3
4 5 4
4 6 1
4 7 4
5 7 1
6 7 2

Escribir un archivo para leer en la función de mapa

//读取map.txt中的信息 
void readMap(Map *map)
{
    
    
	//以读形式打开文件 
	FILE *fp=fopen("map.txt","r");
	//读取地点数量 
	fscanf(fp,"%d",&map->nodeCount);
	int n;
	//读取路线数量 
	fscanf(fp,"%d",&n);
	int i,j;
	//初始化地点id
	for(i=1;i<=map->nodeCount;i++)
	{
    
    
		map->id[i]=i;	
	} 
	//初始化每两地点均无路线
	for(i=1;i<MAXCOUNT;i++)
	{
    
    
		for(j=1;j<MAXCOUNT;j++)
		{
    
    
			map->distance[i][j]=MAXDISTANCE;	
		}		
	}	
	//读入线路
	int k,d;
	for(k=1;k<=n;k++)
	{
    
    
		fscanf(fp,"%d%d%d",&i,&j,&d);
		map->distance[i][j]=d;
		map->distance[j][i]=d;
	} 
	//关闭文件
	fclose(fp); 
} 

Escribir una función de mapa de impresión

//打印地图信息 
void displayMap(Map map)
{
    
    
	int i,j;
	printf("地点个数:%d\n",map.nodeCount);
	printf("各地点间距离(...表示无路线):\n");
	printf("    ");
	for(i=1;i<=map.nodeCount;i++)
	{
    
    
		printf("%-3d ",i);
	}
	printf("\n");
	for(i=1;i<=map.nodeCount;i++)
	{
    
    
		printf("%-3d ",i);
		for(j=i;j<=map.nodeCount;j++)
		{
    
    
			if(map.distance[i][j]==MAXDISTANCE)
			{
    
    
				printf("... ");
			}
			else
			{
    
    
				printf("%-3d ",map.distance[i][j]);	
			}
		}	
		printf("\n");
	} 
	printf("\n");
}

Estructura de la ruta de escritura

//路线结构 
typedef struct road
{
    
    
	//经过地点id 
	int path[MAXCOUNT];
	//距离
	int minDistance; 
	//经过的地点数
	int count; 
}Road; 

El algoritmo de Dijkstra implementa el camino más corto desde el punto a a otros puntos

//迪杰斯特拉算法求地点a到其他地点的最短路径 
Road *djstl(Map map,int id_a)
{
    
    
	//所有路线 
	Road r[MAXCOUNT];
	//标记数组(0为未标记,1为已标记) 
	int flag[MAXCOUNT]={
    
    0};
	
	int i;
	//初始化所有路线 
	for(i=1;i<=map.nodeCount;i++)
	{
    
    
		/*a地点到其他各个地点的距离*/
		/*起点是a,终点是i*/
		r[i].count=2;
		r[i].path[0]=id_a;
		r[i].path[1]=i;
		r[i].minDistance=map.distance[id_a][i];	
	} 
	
	//标记a
	flag[id_a]=1;
	
	//还有未标记地点则循环执行 
	while(1)
	{
    
    
		//寻找a到未标记的地点的最短路线的下标 
		int index=-1;
		for(i=1;i<=map.nodeCount;i++)
		{
    
    
			//未标记 
			if(flag[i]==0)	
			{
    
    
				if(index==-1)
				{
    
    
					index=i;
				}
				else if(r[i].minDistance<r[index].minDistance)
				{
    
    
					index=i;
				}
			}
		}	
		//不存在未标记下标了 
		if(index==-1)
		{
    
    
			return r;
		}
		//标记index
		flag[index]=1; 
		//比较并修改其他路线此时的最短路径 
		for(i=1;i<=map.nodeCount;i++)
		{
    
    
			//未找到最短路径的地点 
			if(flag[i]==0)
			{
    
    
				//a->...->i短还是a->...->index->i短,后者短,则说明a到i有更好的选择 
				if(r[i].minDistance>r[index].minDistance+map.distance[index][i]) 
				{
    
    
					/*将r[index]的值赋予r[i],并修改r[i]的最短路径*/
					r[i].count=r[index].count+1;
					int j;
					for(j=0;j<r[i].count-1;j++)
					{
    
    
						r[i].path[j]=r[index].path[j];
					}
					r[i].path[j]=i;
					r[i].minDistance=r[index].minDistance+map.distance[index][i];
				}
			}
		}
	} 
}

Salida de la ruta buscada

//打印a到b的最短路径 
void displayRoad(Road rab)
{
    
    
	printf("距离:%d\n",rab.minDistance);
	int i;
	printf("路线:");
	for(i=0;i<rab.count-1;i++)
	{
    
    
		printf("%d-->",rab.path[i]);
	}
	printf("%d\n\n",rab.path[i]);
}

Escribir la prueba de la función principal

int main()
{
    
    
	//地图变量 
	Map map;
	//读取地图 
	readMap(&map);
	//打印地图信息 
	displayMap(map);
	
	int id_a,id_b;
	printf("id_a:");
	scanf("%d",&id_a);
	printf("id_b:");
	scanf("%d",&id_b);
	
	printf("搜索最短路径中,请稍后...\n");
	Road *r=djstl(map,id_a);
	printf("搜索最短路径完毕!\n");
	displayRoad(r[id_b]);
	return 0;
}

Pruebe la ruta más corta desde el n.° 1 al n.° 4.
inserte la descripción de la imagen aquí
Pruebe la distancia más corta desde el n.° 1 al n.° 7.
inserte la descripción de la imagen aquí
El resultado es consistente con el cálculo anterior y la realización está completa.

Supongo que te gusta

Origin blog.csdn.net/qq_36694133/article/details/104301906
Recomendado
Clasificación