예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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();
        }
예제 #4
0
        /// <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());
        }
예제 #5
0
 /// <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);
 }