Relatório de experiência - solução de caminho mais curto baseada no algoritmo Dijsktra

Um estudante universitário desconhecido, conhecido como Caigou no mundo das artes marciais.
Autor original: jacky Li
Email: [email protected]
Última edição: 2022.12.3

f65e6a2d969044f6a4c8a2f02066848e.jpeg

 

Índice

1. Finalidade experimental

2. Equipamento experimental

3. Conteúdo experimental

【Descrição do Problema】

【Requisitos de entrada】

[Requisitos de saída]

【Amostra de entrada】

【Amostra de saída】

4. Dicas Experimentais

5. Etapas experimentais

5.1

6. Resultados experimentais

6.1 Capturas de tela dos principais códigos-fonte e resultados de execução após a conclusão do programa

7. Resumo da experiência

Oito: Destacar códigos de referência

O autor tem algo a dizer


 

Título do curso:

estrutura de dados

Nome do Projeto:

Solução de caminho mais curto baseada no algoritmo Dijsktra

Tipo de experimento:

Experimento de projeto

 

1. Finalidade experimental

1. Domine a representação matricial de adjacência de gráficos e domine o algoritmo para criar gráficos usando representação matricial de adjacência.

2. Domine o algoritmo Dijsktra para encontrar o caminho mais curto.


2. Equipamento experimental

Um computador com Dev C++ instalado


3. Conteúdo experimental

Preencha o formulário com base nas tarefas de formação prática concluídas em Touge, não se limitando aos requisitos abaixo. Você mesmo pode adicionar análise de algoritmo, descrição de algoritmo ou fluxograma

 

【Descrição do Problema】

Um mapa inclui n cidades. Supõe-se que existem m caminhos (gráfico direcionado) entre cidades e o comprimento de cada caminho é conhecido. Dada uma cidade inicial e uma cidade final no mapa, use o algoritmo Dijsktra para encontrar o caminho mais curto entre o ponto inicial e o ponto final.

【Requisitos de entrada】

Vários conjuntos de dados, cada conjunto de dados possui m+3 linhas. A primeira linha contém dois inteiros n e m, representando o número de cidades n e o número de caminhos m, respectivamente. A segunda linha possui n caracteres, representando o nome de cada cidade. Cada linha da terceira linha até a linha m+2 possui dois caracteres aeb e um inteiro d, que representa uma estrada com uma distância d da cidade a à cidade b. A última linha tem dois caracteres, representando o ponto inicial e final da cidade onde se encontra o caminho mais curto. Quando n e m são iguais a 0, a entrada termina.

[Requisitos de saída]

Cada conjunto de dados gera 2 linhas. A primeira linha é um número inteiro, que é o comprimento do caminho mais curto do ponto inicial ao ponto final. A linha 2 é uma string que representa o caminho. Separe cada dois caracteres com um espaço.

【Amostra de entrada】

3 3

abc

AB1

1 AC

CA 3

AC

6 8

ABCDEF

AF 100

AE 30

CA 10

5 AC

CD 50

DE 20

FE 60

DF 10

AF

0 0

【Amostra de saída】

2

abc

60

AEDF

4. Dicas Experimentais

O conteúdo deste experimento é uma extensão do Algoritmo 6.10 do livro principal. O Algoritmo 6.10 encontra o caminho mais curto do ponto de origem v0 para todos os outros vértices do gráfico. Este experimento requer encontrar o caminho mais curto de um ponto inicial especificado até um ponto final especificado. A fim de melhorar a eficiência do algoritmo, o julgamento pode ser feito durante a resolução.Quando o ponto final obtido é o ponto final especificado, a solução pode ser encerrada e os resultados correspondentes podem ser produzidos conforme necessário.

5. Etapas experimentais


5.1

Esta seção pode incluir ideias para solução de problemas, procedimentos que foram preenchidos inicialmente, mas falharam, como encontrar problemas e fazer correções por meio de depuração, e capturas de tela ou visualizações de especificações de ajuste podem ser coladas.

 

6. Resultados experimentais

6.1 Capturas de tela dos principais códigos-fonte e resultados de execução após a conclusão do programa

O código final, resultados de execução ou efeitos de visualização podem ser exibidos aqui.

  

 

7. Resumo da experiência

Use uma introdução e uma linguagem precisa para descrever quais problemas este experimento se concentrou em resolver, que conhecimento você aprendeu, quão bem você o dominou, etc.



Oito: Destacar códigos de referência

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <cmath>
#include <cstring>

#define IOS std::ios::sync_with_stdio(false)
//#define YES cout << "YES" << endl
//#define NO cout << "NO" << endl
#define MAXLEN 20  
#define INFINE 99999  

using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;

const int N = 100;

int n, m;

typedef struct ArcNode //定义结构体
{
	int adjvex;//邻接顶点下标
	int weight;//边的权值
	struct ArcNode *next; //指向下一个邻边节点指针
}ArcNode;

typedef struct
{
	char vertex;//顶点标志
	ArcNode *firstedge;//保存第一个边节点指针

}VertexNode;

typedef struct
{
	VertexNode adjlist[MAXLEN];//顶点数组
	int vexnum;  //顶点数 
	int arcnum;  //边数
}AdjList;

