예제 #1
0
        private void Form1_Load(object sender, EventArgs e)
        {
            caminhoADesenhar    = new PilhaLista <Caminho>();
            caminhosDescobertos = new PilhaLista <PilhaLista <Caminho> >();
            arvore = new Arvore <Cidade>();
            var arq = new StreamReader(@"CidadesMarte.txt", Encoding.UTF7);

            while (!arq.EndOfStream)
            {
                var c = new Cidade(arq.ReadLine());
                dadosCidade[c.IdCidade] = c;
                qtosDados++;
            }

            arq.Close();

            NoArvore <Cidade> primeiroNo = null;

            ParticionarVetorEmArvore(0, qtosDados - 1, ref primeiroNo);
            arvore.Raiz = primeiroNo;
            pnlArvore.Invalidate();

            for (int i = 0; i < qtosDados; i++)
            {
                lsbOrigem.Items.Add($"{dadosCidade[i].IdCidade} - {dadosCidade[i].NomeCidade}");
                lsbDestino.Items.Add($"{dadosCidade[i].IdCidade} - {dadosCidade[i].NomeCidade}");
            }

            CriarGrafo();
            pbMapa.Invalidate();
        }
예제 #2
0
        //método não é mais utilizado por conta de usarmos o ordenar caminhos, que deixa o melhor caminho sempre na primeira posição
        private PilhaLista <int> SelecionarMelhorCaminho()           //retorna um inteiro o qual é o índice do melhor caminho guardado para a cidade desejada
        {
            PilhaLista <int> melhorCaminho = new PilhaLista <int>(); //criamos uma nova pilha a qual será retornada no final do método contendo o melhor caminho possível
            int distanciaTotal             = 0;                      //distanciaTotal receberá a soma da distância percorrida em um caminho
            int menorDistancia             = int.MaxValue;           //menorDistância será usada para definir qual caminho utilizar, comparando as distâncias entre dois caminhos

            foreach (var caminho in caminhosPossiveis)
            {
                distanciaTotal = 0;
                var aux      = caminho.Clone();
                int anterior = aux.Desempilhar(); //variável que será utilizada como a origem, em qual cidade se está atualmente

                //enquanto ainda houver cidades a serem percorridas
                while (!aux.EstaVazia())
                {
                    int cidade = aux.Desempilhar();//desempilharemos o id de uma cidade
                    //somaremos o valor de distância da cidade que teve o id desempilhado através da matriz adjacências
                    //que possue como valor a distância a ser percorrida de seu ponto de origem até seu ponto de destino
                    distanciaTotal += adjacencias[cidade, anterior];
                    anterior        = cidade; //fazemos com que a variável de origem receba o destino, de certa forma como se o usuário tivesse percorrido o caminho até a cidade
                }


                //se a menorDistancia for maior do que a do caminhoPercorrido
                //o caminhoPercorrido pelo programa torna-se o melhorCaminho
                if (menorDistancia > distanciaTotal)
                {
                    menorDistancia = distanciaTotal;
                    melhorCaminho  = caminho.Clone();
                }
            }
            return(melhorCaminho);
        }
예제 #3
0
        void ExibirCaminhos(PilhaLista <PilhaLista <Caminho> > caminhos)
        {
            dgvCaminhos.Rows.Clear();
            dgvCaminhos.RowCount    = caminhos.Tamanho();
            dgvCaminhos.ColumnCount = 10;
            var pilhaCopia = caminhos.Copia();

            Color[] cores = { Color.Black, Color.Blue, Color.Red, Color.Green, Color.Orange, Color.Purple, Color.Navy, Color.Brown };

            for (int i = 0; i < dgvCaminhos.RowCount; i++)
            {
                PilhaLista <Caminho> pcAtual = caminhos.Desempilhar();
                var aux = new PilhaLista <Caminho>();

                while (!pcAtual.EstaVazia())
                {
                    aux.Empilhar(pcAtual.Desempilhar());
                }

                int     c      = 0;
                Caminho cAtual = null;
                dgvCaminhos.Rows[i].DefaultCellStyle.ForeColor = Color.White;

                dgvCaminhos.Rows[i].DefaultCellStyle.BackColor = cores[i];
                while (!aux.EstaVazia())
                {
                    cAtual = aux.Desempilhar();
                    dgvCaminhos.Rows[i].Cells[c].Value = dadosCidade[cAtual.IdCidadeOrigem].NomeCidade;
                    c++;
                }
                dgvCaminhos.Rows[i].Cells[c].Value = dadosCidade[cAtual.IdCidadeDestino].NomeCidade;
            }
            caminhosDescobertos = pilhaCopia;
            pbMapa.Invalidate();
        }
