/// <summary> /// Cria uma aresta entre duas cidades /// </summary> private void btnCriar_Click(object sender, EventArgs e) { if (cbOrigem.SelectedItem == cbDestino.SelectedItem) { MessageBox.Show(this, "Não pode criar aresta de uma cidade para ela mesma", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } Aresta <Cidade> nova = new Aresta <Cidade>((Cidade)cbOrigem.SelectedItem, (Cidade)cbDestino.SelectedItem, (int)numPeso.Value); // Procura por uma aresta que tenha a mesma origem e destino Aresta <Cidade> existente = arestas.Find( (Aresta <Cidade> a) => a.Destino.Equals(nova.Destino) && a.Origem.Equals(nova.Origem) // Ai ); // Se existir, sugere mudar o peso dela if (existente != null) { DialogResult r = MessageBox.Show(this, "Já existe uma aresta ligando estas cidade. Deseja mudar seu peso?", Text, MessageBoxButtons.YesNo); if (r == DialogResult.Yes) { arestas[arestas.IndexOf(existente)] = nova; } return; } // Se não, cria a aresta arestas.Add(nova); }
/// <summary> /// Verifica igualdade entre duas arestas /// </summary> /// <param name="other">Aresta com a qual comparar</param> /// <returns>Verdadeiro se forem iguais, falso se não</returns> public override bool Equals(object other) { if (other == null || other.GetType() != typeof(Aresta <Tipo>)) { return(false); } Aresta <Tipo> a = (Aresta <Tipo>)other; return(Origem.Equals(a.Origem) && Destino.Equals(a.Destino) && Valor == a.Valor); }
/// <summary> /// Caminho selecionado /// </summary> private void lbCaminhos_SelectedIndexChanged(object sender, EventArgs e) { caminho.Clear(); if (lbCaminhos.SelectedItem != null) { string[] c = lbCaminhos.SelectedItem.ToString().Split(','); for (int i = 0; i < c.Length - 1; i++) { Cidade c1 = new Cidade(c[i]), c2 = new Cidade(c[i + 1]); Aresta <Cidade> aresta = grafo.ArestaEntre(c1, c2); caminho.Add(aresta); } } canvasGrafo.Invalidate(); }
/// <summary> /// Procura um caminho entre dois nós com dijkstra /// </summary> /// <param name="origem">Índice do nó de origem</param> /// <param name="destino">Índice do nó de destino</param> /// <returns>Uma lista com os índices dos nós no caminho</returns> List <int> Dijkstra(int origem, int destino) { var n = grafo.Vertices.Length; var distancias = new int[n]; for (int i = 0; i < n; i++) { distancias[i] = int.MaxValue; } distancias[origem] = 0; var visitado = new bool[n]; var anterior = new int?[n]; while (true) { var minimaDistancia = int.MaxValue; var verticeMinimo = 0; for (int i = 0; i < n; i++) { if (!visitado[i] && minimaDistancia > distancias[i]) { minimaDistancia = distancias[i]; verticeMinimo = i; } } if (minimaDistancia == int.MaxValue) { break; } visitado[verticeMinimo] = true; for (int i = 0; i < n; i++) { Aresta <Cidade> a = grafo.ArestaEntre(grafo.Vertices[verticeMinimo], grafo.Vertices[i]); int v = a == null ? 0 : a.Valor; if (v > 0) { var menorParaOMinimo = distancias[verticeMinimo]; var distanciaParaOProximo = v; var total = menorParaOMinimo + distanciaParaOProximo; if (total < distancias[i]) { distancias[i] = total; anterior[i] = verticeMinimo; } } } } if (distancias[destino] == int.MaxValue) { return(null); } var caminho = new LinkedList <int>(); int?atual = destino; while (atual != null) { caminho.AddFirst(atual.Value); atual = anterior[atual.Value]; } return(caminho.ToList()); }
/// <summary> /// Adiciona uma aresta ao grafo /// </summary> /// <param name="aresta">Aresta a ser adicionada ao grafo</param> public void AdicionarAresta(Aresta <Tipo> aresta) { _arestas.Add(aresta); }