示例#1
0
        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
            }
        }