예제 #4
0
        void ExibirMelhorCaminho(PilhaLista <Caminho> caminho, int cor)
        {
            dgvMelhorCaminho.Rows.Clear();
            dgvMelhorCaminho.RowCount    = 1;
            dgvMelhorCaminho.ColumnCount = 10;
            var     pilhaCopia   = caminho.Copia();
            Caminho caminhoAtual = null;
            PilhaLista <Caminho> pilhaCopiaAux = new PilhaLista <Caminho>();

            while (!pilhaCopia.EstaVazia())
            {
                pilhaCopiaAux.Empilhar(pilhaCopia.Desempilhar());
            }

            corAtual      = 2;
            melhorCaminho = pilhaCopiaAux.Copia();
            int c = 0;

            while (!pilhaCopiaAux.EstaVazia())
            {
                caminhoAtual = pilhaCopiaAux.Desempilhar();
                dgvMelhorCaminho.Rows[0].Cells[c].Value = dadosCidade[caminhoAtual.IdCidadeOrigem].NomeCidade;
                c++;
            }
            dgvMelhorCaminho.Rows[0].Cells[c].Value = dadosCidade[caminhoAtual.IdCidadeDestino].NomeCidade;
        }
예제 #5
0
        // Evento click do botão que irá obter as cidades escolhidas pelo usuário e chamará o método de busca de caminhos
        private void BtnBuscar_Click(object sender, EventArgs e)
        {
            int idOrigem  = GetOrigem();
            int idDestino = GetDestino();

            if (idOrigem == -1 || idDestino == -1)
            {
                MessageBox.Show("Cidades inválidas");
                return;
            }

            if (idOrigem == idDestino)
            {
                MessageBox.Show("Destino é igual à origem!");
                return;
            }

            caminhos = grafo.ProcurarCaminhos(idOrigem, idDestino);
            if (caminhos.GetQtd() == 0)
            {
                MessageBox.Show("Nenhum caminho foi encontrado!");
            }
            else
            {
                MessageBox.Show("Número de caminhos encontrados: " + caminhos.GetQtd().ToString());
            }

            LimparDados();
            if (caminhos.GetQtd() > 0)
            {
                ExibirCaminhos();
                ExibirMelhorCaminho();
            }
        }
예제 #6
0
 private void DesenharCaminho(PilhaLista <CaminhoEntreCidades> caminho)
 {
     // cria um novo gráfico sobre o pictureBox
     g = pbMapa.CreateGraphics();
     //redesenha as cidades nas coordenadas corretas
     arvoreCidades.DesenharMapa(arvoreCidades.Raiz, g);
     // atualiza
     pbMapa.Refresh();
     while (!caminho.EstaVazia) // percorre o caminho
     {
         var atual = caminho.OTopo();
         // resgata e instancia as cidades de origem e destino de cada passo
         Cidades origem  = arvoreCidades.GetDado(new Cidades(atual.IdCidadeOrigem));
         Cidades destino = arvoreCidades.GetDado(new Cidades(atual.IdCidadeDestino));
         // instancia-se caneta para desenhar as linhas
         Pen pen = new Pen(Color.DarkRed, 2); // cor: vermelho escuro - espessura = 2px
         pen.StartCap = LineCap.RoundAnchor;  // bolinha no início da seta (origem)
         pen.EndCap   = LineCap.ArrowAnchor;  // seta no fim da reta (destino)
         //pontos de coordenadas da origem e do destino
         PointF pOrigem  = new PointF(origem.CoordenadaX / 4 + 5, origem.CoordenadaY / 4 + 5);
         PointF pDestino = new PointF(destino.CoordenadaX / 4 + 5, destino.CoordenadaY / 4 + 5);
         g.DrawLine(pen, pOrigem, pDestino); // desenha a linha
         caminho.Desempilhar();
     }
     // atualiza graphic
     g.Dispose();
 }
예제 #7
0
        // Método que desenha no picture box, o caminho selecionado pelo usuário
        private void DesenharCaminho(PilhaLista <Movimento> umCaminho)
        {
            pbMapa.Refresh();
            No <Movimento> umMovimento = umCaminho.Inicio;

            while (umMovimento != null)
            {
                var pontoInicial = arvoreCidades.GetCidade(umMovimento.Info.Origem);
                var pontoFinal   = arvoreCidades.GetCidade(umMovimento.Info.Destino);

                double x  = pontoInicial.X;
                double y  = pontoInicial.Y;
                double xf = pontoFinal.X;
                double yf = pontoFinal.Y;

                GetProporcao(ref x, ref y);
                GetProporcao(ref xf, ref yf);

                Pen caneta = new Pen(Color.Red);
                caneta.Width = 3;

                Graphics g = pbMapa.CreateGraphics();

                g.FillEllipse(new SolidBrush(Color.Black), Convert.ToInt32(x - 5), Convert.ToInt32(y - 5), 10, 10);
                g.DrawLine(caneta, Convert.ToInt32(x), Convert.ToInt32(y), Convert.ToInt32(xf), Convert.ToInt32(yf));
                g.DrawString(pontoInicial.NomeCidade.Trim(), new Font("Comic Sans", 10, FontStyle.Bold), new SolidBrush(Color.Black), Convert.ToInt32(x - 10), Convert.ToInt32(y - 20));
                g.DrawString(pontoFinal.NomeCidade.Trim(), new Font("Comic Sans", 10, FontStyle.Bold), new SolidBrush(Color.Black), Convert.ToInt32(xf - 10), Convert.ToInt32(yf - 20));
                g.FillEllipse(new SolidBrush(Color.Black), Convert.ToInt32(xf - 5), Convert.ToInt32(yf - 5), 10, 10);

                umMovimento = umMovimento.Prox;
            }
        }
