Algorithme de Dijkstra en langage C pour trouver l'explication détaillée du chemin le plus court

préparer une carte

Voler la photo d'un ami inconnu, hee hee.insérez la description de l'image ici

Description de l'exemple d'algorithme

But : Trouver un chemin le plus court entre un point A et un point B dans une carte (en fait, chaque opération de l'algorithme trouvera un chemin le plus court du point A à chaque autre point).
Processus :
1) Prenez l'exemple du point 1 au point 4.
2) Marquez l'emplacement 1. (Le rôle du balisage se réalisera plus tard. Quand tous les emplacements seront marqués, le chemin le plus court sera trouvé !), à ce moment tirez sur le brouillon (99 n'est pas directement joignable)

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

3) Par comparaison, nous pouvons obtenir que la distance 1-> 2 est la plus courte, puis nous marquons l'emplacement n° 2 à ce moment pour indiquer que nous avons trouvé la distance la plus courte du n° 1 au n° 2. Donc, à ce moment, pouvons-nous raccourcir la distance entre le n° 1 et des endroits autres que le n° 2 ? En comparant 1->3 et 1->2->3, nous pouvons voir que la distance de 1->2->3 est 4, ce qui est plus court Modifier 1 L'itinéraire et la distance entre le n° 3 et le n° 3, puis comparer tour à tour les autres itinéraires non marqués du site. Puis réviser le brouillon

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

4) Par comparaison, parmi les emplacements non marqués, nous pouvons obtenir la distance la plus courte entre le n° 1 et le n° 3. On peut voir que le chemin le plus court entre le n° 1 et le n° 3 a également été conclu. Ensuite, marquez le n° 3. À ce moment, la distance entre le n° 1 et l'emplacement non marqué est plus proche de l'itinéraire d'origine, ou allez d'abord au n° 3, puis rapprochez-vous du n° 3 et comparez. Prenons l'exemple du numéro 4. Dans la dernière conclusion, 1->2->4=6, maintenant 1->2->3->4=5, qui est plus court, modifiez l'itinéraire, puis comparez les numéros 1 à 5 tour à tour, n ° 1 à n ° 6 et n ° 1 à n ° 7. La distance la plus courte peut être modifiée pour être plus courte.

线路  			距离总和
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) Selon les règles ci-dessus, marquez le n ° 4 à ce moment, comparez et modifiez pour obtenir les emplacements n ° 5, 6 et 7 avec des distances plus courtes

线路  			距离总和
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) Selon les règles ci-dessus, marquez le n ° 6 à ce moment, comparez et modifiez pour obtenir les emplacements n ° 5 et n ° 7 avec des distances plus courtes

线路  				距离总和
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) Selon les règles ci-dessus, marquez le n ° 5 à ce moment (les deux distances sont les mêmes, choisissez-en une au hasard), comparez et modifiez pour obtenir l'emplacement n ° 7 avec une distance plus courte

线路  				距离总和
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) Marquez l'emplacement n° 7, et il n'y a pas d'emplacements non marqués pour le moment, ce qui signifie que tous les emplacements ont trouvé le chemin le plus court entre le n° 1 et celui-ci ! L'algorithme se termine.

Résumé de l'algorithme

Trouver le chemin le plus court de A à B
1. Dans la carte de localisation, marquez A en premier.
2. Enregistrez directement le chemin et la distance de A à d'autres endroits, choisissez le plus court, en supposant qu'il s'agit de A-> C, puis marquez C à ce moment, indiquant que le chemin le plus court de A à C a été trouvé, et comparez A ->autres distances Pour la distance de A->C->Autre, si l'itinéraire passant par C est relativement court, modifiez A->Autre en A->C->Autre, et mettez à jour sa distance la plus courte actuelle dans le temps.
3. Répétez l'étape 2 jusqu'à ce que tous les emplacements soient marqués.
4. A->…->B chemin et distance dans le résultat de sortie (… signifie 0 à plusieurs points intermédiaires).

Code

Enregistrer la carte avec une structure de carte

//最大地点数 
#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; 

Comme il y a beaucoup de lignes sur la carte, la méthode de lecture de fichier est utilisée ici pour écrire map.txt, et le format est le
nombre d'emplacements n1
le nombre de lignes n2
n2 (l'id de l'emplacement a, la distance entre l'id a et b de l'emplacement 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

Ecrire un fichier à lire dans la fonction map

//读取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); 
} 

Écrire une fonction d'impression de carte

//打印地图信息 
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");
}

Écrire la structure du chemin

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

L'algorithme de Dijkstra implémente le chemin le plus court du point a à d'autres points

//迪杰斯特拉算法求地点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];
				}
			}
		}
	} 
}

afficher le chemin demandé

//打印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]);
}

Rédiger le test de fonction 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;
}

Testez le chemin le plus court du n° 1 au n° 4.
insérez la description de l'image ici
Testez la distance la plus courte du n° 1 au n° 7.
insérez la description de l'image ici
Le résultat est cohérent avec le calcul ci-dessus, et la réalisation est terminée !

Je suppose que tu aimes

Origine blog.csdn.net/qq_36694133/article/details/104301906
conseillé
Classement