public void AddEdge(Edge <T> edge) { Vertex <T> from = edge.FromVertex; Vertex <T> to = edge.ToVertex; if (Math.Max(from.Id, to.Id) >= highestIndex) { highestIndex = Math.Max(from.Id, to.Id); } if (!digraph) { if (aList.ContainsKey(from.Id)) { aList[from.Id].Add(to); edgesList.Add(new Edge <T>(from, to)); } else { aList[from.Id] = new List <Vertex <T> >(); aList[from.Id].Add(to); edgesList.Add(new Edge <T>(from, to)); edgesList.Add(new Edge <T>(to, from)); } //dodaj sasiadow from.Neighbors.Add(to); } else { //jesli digraf if (aList.ContainsKey(from.Id) && aList.ContainsKey(to.Id)) { aList[from.Id].Add(to); aList[to.Id].Add(from); } else if (aList.ContainsKey(from.Id) && !aList.ContainsKey(to.Id)) { aList[to.Id] = new List <Vertex <T> >(); aList[from.Id].Add(to); aList[to.Id].Add(from); } else if (aList.ContainsKey(to.Id) && !aList.ContainsKey(from.Id)) { aList[from.Id] = new List <Vertex <T> >(); aList[from.Id].Add(to); aList[to.Id].Add(from); } else if (!aList.ContainsKey(to.Id) && !aList.ContainsKey(from.Id)) { aList[from.Id] = new List <Vertex <T> >(); aList[to.Id] = new List <Vertex <T> >(); aList[from.Id].Add(to); aList[to.Id].Add(from); } //dodaj sasiadow from.Neighbors.Add(to); to.Neighbors.Add(from); } }
public void AddOneWayEdge(Edge Edge) { SetOfEdges.Add(Edge); SetOfEdges[SetOfEdges.Count - 1].Index = SetOfEdges.Count - 1; }
/// <summary> /// Algoritmo de Prim com as duas implementações. /// </summary> /// <param name="implementationType">Tipo de implemantação que será usada para executar o algoritmo</param> /// <returns></returns> public int Prim(PrimType implementationType) { //Declaração de variáveis auxiliares que serão usadas globalmente int initialVertex = 1; int minimumSpaningTreeCost = 0; Edge edge = new Edge(); //Verifica qual é o tipo de implementação do Prim foi escolhida e executa as ações condizentes switch (implementationType) { case PrimType.PQEdge: //Prim com fila de prioridades sobre as arestas //Vetor boolean com n + 1 posições que controla quais vértices já foram explorados. O vetor é inicializado com todas as posições em false. bool[] explored = Enumerable.Repeat(false, numberOfVertices + 1).ToArray(); //Declaração de variável que representa o heap var heap = new Heap <Edge>(); //Marca o vértice inicial como explorado explored[initialVertex] = true; //Coloca no heap as arestas incidentes sobre o vértice inicial foreach (var vertex in adjacencyLists[initialVertex]) { if (explored[vertex.key] == false) { edge.vertexFrom = initialVertex; edge.vertexTo = vertex.key; heap.HeapAdd(vertex.weight, edge); } } //Enquanto o heap não estiver vazio while (heap.HeapSize() > 0) { //Extrai a menor aresta do heap. A aresta vem encapsulada com peso e índice. var extractedEdge = heap.HeapExtractMin(); int edgeWeight = extractedEdge.Item1; edge = extractedEdge.Item3; //Verifica qual vértice ainda não foi explorado int unexploredVertex = 0; if (explored[edge.vertexFrom] == false) { unexploredVertex = edge.vertexFrom; } else if (explored[edge.vertexTo] == false) { unexploredVertex = edge.vertexTo; } //Se os dois vértices já foram explorados não faz nada if (unexploredVertex != 0) { minimumSpaningTreeCost += edgeWeight; explored[unexploredVertex] = true; //Adiciona as arestas na vizinhaca do vértice no heap foreach (var vertex in adjacencyLists[unexploredVertex]) { //Se o vértice de destino já foi explorado antão não coloca a aresta no heap if (explored[vertex.key] != true) { edge.vertexFrom = unexploredVertex; edge.vertexTo = vertex.key; heap.HeapAdd(vertex.weight, edge); } } } } break; case PrimType.PQVertex: //Prim com fila de prioridades sobre os vértices //Inicializa a distância de todos os vértices em infinito, salvo o primeiro, que é igual a zero. //Tupla: Item1 - Distância do vértice para o grupo (prioridade no heap); Item2 - Índice do vértice; Item3 - Conteúdo do vértice. //A lista tem esse formato para que possa se passada como parâmetro para o heap var initialDistances = Enumerable.Range(1, numberOfVertices).Select(a => new Tuple <int, int, int>(int.MaxValue, a, a)).ToList(); initialDistances[0] = new Tuple <int, int, int>(0, 1, 1); //Cria o heap com as distancias iniciais para os vértices var distHeap = new Heap <int>(initialDistances); while (distHeap.HeapSize() > 0) { var extractedVertex = distHeap.HeapExtractMin(); //Incrementa o custa da arvore geradora mínima com o valor mínimo extraido do heap minimumSpaningTreeCost += extractedVertex.Item1; //Para cada vértice adjacente aquele que foi retirado do heap foreach (var vertex in adjacencyLists[extractedVertex.Item2]) { int vertexKey = distHeap.HeapGetKey(vertex.key); //Verifica se sua distância do grupo dimunuiu if ((vertexKey > 0) && (vertexKey > vertex.weight)) { distHeap.HeapChangeKey(vertex.weight, vertex.key); } } } break; default: throw new ArgumentException("Tipo de Prim não especificado."); } return(minimumSpaningTreeCost); }
void AddEdge(Edge e) { AddEdge(e.V1, e.V2, e.Orientation, Math.Max(1, e.Multiplicity), e.Thickness, e.Style, e.Label); }