예제 #8
0
 private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e) //quando uma célula específica do dgv receber foco de entrada
 {
     //utilizamos o index da linha para encontrar a qual caminho ela se refere
     //pois os index do dgv estão de acordo com a List caminhos possíveis
     caminhoASerMostrado = caminhosPossiveis[int.Parse(e.RowIndex.ToString())].Clone();
     //permissão para redesenhar o mapa
     pbMapa.Invalidate();
 }
예제 #9
0
        private void BtnBuscar_Click(object sender, EventArgs e)
        {
            if (lsbOrigem.SelectedIndex == -1 || lsbDestino.SelectedIndex == -1)
            {
                MessageBox.Show("Selecione as cidades de origem e destino!");
            }
            else
            {
                grafo.ProcurarCaminhos(lsbOrigem.SelectedIndex, lsbDestino.SelectedIndex);

                dgvCaminhos.RowCount      = grafo.Caminhos.Count;
                dgvMelhorCaminho.RowCount = (dgvCaminhos.RowCount > 0 ? 1 : 0);
                var melhorCaminho = grafo.MelhorCaminho;

                pontosAUnir = new List <Point>();

                for (int i = 0; i < grafo.Caminhos.Count; i++)
                {
                    PilhaLista <Cidade> aux = new PilhaLista <Cidade>();

                    for (int j = 0; !grafo.Caminhos[i].EstaVazia(); j++)
                    {
                        if (grafo.Caminhos[i] == melhorCaminho) // Coloca os nomes das cidades no DataGridView de melhor caminho
                        {
                            var cidade = grafo.Caminhos[i].OTopo();

                            if (dgvMelhorCaminho.ColumnCount < j + 1) // Aumenta a quantidade de colunas no DataGridView de melhor caminho se necessário
                            {
                                dgvMelhorCaminho.ColumnCount = j + 1;
                            }

                            dgvMelhorCaminho.Rows[0].Cells[j].Value = cidade.NomeCidade;
                        }

                        if (dgvCaminhos.ColumnCount < j + 1) // Aumenta a quantidade de colunas no DataGridView de caminhos se necessário
                        {
                            dgvCaminhos.ColumnCount = j + 1;
                        }

                        dgvCaminhos.Rows[i].Cells[j].Value = grafo.Caminhos[i].OTopo().NomeCidade;
                        aux.Empilhar(grafo.Caminhos[i].Desempilhar());
                    }
                    while (!aux.EstaVazia()) // Restaura a pilha do caminho, para que possa ser reutilizada
                    {
                        grafo.Caminhos[i].Empilhar(aux.Desempilhar());
                    }
                }

                AtualizarPontosAUnir();
                pbArvore.Invalidate();

                if (grafo.Caminhos.Count == 0)
                {
                    MessageBox.Show("Não há caminhos!");
                }
            }
        }
예제 #10
0
 private void dgvMenorCaminho_CellClick(object sender, DataGridViewCellEventArgs e)
 {
     // ao selecionar a linha do menor caminho
     dgvCaminhos.ClearSelection();
     if (menorCaminho != null)
     {
         PilhaLista <CaminhoEntreCidades> caminho = menorCaminho.Copia(); // faz-se cópia para não estragar
         DesenharCaminho(caminho);                                        // desenhar o menor caminho no mapa
     }
 }
예제 #11
0
        private void BtnBuscar_Click(object sender, EventArgs e)
        {
            //verificamos se duas cidades foram selecionadas, caso contrário avisamos o usuário
            if (lsbOrigem.SelectedItem != null && lsbDestino.SelectedItem != null)
            {
                //pegamos o índice das cidades de origem e destino disponíveis nos lsbs
                int idCidadeOrigem  = Int32.Parse(lsbOrigem.SelectedIndex.ToString().Split('-')[0]);
                int idCidadeDestino = Int32.Parse(lsbDestino.SelectedIndex.ToString().Split('-')[0]);

                //verificamos se origem e destino são iguais
                if (idCidadeOrigem == idCidadeDestino)
                {
                    MessageBox.Show("Seu ponto de partida é o mesmo que o seu destino!");
                }
                else
                {
                    //instanciamos as variáveis que serão utilizadas neste método
                    cidadesPercorridas = new bool[cidades.QuantosDados];
                    caminhosPossiveis  = new List <PilhaLista <int> >();
                    caminho            = new PilhaLista <int>();
                    percorreuTodosOsCaminhosPossiveis = false;

                    //chamamos o método buscarCaminhos com base no destino desejado e na cidade de origem
                    BuscarCaminhos(idCidadeOrigem, idCidadeDestino, 0);

                    //enquanto houver caminhos a serem percorridos, voltamos uma posição(uma cidade) e chamamos o método Retornar
                    //este método chamará novamente BuscarCaminhos, desempilhando uma cidade
                    //ou seja, voltando uma posição para verificar a existência de outros caminhos para o mesmo local
                    while (!percorreuTodosOsCaminhosPossiveis)
                    {
                        int idOrigem = caminho.Desempilhar();
                        Retornar(idOrigem, idCidadeDestino);
                    }
                    //o caminho a ser mostrado(desenhado) por padrão será o do index 0 do dgv, pois de acordo com a ordenação, este trata-se do melhor caminho
                    if (caminhosPossiveis.Count > 0)
                    {
                        //ordenamos os caminhos encontrados do melhor para o pior
                        OrdenarCaminhos();
                        //exibimos os caminhos no gridView
                        ExibirCaminhos();
                        caminhoASerMostrado = caminhosPossiveis[0].Clone();
                    }
                    else
                    {
                        MessageBox.Show("Não há caminhos");
                    }
                    //permitimos que o mapa seja redesenhado
                    pbMapa.Invalidate();
                }
            }
            else
            {
                MessageBox.Show("Por favor selecione uma origem e um destino");
            }
        }