//创建邻接表
AdjList *Created_Graph(AdjList *G)
{
	int i, k, weight;
	ArcNode *s;
	char vex1, vex2; //顶点标志
	int n1, n2;//顶点下标
	G -> vexnum = n, G -> arcnum = m;
	for (i = 1; i <= G -> vexnum; i++)
	{
		cin >> G -> adjlist[i].vertex;
		G->adjlist[i].firstedge = NULL;   //头节点指向为空;
	}
	for (k = 1; k <= G -> arcnum; k ++) 
	{
		cin >> vex1 >> vex2;
		for (i = 1; i <= G -> vexnum; i ++) 
		{
			if (G -> adjlist[i].vertex == vex1) n1 = i;
			if (G -> adjlist[i].vertex == vex2) n2 = i;
		}
		cin >> weight;
		s = new(ArcNode);
		s -> adjvex = n2, s -> weight = weight;
		s -> next = G -> adjlist[n1].firstedge;
		G -> adjlist[n1].firstedge = s;
	}
	return G;
}

//获取位置
int getPosition(AdjList *G, char c)
{
	int m;
	for (m = 1; m <= G -> vexnum; m ++) 
		if (G -> adjlist[m].vertex == c)
			return  m;
	return 1;
}

//获取G中边<start, end>的权值;若start和end不是连通的,则返回无穷大。
int get_weight(AdjList *G, int start, int end)
{
	ArcNode *node;

	if (start == end)
		return 0;

	node = G -> adjlist[start].firstedge;
	while (node != NULL)
	{
		if (end == node -> adjvex)
			return node -> weight;
		node = node -> next;
	}
	return INFINE;
}

/*
* 迪杰斯特拉算法求最短路径。统计图(G)中"顶点vs"到其它各个顶点的最短路径。
* 参数说明:
* G -- 邻接图
* vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
* prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
* dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
*/
void Dijkstra(AdjList *G, int vs, int prev[], int dist[], char over)
{
	int i, j, k, t,m;
	int min;
	int tmp;
	int flag[INFINE];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。
	int path[MAXLEN][MAXLEN]={0};
	// 初始化
	for (i = 1; i <= G->vexnum; i++)
	{
		flag[i] = 0;                     // 顶点i的最短路径还没获取到。
		prev[i] = 0;                     // 顶点i的前驱顶点为0。
		dist[i] = get_weight(G, vs, i);  // 顶点i的最短路径为"顶点vs"到"顶点i"的权。
		path[i][0] = 0;
	}
	// 对"顶点vs"自身进行初始化
	flag[vs] = 1;
	dist[vs] = 0;
	path[vs][0] =1;
	// 遍历G->vexnum-1次;每次找出一个顶点的最短路径。
	for (i = 2; i <= G->vexnum; i++)
	{
		// 寻找当前最小的路径,即在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
		t = 0;
		min = INFINE;
		for (j = 1; j <= G->vexnum; j++)
			if (flag[j] == 0 && dist[j]<min)
				min = dist[j], k = j;

		// 标记"顶点k"为已经获取到最短路径
		flag[k] = 1;
		// 修正当前最短路径和前驱顶点,即当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
		for (j = 1; j <= G->vexnum; j++)
		{
			tmp = get_weight(G, k, j);
			tmp = (tmp == INFINE ? INFINE : (min + tmp)); // 防止溢出
			if (flag[j] == 0 && (tmp  < dist[j]))
			{
				dist[j] = tmp;
				prev[j] = k;
				path[j][t] = k;
				t++;
			}
		}
	}
	// 打印dijkstra最短路径的结果
	for (i = 1; i <= G -> vexnum; i++)
	{
		if(G -> adjlist[i].vertex == over) 
		{
			cout << G -> adjlist[vs].vertex << "到" << over << "的最短路径长度为:" << dist[i];

			int showpath[MAXLEN] = {0};//存储最短路径上的节点
			for (m = 0; m < G->vexnum; m++)
			{
				if (path[i][m] == 0|| G->adjlist[path[i][m]].vertex == G->adjlist[vs].vertex) break;
				showpath[m] = path[i][m];
			}
//		//以下用于拼接路径
			if (dist[i]!= INFINE)
			{
				cout << endl << "当前最短路径为:" << G->adjlist[vs].vertex << "->";
				for (int q = MAXLEN - 1; q >= 0; q--)//存入的中间节点是【距离原点最远的顶点】依次递减存入的,故需逆序输出
				{
					if (showpath[q] == 0) continue;
					cout << G -> adjlist[showpath[q]].vertex << "->";
				}
				cout << G -> adjlist[i].vertex << endl;
			}
		}
	}

}

int main()
{
	while(scanf("%d%d", &n, &m) != EOF)
	{
	    AdjList G;
	    char start1, over1;
	    int ps;
	    int dist[MAXLEN], prev[MAXLEN];
	    AdjList *G2 = Created_Graph(&G);//创建表
	    cin >> start1 >> over1;
	    ps = getPosition(G2, start1);//获取起点位置
	    Dijkstra(G2, ps, prev, dist, over1);
	}
	return 0;
}

O autor tem algo a dizer

Se precisar do código, envie uma mensagem privada ao blogueiro e ele responderá após vê-lo.

Se você acha que o que o blogueiro disse é útil para você, clique em "Seguir" para apoiá-lo. Continuaremos atualizando essas questões...

 

Acho que você gosta

Origin blog.csdn.net/weixin_62075168/article/details/128167492
Recomendado
Clasificación