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(); }
//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); }
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(); }
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; }
// 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(); } }
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(); }
// 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; } }
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(); }
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!"); } } }
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 } }
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"); } }
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; } }
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 } }
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(); }
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(); } } } } }
// 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); }
/* * 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); } } } } }
// 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); }
// 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); }
// 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); }
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; } } }
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(); } } }
//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(); }
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); } }
// 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(); }
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++; } }
// 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); }
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); } }
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); }
/* * 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(); }