예제 #12
0
        private void DesenharCaminho(PilhaLista <int> caminho, Graphics g) //desenha com base em um caminho selecionado nos DGVs ou com base no melhorCaminho
        {
            //classe que será utilizada para desenhar
            Pen caneta = new Pen(Color.Black);

            caneta.Width = 2.0F;

            //desempilhamos de caminho uma id de uma cidade, verificando sua existência na árvore de cidades
            // caso exista, a variável cidadeAnterior receberá todas as informações desta cidade
            int idCidadeAnterior = caminho.Desempilhar();

            cidades.Existe(new Cidade(idCidadeAnterior, " ", 0, 0));
            Cidade cidadeAnterior = cidades.Atual.Info;

            //enquanto houver cidades a serem percorridas
            while (!caminho.EstaVazia())
            {
                //desempilhamos de caminho uma id de uma cidade, verificando sua existência na árvore de cidades
                // caso exista, a variável cidade receberá todas as informações desta cidade
                int idCidade = caminho.Desempilhar();
                cidades.Existe(new Cidade(idCidade, " ", 0, 0));
                Cidade cidade = cidades.Atual.Info;

                //refazemos as proporções do mapa de acordo com as coordenadas da cidade
                int x1 = (cidadeAnterior.CoordenadaX * pbMapa.Width) / 4096;
                int y1 = (cidadeAnterior.CoordenadaY * pbMapa.Height) / 2048 + 3;

                //refazemos as proporções do mapa de acordo com as coordenadas da cidade
                int x2 = (cidade.CoordenadaX * pbMapa.Width) / 4096;
                int y2 = (cidade.CoordenadaY * pbMapa.Height) / 2048 + 3;

                // caso a distância entre x1 e x2 seja maior que a distância "por trás",
                // deve -se desenhar as retas entre as cidades passando por trás
                // (por exemplo Gondor e Arrakeen
                if (x1 - x2 > (pbMapa.Width - x1) + x2)
                {
                    g.DrawLine(caneta, x1, y1, pbMapa.Width, (y1 + y2) / 2);
                    g.DrawLine(caneta, x2, y2, 0, (y1 + y2) / 2);
                }
                else if (x2 - x1 > (pbMapa.Width - x2) + x1)
                {
                    g.DrawLine(caneta, x1, y1, 0, (y1 + y2) / 2);
                    g.DrawLine(caneta, x2, y2, pbMapa.Width, (y1 + y2) / 2);
                }
                //se não for o caso da linha ter de passar por trás
                else
                {
                    //desenhamos uma linha entre as duas cidades, cidadeAnterior representando a posição atual, e cidade representando aonde é necessário ir
                    g.DrawLine(caneta, x1, y1, x2, y2); //utilizando as localizações "x" e "y" das cidades
                }

                //fazemos com que o destino se torne a origem, para refazer o processo
                cidadeAnterior = cidade;
            }
        }
예제 #13
0
        private void dgvCaminhos_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            // ao selecionar uma linha do dgv (um caminho)
            dgvMenorCaminho.ClearSelection();
            int idCaminho = e.RowIndex; // index da linha selecionada

            if (listaCaminhos[0] != null)
            {
                PilhaLista <CaminhoEntreCidades> caminho = listaCaminhos[idCaminho].Copia(); // faz-se cópia para não estragar
                DesenharCaminho(caminho);                                                    // desenhar o caminho no mapa
            }
        }
예제 #14
0
        private void dgvCaminhos_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            int selecionado = e.RowIndex;
            var aux         = caminhosDescobertos.Copia();

            for (int i = 0; i <= selecionado; i++)
            {
                caminhoADesenhar = aux.Desempilhar();
            }
            corAtual = selecionado;
            pbMapa.Invalidate();
        }
