Exemplo n.º 1
0
        public LGraph Transpose()
        {
            LGraph transp = new LGraph("\\{" + key + "\\}^T");

            foreach (LNode u in this)
            {
                transp.AddVertex(u.Vertex);
            }
            foreach (LNode u in this)
            {
                foreach (LNode v in u.Successor)
                {
                    transp.AddEdge(transp[v.Vertex.Key], transp[u.Vertex.Key]);
                }
            }

            return(transp);
        }
Exemplo n.º 2
0
        public LGraph BFTree(int s)
        {
            LGraph tree = new LGraph("BFTree");

            BFS(s);

            tree.AddVertex(this[s].Vertex);

            for (int i = 0; i < Count; i++)
            {
                if (i != s && this[i].pi != null)
                {
                    LNode from = tree.AddVertex(this[i].Vertex);
                    LNode to   = tree.AddVertex(this[i].pi.Vertex);
                    tree.AddEdge(from, to);
                }
            }

            return(tree);
        }
Exemplo n.º 3
0
        public LGraph[] DFForest()
        {
            bool[] root = new bool[Count];

            List <KeyedData> tSort = DFS();

            int nTrees = 0;

            for (int i = 0; i < Count; i++)
            {
                if (nodes[i].pi == null)
                {
                    nTrees++;
                    root[i] = true;
                }
                else
                {
                    root[i] = false;
                }
            }

            LGraph[] tree = new LGraph[nTrees];

            int t = 0;

            for (int s = 0; s < Count; s++)
            {
                if (root[s])
                {
                    tree[t] = new LGraph("DFForest");

                    tree[t].AddVertex(this[s].Vertex);

                    Queue <object> q = new Queue <object>();

                    foreach (LNode u in this[s].Successor)
                    {
                        if (u.pi == this[s])
                        {
                            q.Enqueue(u);
                        }
                    }

                    while (q.Count > 0)
                    {
                        LNode u = (LNode)q.Dequeue();

                        LNode from = tree[t].AddVertex(u.Vertex);
                        LNode to   = tree[t].AddVertex(u.pi.Vertex);
                        tree[t].AddEdge(from, to);

                        foreach (LNode v in u.Successor)
                        {
                            if (v.pi == u)
                            {
                                q.Enqueue(v);
                            }
                        }
                    }

                    t++;
                }
            }

            return(tree);
        }
Exemplo n.º 4
0
        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);
        }