private void BtnBuscar_Click(object sender, EventArgs e) //Método chamado no evento click do btnBuscar { MessageBox.Show("Buscar caminhos entre cidades selecionadas"); //Mensagem mandada ao usuário ao clique do botão btnBuscar pbMapa.Refresh(); //Método que "limpa" o mapa, apagando o caminho que possivelmente estava sendo exibido antes dataGridView1.Rows.Clear(); //Método que apaga as linhas populadas com o caminho escolhido anteriormente peo usuário dataGridView2.Rows.Clear(); //Método que apaga as linhas populadas com o caminho escolhido anteriormente peo usuário dataGridView2.Columns.Clear(); //Método que deleta as colunas antes exibidas no dataGridView PilhaLista <Caminho> aux2 = new PilhaLista <Caminho>(); //Declaração e instanciação da pilha de caminhos que guardará todos os caminhos encontrados que levarão ao destino desejado PilhaLista <Caminho> caminhos = new PilhaLista <Caminho>(); //Declaração e instanciação da pilha de caminhos que guardará todos os possíveis caminhos, cada rota que possivelmente levará ao destino escolhido PilhaLista <Caminho> aux = new PilhaLista <Caminho>(); //Declaração e instanciação da pilha de caminhos que inicialmente guardará todos os caminhos que tem como início a origem determinada int qtdCaminhos = 0; //Variável que guarda o número de caminhos encontrados, usada mais tarde na instanciação do vetor de caminhos int atual = lsbOrigem.SelectedIndex; //Variável que guarda o índice da cidade escolhida pelo usuário como origem bool acabouCaminho = false; //Variável que guarda 'true' se a cidade destino foi alcançada ou 'false' caso não bool[] visitados = new bool[arvore.QuantosDados]; //Vetor do tipo boolean que guardará true sempre que a cidade correspondente foi verificada/visitada e false em caso contrário int nCidades = 0; //Variável que guarda o número de cidades que o caminho com maior cidades contém int menorCaminho = Int32.MaxValue; //Variável que guarda a menor distância encontrada int distancia; //Variável que guarda a distância percorrida no caminho atualmente analisado string[] nomeMelhor = new string[arvore.QuantosDados]; //Vetor de string que guarda os nomes das cidades contidas no melhor caminho encontrado vetorCaminhos = new object[100]; int qtd = arvore.QuantosDados; //Variável que guarda a quantidade de cidades contidas na árvore criada while (!acabouCaminho) //Loop definido pela verificação do encontro ou não de um caminho { distancia = 0; bool empilhou = false; //Variável boolean que verifica se algum caminho foi empilhado com a origem atual for (int c = 0; c < qtd; c++) //Loop que se repete pelo número de cidades existentes { if (matriz[atual, c] != default(int)) //Verificação: se o valor da posição atual da matriz é diferente de 0, ou seja, se entre os índices(cidades) definidos existe uma rota { aux.Empilhar(new Caminho(atual, c, matriz[atual, c])); //Caso exista uma rota entre essas cidades, essa será empilhada na pilha empilhou = true; //Atribuição de valor true para a variável 'empilhou', já que um posssível caminho foi encontrado } } if (!empilhou) //Verificação: se nenhum possível caminho foi encontrado desta vez { if (!aux.EstaVazia()) //se a pilha aux não estiver vazia { while (!aux.EstaVazia() && !caminhos.EstaVazia() && aux.OTopo().Origem != caminhos.OTopo().Destino) //se a pilha "aux" e a pilha "caminhos" não estiverem vazia e a origem do topo de "aux" for diferente da origem do topo de "caminhos" { caminhos.Desempilhar(); //Caso nada tenha sido empilhado, devemos desempilhar da pilha caminhos até que a origem do caminho no topo da pilha aux seja igual ao destino do caminho do topo da pilha caminhos } } } if (aux.EstaVazia()) //Verificação: se a pilha aux não tiver elementos, então não é possível prosseguir a procura por um caminho { acabouCaminho = true; //Portanto, para sair do loop, a variável acabouCaminho recebe true } else //Caso a pilha aux não esteja vazia, a busca por um caminho deve presseguir { Caminho um = aux.Desempilhar(); //Variável local que guarda o caminho analisado atualmente if (um.Destino == lsbDestino.SelectedIndex) //Verificação: se um caminho foi encontrado { caminhos.Empilhar(um); //Empilha na pilha "caminhos" if (caminhos.Tamanho() > nCidades) //Se o tamanho da pilha "caminhos" atual, a quantidade de cidades, for maior do que a maior quantidades de cidades em um caminho ("nCidades") { nCidades = caminhos.Tamanho(); //A quantidade máxima de cidades em um caminho recebe a quantidade de cidades no caminho atual } aux2 = caminhos.Clone().Inverter(); //A pilha "aux2" recebe o clone da pilha "caminhos" invertida if (!aux.EstaVazia()) //se a pilha aux não estiver vazia { while (!aux.EstaVazia() && !caminhos.EstaVazia() && aux.OTopo().Origem != caminhos.OTopo().Destino) //se a pilha "aux" e a pilha "caminhos" não estiverem vazia e a origem do topo de "aux" for diferente da origem do topo de "caminhos" { caminhos.Desempilhar(); //Caso nada tenha sido empilhado, devemos desempilhar da pilha caminhos até que a origem do caminho no topo da pilha aux seja igual ao destino do caminho do topo da pilha caminhos } } caminhos.Empilhar(um); atual = um.Destino; //variável atual recebe o destino do topo de "aux" int i = 0; //Variável que armazena o indíce dos vetores dataGridView1.RowCount++; //Aumenta a quantidade de linhas do DataGridView dataGridView1.ColumnCount = nCidades + 1; //A quantidade de colunas do DataGridView recebe o maior número de cidades de todos os caminhos possíveis double?[] cod = new double?[arvore.QuantosDados]; //Representa um vetor que armazena os códigos de todas as cidades do caminho atual em ordem string[] nomes = new string[arvore.QuantosDados]; //Representa um vetor que armazena os nomes de todas as cidades do caminho atual em ordem Caminho c = new Caminho(); //Representa a rota atual while (!aux2.EstaVazia()) //Enquanto a pilha "aux2" estiver vazia { c = aux2.Desempilhar(); //A rota atual recebe o topo de "aux2" e desempilha esta Cidade cid = arvore.BuscaPorDado(new Cidade(c.Origem)); //Representa a cidade de origem da rota atual nomes[i] = cid.Nome; //Armazena o nome desta cidade na posição atual do vetor de nomes cod[i] = cid.Cod; //Armazena o codigo desta cidade na posição atual do vetor de códigos distancia += c.Distancia; //A distância total do caminho soma a distância da rota atual dataGridView1[i++, dataGridView1.RowCount - 1].Value = cid.Nome; //"Escreve" o nome da cidade atual no DataGridView } nomes[i] = (arvore.BuscaPorDado(new Cidade(c.Destino))).Nome; //Guarda o nome da última cidade no vetor de nomes cod[i] = (arvore.BuscaPorDado(new Cidade(c.Destino))).Cod; //Guarda o codigo da última cidade no vetor de códigos dataGridView1[i, dataGridView1.RowCount - 1].Value = nomes[i]; //"Escreve" o nome da última cidade no DataGridView if (distancia < menorCaminho) //Verificação: se a distância percorrida nesse caminho for menor que a menor distância já encontrada { menorCaminho = distancia; //A variável menorCaminho passa a guardar a distância atual melhorCaminho = cod; //Como a distância atual é a menor encontrada, o melhor caminho passa a ser o atual, portanto o valor do vetor de códigos melhorCaminho recebe o vator de códigos atual nomeMelhor = new string[i]; //Instanciação do vetor que guarda os nomes das cidades que o caminho atual contém nomeMelhor = nomes; //Atribuição do vetor de nomes das cidades percorridas neste caminho ao vetor que guarda nomes de cidades pelas quais passa o melhor caminho } //Caso não seja menor, nada acontece, para que a variável contenha o menor valor de todos corretamente vetorCaminhos[qtdCaminhos] = cod; //Atribuição do vetor de códigos atual à posição atual do vetorCaminhos, para que este guarde os códigos das cidades percorridas nesse caminho qtdCaminhos++; //Acrescentamos uma unidade à variável qtdCaminhos } else { caminhos.Empilhar(um); //Ao acharmos uma possível rota, ela é guardada na pilha de possíveis rotas atual = um.Destino; //Mudamos o valor da variável atual, que passará a guardar a origem do caminho que será verificado posteriormente } } } if (qtdCaminhos == 0) //Caso a quantidade de caminhos encontrados seja zero, não existe uma rota entre as cidades escolhidas, portanto, alertamos o usuário { MessageBox.Show("Não existe caminho!"); //Mensagem exibida ao usuário para alertá-lo da inexistência de caminhos } else //Caso a quantidade de caminhos encontrados não seja zero, achamos pelo menos um caminho { ExibirMelhorCaminho(nomeMelhor); //Chamada de método para exibir o melhor caminho encontrado } }