예제 #15
0
        public void encontrarCaminho(int idCidadeDestino, int idCidadeOrigem, int idAtual)
        {
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //CALCULA TODOS OS CAMINHOS POSSIVEIS E OS ARMAZENA NO LIST todosCaminho
            if (idCidadeDestino == idCidadeOrigem)          // Caso a cidade origem seja igual a cidade destino
            {
                caminhoPossivel.Empilhar(idCidadeDestino);
                todosCaminhos.Add(caminhoPossivel.Clone());
                achou = true;
            }
            else
            {
                for (int i = 0; i <= 22; i++)
                {
                    if (caminhos[idAtual, i] != null && !visitadados.Contains(caminhos[idAtual, i])) // Verifica se o caminho atual já foi percorrido ou seja diferente
                    {                                                                                // de null, caso isso ocorra ele continua com a busca de caminhos
                        caminhoPossivel.Empilhar(idAtual);
                        if (i == idCidadeDestino)                                                    // caso a cidadeDestino seja encontrada
                        {
                            caminhoPossivel.Empilhar(i);

                            todosCaminhos.Add(caminhoPossivel.Clone()); //CaminhoPossivel é armazenado em todosCaminhos

                            while (!caminhoPossivel.EstaVazia())        // Desempilha o caminhoPossivel para tentar encontrar ou caminho
                            {
                                caminhoPossivel.Desempilhar();
                            }

                            visitadados.Add(caminhos[idAtual, i]); // Adiciona o caminho atual nos visitados para que ele não seja percorrido de novo

                            achou = true;
                            encontrarCaminho(idCidadeDestino, idCidadeOrigem, idCidadeOrigem); // O método é chamado novamente de forma recurssiva
                        }                                                                      // para verificar se existe outro caminho possivel
                        else
                        {
                            PilhaLista <int> caminhoPossivelAux = caminhoPossivel.Clone();
                            caminhoPossivelAux.Desempilhar();

                            encontrarCaminho(idCidadeDestino, idCidadeOrigem, i); // Caso o caminhoAtual não seja igual ao caminhoDestino

                            caminhoPossivel = caminhoPossivelAux;                 //
                        }
                    }
                    if (i == 22)                             // caso não tenha sido achodo nenhum caminho e o for tenha chegado ao fim .
                    {
                        while (!caminhoPossivel.EstaVazia()) // limpa a variavel caminhoPossivel desempilhando ela
                        {
                            caminhoPossivel.Desempilhar();
                        }
                    }
                }
            }
        }
예제 #16
0
        // Método que retorna uma pilha de Movimento a partir de um vetor de Movimento
        private PilhaLista <Movimento> GetPilha(Movimento[] percurso)
        {
            var pilhaLista = new PilhaLista <Movimento>();

            for (int i = 0; i < percurso.Length - 1; i++)
            {
                var lc = grafoBacktracking.GetLigacaoEntreCidades(percurso[i].Origem, percurso[i + 1].Origem);
                pilhaLista.Empilhar(new Movimento(percurso[i].Origem, percurso[i + 1].Origem, lc));
            }

            return(pilhaLista);
        }
예제 #17
0
        /*
         * Evento paint do pictureBox mapa que exibirá as cidades e os caminhos. Desenha os pontos em cada cidade, seguindo
         * PreOrdem da Árvore. Também exibe um caminho selecionado pelo usuário caso ele não seja negativo.
         */
        private void pbMapa_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            arvore.PreOrdem((Cidade c) =>
            {
                float coordenadaX = c.CoordenadaX * pbMapa.Width / TAMANHOX;
                float coordenadaY = c.CoordenadaY * pbMapa.Height / TAMANHOY;
                g.FillEllipse(
                    new SolidBrush(Color.Black),
                    coordenadaX, coordenadaY, 10f, 10f
                    );
                g.DrawString(c.Nome, new Font("Courier New", 8, FontStyle.Bold),
                             new SolidBrush(Color.FromArgb(32, 32, 32)), coordenadaX + 12, coordenadaY - 10);
            });

            if (selecionado >= 0)
            {
                PilhaLista <Caminho> aux = listaCaminhos[selecionado].Clone();

                while (!aux.EstaVazia())
                {
                    Caminho possivelCaminho = aux.Desempilhar();

                    Cidade origem  = arvore.ExisteDado(new Cidade(possivelCaminho.IdOrigem));
                    Cidade destino = arvore.ExisteDado(new Cidade(possivelCaminho.IdDestino));
                    using (var pen = new Pen(Color.FromArgb(211, 47, 47), 2))
                    {
                        int origemX  = origem.CoordenadaX * pbMapa.Width / TAMANHOX + 5;
                        int origemY  = origem.CoordenadaY * pbMapa.Height / TAMANHOY + 5;
                        int destinoX = destino.CoordenadaX * pbMapa.Width / TAMANHOX + 5;
                        int destinoY = destino.CoordenadaY * pbMapa.Height / TAMANHOY + 5;
                        AdjustableArrowCap flecha = new AdjustableArrowCap(5, 5);


                        if (destinoX - origemX > pbMapa.Width / 2)
                        {
                            g.DrawLine(pen, origemX, origemY, 0, origemY);
                            pen.CustomEndCap = flecha;
                            g.DrawLine(pen, pbMapa.Width, origemY, destinoX, destinoY);
                        }
                        else
                        {
                            pen.CustomEndCap = flecha;
                            g.DrawLine(pen, origemX, origemY, destinoX, destinoY);
                        }
                    }
                }
            }
        }
