public int AddVertex(KeyedData vertex) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].Vertex.Key == vertex.Key) { return(i); } } Node node = new Node(vertex); nodes.Add(node); return(nodes.Count); }
public LNode AddVertex(KeyedData vertex) { foreach (LNode u in this) { if (u.Vertex.Key == vertex.Key) { return(u); } } LNode node = new LNode(vertex); nodes.Add(node); return(node); }
public Node(KeyedData vertex) { this.vertex = vertex; adjacency = new List <int>(); }
public LGraph StronglyConnectedComponents() { // Chama DFS para computar os tempos finais f[u] para cada vertice u List <KeyedData> Q1 = DFS(); // A segunda invocacao de DFS adiante, requer que os vertices sejam // analisados em ordem decrescente de tempos finais for (int i = 0; i < Q1.Count / 2; i++) { KeyedData tmp = (KeyedData)Q1[i]; Q1[i] = Q1[Q1.Count - i - 1]; Q1[Q1.Count - i - 1] = tmp; } // Calcula o grafo transposta LGraph T = Transpose(); // Segunda invocacao de DFS eh sobre o grafo transposto LGraph[] forest = T.DFForest(Q1); // Cada subconjunto de vertices de cada arvore da floresta forest // determina um componente fortemente conectado //////////////////////////////////////////////////////////// // A partir daqui, vai construir um grafo cujos vertices // sao grafos conectados // List <KeyedData>[] vertex = new List <KeyedData> [forest.Length]; // Primeiro particiona o conjunto de vertices for (int t = 0; t < forest.Length; t++) { string key = ""; vertex[t] = new List <KeyedData>(); for (int i = 0; i < forest[t].Count; i++) { key += forest[t][i].ToString(); vertex[t].Add(forest[t][i].Vertex); } } // Conjunto de subgrafos estritamente conectados LGraph[] node = new LGraph[vertex.Length]; // Matrix relacao bool[,] mat = ToMatrix(); // Selecionamento das linhas e colunas da matrix relacao bool[,] selected = new bool[node.Length, Count]; // Para cada subconjunto de vertices do particionamento, // constroi um novo grafo for (int t = 0; t < node.Length; t++) { string key = ""; for (int v = 0; v < vertex[t].Count; v++) { key += vertex[t][v].Key; } node[t] = new LGraph(key); for (int v = 0; v < vertex[t].Count; v++) { node[t].AddVertex(vertex[t][v]); } } // Selecionamento das colunas da matrix relacao em funcao do // particionamento do conjunto de vertices for (int t = 0; t < node.Length; t++) { for (int i = 0; i < Count; i++) { if (node[t].FindVertice(nodes[i].Vertex.Key) != null) { selected[t, i] = true; } else { selected[t, i] = false; } } } // Insere as transicoes dentro dos subgrafos for (int t = 0; t < node.Length; t++) { for (int i = 0; i < Count; i++) { for (int j = 0; j < Count; j++) { if (selected[t, i] && selected[t, j] && mat[i, j]) { node[t].AddEdge( node[t].FindVertice(nodes[i].Vertex.Key), node[t].FindVertice(nodes[j].Vertex.Key) ); } } } } // Elimina as transicoes internas aos subgrafos da matrix relacao for (int t = 0; t < node.Length; t++) { for (int i = 0; i < Count; i++) { for (int j = 0; j < Count; j++) { if (selected[t, i] && selected[t, j]) { mat[i, j] = false; } } } } // Constroi o grafo cujos vertices sao subgrafos LGraph gr = new LGraph(Key + "_SCC"); // Insere os subgrafos como vertices do grafo resultante for (int t = 0; t < node.Length; t++) { gr.AddVertex(node[t]); } // Adiciona as transicoes entre subgrafos no grafo resultante for (int i = 0; i < Count; i++) { for (int j = 0; j < Count; j++) { if (mat[i, j]) { int from, to; for (from = 0; from < node.Length; from++) { if (selected[from, i]) { break; } } for (to = 0; to < node.Length; to++) { if (selected[to, j]) { break; } } gr.AddEdge(gr[from], gr[to]); } } } // Retorna o grafo resultante return(gr); }
public LNode(KeyedData vertex) { this.vertex = vertex; pred = new List <LNode>(); succ = new List <LNode>(); }