예제 #18
0
        // Método que obtém a distância total a ser percorrida em um determinado caminho
        private int ObterDistancia(PilhaLista <Movimento> umCaminho)
        {
            No <Movimento> aux       = umCaminho.Inicio;
            int            distancia = 0;

            while (aux != null)
            {
                distancia += aux.Info.Lc.Distancia;

                aux = aux.Prox;
            }

            return(distancia);
        }
예제 #19
0
        // Método que obtém o tempo total gasto em um determinado caminho
        private int ObterTempo(PilhaLista <Movimento> umCaminho)
        {
            No <Movimento> aux   = umCaminho.Inicio;
            int            tempo = 0;

            while (aux != null)
            {
                tempo += aux.Info.Lc.Tempo;

                aux = aux.Prox;
            }

            return(tempo);
        }
예제 #20
0
        // Método que obtém o custo necessário de um determinado caminho
        private int ObterCusto(PilhaLista <Movimento> umCaminho)
        {
            No <Movimento> aux   = umCaminho.Inicio;
            int            custo = 0;

            while (aux != null)
            {
                custo += aux.Info.Lc.Custo;

                aux = aux.Prox;
            }

            return(custo);
        }
예제 #21
0
        private void AcharCaminhos(int origem, int destino, int distanciaAcumulada) //origem == idCidadeOrigem || destino == idCidadeDestino
        {
            var cidadeOrigem = cidades.Find(c => c.IdCidade == origem);

            if (origem != destino) // Indica que ainda não chegou no destino
            {
                cidadeOrigem.FoiVisitado = true;

                for (int coluna = 0; coluna < cidades.Count; coluna++)
                {
                    if (!(matrizDeAdjacencias[origem, coluna] == 0 || cidades.Find(c => c.IdCidade == coluna).FoiVisitado)) // Se há caminho entre as cidades e a segunda ainda não foi visitada
                    {
                        if (caminho.EstaVazia() || caminho.OTopo().IdCidade != origem)
                        {
                            caminho.Empilhar(cidadeOrigem);
                        }
                        AcharCaminhos(coluna, destino, distanciaAcumulada + matrizDeAdjacencias[origem, coluna]);
                        caminho.Desempilhar(); // Desempilha para permitir que outros caminhos sejam encontrados
                    }
                }
            }
            else
            {
                caminho.Empilhar(cidades.Find(c => c.IdCidade == destino));

                var caminho2 = new PilhaLista <Cidade>();
                var aux      = new PilhaLista <Cidade>();

                while (!caminho.EstaVazia()) // Desempilha o caminho para inverter a pilha
                {
                    caminho2.Empilhar(caminho.OTopo());
                    aux.Empilhar(caminho.Desempilhar());
                }
                caminhos.Add(caminho2); // Armazena o caminho encontrado

                caminho = new PilhaLista <Cidade>();

                while (!aux.EstaVazia()) // Retorna as informações que foram colocadas numa pilha auxiliar à variavel "caminho"
                {
                    caminho.Empilhar(aux.Desempilhar());
                }

                distancias.Add(distanciaAcumulada); // Armazena a distância percorrida no caminho encontrado

                foreach (Cidade c in cidades)       // Desmarca as cidades para permitir que outros caminhos com trechos parecidos sejam encontrados
                {
                    c.FoiVisitado = false;
                }
            }
        }
예제 #22
0
        public void melhorCaminho() // Procura o menor caminho entre os caminhos do List todosCaminhos
        {
            int menorDistacia = -1;
            int i             = 0;

            for (i = 0; i < todosCaminhos.Count(); i++)
            {
                if (menorDistacia == -1 || menorDistacia > distancia(todosCaminhos[i]))
                {
                    menorDistacia = distancia(todosCaminhos[i]);
                    menorCaminho  = todosCaminhos[i].Clone();
                }
            }
        }
예제 #23
0
        //ao iniciar o programa
        private void Form1_Load(object sender, EventArgs e)
        {
            //limpamos os itens existentes nos lsbs
            lsbOrigem.Items.Clear();
            lsbDestino.Items.Clear();
            //instanciamos variáveis
            caminho = new PilhaLista <int>();
            cidades = new Arvore <Cidade>();

            //leitura do arquivo de cidades de acordo com o método feito na classe Cidade
            //incluimos as cidades na árvore de cidades
            StreamReader arq = new StreamReader("CidadesMarte.txt");

            while (!arq.EndOfStream)
            {
                Cidade cid = Cidade.LerArquivo(arq);
                cidades.Incluir(cid);
            }
            arq.Close();

            //lemos o arquivo ordenado para inclusão das cidades nos lsbs de origem e destino
            arq = new StreamReader("CidadesMarteOrdenado.txt");
            while (!arq.EndOfStream)
            {
                Cidade cid = Cidade.LerArquivo(arq);
                lsbOrigem.Items.Add(cid.IdCidade + "-" + cid.NomeCidade);
                lsbDestino.Items.Add(cid.IdCidade + "-" + cid.NomeCidade);
            }
            arq.Close();

            //criamos uma matriz de cidades de acordo com a quantidade de cidades existentes
            adjacencias = new int[cidades.QuantosDados, cidades.QuantosDados];
            //lemos o arquivo que nos passa os caminhos entre as cidades
            arq = new StreamReader("CaminhosEntreCidadesMarte.txt");

            //cria-se uma variável que recebe o caminho entre as cidades
            //guarda-se a distância do caminho na matriz de acordo com a cidade de origem e cidade de destino
            //[idOrigem, idDestino] == [x,y]
            while (!arq.EndOfStream)
            {
                CaminhoEntreCidades caminho = CaminhoEntreCidades.LerArquivo(arq);
                adjacencias[caminho.IdCidadeOrigem, caminho.IdCidadeDestino] = caminho.Distancia;
            }
            arq.Close();

            //pedimos para que o mapa seja redesenhado
            pbMapa.Invalidate();
        }
예제 #24
0
        void AcharMelhorCaminho(PilhaLista <PilhaLista <Caminho> > caminhos)
        {
            if (!caminhos.EstaVazia())
            {
                var   copiaAux   = caminhos.Copia();
                int[] distancias = new int[copiaAux.Tamanho()];
                int   i          = 0;
                while (!copiaAux.EstaVazia())
                {
                    var caminhoAux          = copiaAux.Desempilhar();
                    int distanciaPercorrida = 0;
                    while (!caminhoAux.EstaVazia())
                    {
                        var cidadeAux = caminhoAux.Desempilhar();
                        distanciaPercorrida += cidadeAux.Distancia;
                    }
                    distancias[i] = distanciaPercorrida;
                    i++;
                }

                int menor       = distancias[0];
                int indiceMenor = 0;
                for (int ii = 0; ii < distancias.Length; ii++)
                {
                    if (distancias[ii] < menor)
                    {
                        menor       = distancias[ii];
                        indiceMenor = ii;
                    }
                }

                //mostrar no gridView
                copiaAux = caminhos.Copia();
                PilhaLista <Caminho> caminhoAtual = null;
                for (int atual = 0; atual <= indiceMenor; atual++)
                {
                    caminhoAtual = copiaAux.Desempilhar();
                }

                ExibirMelhorCaminho(caminhoAtual, indiceMenor);
            }
        }
예제 #25
0
        // Método que exibe no dgvMelhorCaminho, o melhor caminho encontrado
        private void ExibirMelhorCaminho()
        {
            var rb = GetCriterio();

            switch (rb.Name)
            {
            case "rbDistancia": melhorCaminho = MelhorCaminhoDistancia();
                txtTotal.Text = ObterDistancia(melhorCaminho) + "";
                break;

            case "rbTempo": melhorCaminho = MelhorCaminhoTempo();
                txtTotal.Text             = ObterTempo(melhorCaminho) + "";
                break;

            case "rbCusto": melhorCaminho = MelhorCaminhoCusto();
                txtTotal.Text             = ObterCusto(melhorCaminho) + "";
                break;
            }

            dgvMelhorCaminho.RowCount    = 1;
            dgvMelhorCaminho.ColumnCount = melhorCaminho.GetQtd() + 1;
            InicializarColunas(dgvMelhorCaminho.ColumnCount, dgvMelhorCaminho);

            var umMovimento = melhorCaminho.Inicio;

            for (int col = 0; col < dgvMelhorCaminho.ColumnCount; col++)
            {
                if (umMovimento == null)
                {
                    break;
                }

                var primeiraCidade = arvoreCidades.GetCidade(umMovimento.Info.Origem);
                var segundaCidade  = arvoreCidades.GetCidade(umMovimento.Info.Destino);
                dgvMelhorCaminho[col, 0].Value     = primeiraCidade.NomeCidade;
                dgvMelhorCaminho[col + 1, 0].Value = segundaCidade.NomeCidade;

                umMovimento = umMovimento.Prox;
            }

            dgvMelhorCaminho.Refresh();
        }
예제 #26
0
        private void OrdenarCaminhos()
        {
            int[] distancias = new int[caminhosPossiveis.Count];

            for (int i = 0; i < caminhosPossiveis.Count; i++)
            {
                PilhaLista <int> aux = caminhosPossiveis[i].Clone();
                int caminho          = 0;
                int anterior         = aux.Desempilhar();
                while (!aux.EstaVazia())
                {
                    int cidade = aux.Desempilhar();
                    caminho += adjacencias[cidade, anterior];
                    anterior = cidade;
                }
                distancias[i] = caminho;
            }

            int quantosCaminhosForam = 0;
            int indiceMenorCaminho   = 0;

            while (quantosCaminhosForam < caminhosPossiveis.Count)
            {
                int menorCaminho = int.MaxValue;

                for (int i = quantosCaminhosForam; i < caminhosPossiveis.Count; i++)
                {
                    if (distancias[i] < menorCaminho)
                    {
                        menorCaminho       = distancias[i];
                        indiceMenorCaminho = i;
                    }
                }

                PilhaLista <int> melhor = caminhosPossiveis[indiceMenorCaminho].Clone();
                caminhosPossiveis.RemoveAt(indiceMenorCaminho);
                caminhosPossiveis.Insert(quantosCaminhosForam, melhor);
                quantosCaminhosForam++;
            }
        }
예제 #27
0
        // Método que obtém o caminho com menor custo gasto
        private PilhaLista <Movimento> MelhorCaminhoCusto()
        {
            No <PilhaLista <Movimento> > umCaminho     = caminhos.Inicio;
            PilhaLista <Movimento>       melhorCaminho = umCaminho.Info;

            while (umCaminho != null)
            {
                if (umCaminho.Prox == null)
                {
                    break;
                }

                if (ObterCusto(melhorCaminho) > ObterCusto(umCaminho.Prox.Info))
                {
                    melhorCaminho = umCaminho.Prox.Info;
                }

                umCaminho = umCaminho.Prox;
            }

            return(melhorCaminho);
        }
예제 #28
0
        void DesenharCaminho(PilhaLista <Caminho> aDesenhar, SolidBrush preenchimento, Pen caneta, Graphics g, int cor)
        {
            int xOrigem  = 0;
            int yOrigem  = 0;
            int xDestino = 0;
            int yDestino = 0;

            Color[] cores = { Color.Black, Color.Blue, Color.Red, Color.Green, Color.Orange, Color.Purple, Color.Navy, Color.Brown, Color.Pink };

            preenchimento = new SolidBrush(cores[cor]);
            caneta        = new Pen(cores[cor], 3);
            while (!aDesenhar.EstaVazia())
            {
                var caminho = aDesenhar.Desempilhar();
                xOrigem  = (dadosCidade[caminho.IdCidadeOrigem].CoordenadaX * pbMapa.Width) / 4096;
                yOrigem  = (dadosCidade[caminho.IdCidadeOrigem].CoordenadaY * pbMapa.Height) / 2048;
                xDestino = (dadosCidade[caminho.IdCidadeDestino].CoordenadaX * pbMapa.Width) / 4096;
                yDestino = (dadosCidade[caminho.IdCidadeDestino].CoordenadaY * pbMapa.Height) / 2048;

                g.DrawLine(caneta, xOrigem, yOrigem, xDestino, yDestino);
            }
        }
예제 #29
0
        public int distancia(PilhaLista <int> caminho) // Calcula a distancia total de um caminho
        {
            int distanciaTotal = 0;

            int[]            caminhoVet = new int[caminho.Tamanho()];
            PilhaLista <int> caminhoAux = caminho.Clone();


            int i = 0;

            while (!caminhoAux.EstaVazia())
            {
                caminhoVet[i] = caminhoAux.Desempilhar(); // Preenche o vetor caminhoVet com os caminhos da pilha caminhoAux
                i++;
            }

            for (i = caminho.Tamanho() - 1; i > 0; i--)
            {
                distanciaTotal += caminhos[caminhoVet[i], caminhoVet[i - 1]].Distancia; // calcula a distancia total do caminho
            }
            return(distanciaTotal);
        }
예제 #30
0
        /*
         * Exibe todos os caminhos em um dataGridView de caminhos e o menor caminho em um outro.
         */
        private void MostrarCaminhos()
        {
            foreach (PilhaLista <Caminho> caminho in listaCaminhos)
            {
                int posicao = 0;
                PilhaLista <Caminho> aux = caminho.Clone();
                aux.Inverter();

                if (dgvCaminhoEncontrado.RowCount == menor)
                {
                    dgvMelhorCaminho.RowCount++;
                    dgvMelhorCaminho.ColumnCount = aux.Tamanho() + 1;
                }

                dgvCaminhoEncontrado.RowCount++;


                if (dgvCaminhoEncontrado.ColumnCount <= aux.Tamanho())
                {
                    dgvCaminhoEncontrado.ColumnCount = aux.Tamanho() + 1;
                }

                while (!aux.EstaVazia())
                {
                    Caminho c = aux.Desempilhar();
                    if (dgvCaminhoEncontrado.RowCount - 1 == menor)
                    {
                        ExibirDgv(dgvMelhorCaminho, c, posicao);
                    }

                    ExibirDgv(dgvCaminhoEncontrado, c, posicao);
                    posicao++;
                }
            }

            selecionado = menor;
            dgvCaminhoEncontrado.Rows[selecionado].Selected = true;
            pbMapa.Invalidate();
        }