Exemplo n.º 1
0
        public bool Possible()
        {
            Graph     g   = new Graph(N * 2, E, true);
            TarjanSCC scc = new TarjanSCC(g);

            for (int v = 0; v < N; v++)
            {
                if (scc.StronglyConnected(v << 1, (v << 1) ^ 1))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 2
0
        // 参考解答 连通性 + 最小生成树性质
        public static IList <IList <int> > FindCriticalAndPseudoCriticalEdges_1(int n, int[][] edges)
        {
            int length   = edges.Length;
            var newEdges = edges.Select((item, index) => (X: item[0], Y: item[1], V: item[2], Index: index))
                           .OrderBy(item => item.V)
                           .ToArray();

            UnionFind            unionFind = new UnionFind(n);
            IList <IList <int> > result    = new List <IList <int> >();

            for (int i = 0; i < 2; i++)
            {
                result.Add(new List <int>());
            }

            int[] label = new int[length];
            int   index = 0;

            while (index < length)
            {
                int v = newEdges[index].V;
                int j = index;

                while (j < length && newEdges[j].V == v)
                {
                    j++;
                }

                Dictionary <int, int> compToId = new Dictionary <int, int>();
                int gn = 0;

                for (int k = index; k < j; k++)
                {
                    int x = newEdges[k].X;
                    int y = newEdges[k].Y;
                    if (x != y)
                    {
                        if (!compToId.ContainsKey(x))
                        {
                            compToId[x] = gn++;
                        }

                        if (!compToId.ContainsKey(y))
                        {
                            compToId[y] = gn++;
                        }
                    }
                    else
                    {
                        label[newEdges[k].Index] = -1;
                    }
                }

                List <int>[] gm   = new List <int> [gn];
                List <int>[] gmid = new List <int> [gn];
                for (int k = 0; k < gn; k++)
                {
                    gm[k]   = new List <int>();
                    gmid[k] = new List <int>();
                }

                for (int k = index; k < j; k++)
                {
                    int x = newEdges[k].X;
                    int y = newEdges[k].Y;
                    if (x == y)
                    {
                        continue;
                    }

                    int idX = compToId[x];
                    int idY = compToId[y];
                    gm[idX].Add(idY);
                    gmid[idX].Add(newEdges[k].Index);
                    gm[idY].Add(idX);
                    gmid[idY].Add(newEdges[k].Index);
                }

                List <int> bridges = new TarjanSCC(gn, gm, gmid).CuttingEdge;
                foreach (int id in bridges)
                {
                    result[0].Add(id);
                    label[id] = 1;
                }

                for (int k = index; k < j; k++)
                {
                    unionFind.Union(newEdges[k].X, newEdges[k].Y);
                }

                index = j;
            }

            for (int i = 0; i < length; i++)
            {
                if (label[i] == 0)
                {
                    result[i].Add(i);
                }
            }

            return(result);
        }
Exemplo n.º 3
0
        public void Run()
        {
            Console.WriteLine("Choose file:");     // Prompt
            Console.WriteLine("1 - tinyDG.txt");   // Prompt
            Console.WriteLine("2 - mediumDG.txt"); // Prompt
            Console.WriteLine("or quit");          // Prompt

            var    fileNumber = Console.ReadLine();
            string fileName;

            switch (fileNumber)
            {
            case "1":
                fileName = "tinyDG.txt";
                break;

            case "2":
                fileName = "mediumDG.txt";
                break;

            case "quit":
                return;

            default:
                return;
            }


            var @in   = new In($"Files\\Graphs\\{fileName}");
            var lines = @in.ReadAllLines();

            var lineIterator = 0;
            var v            = 0;
            var e            = 0;
            var edges        = new List <EdgeD>();

            foreach (var line in lines)
            {
                if (lineIterator == 0)
                {
                    v = Convert.ToInt32(line);
                }
                if (lineIterator == 1)
                {
                    e = Convert.ToInt32(line);
                }
                if (lineIterator > 1)
                {
                    var lineSplitted = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    var ve           = Convert.ToInt32(lineSplitted[0]);
                    var we           = Convert.ToInt32(lineSplitted[1]);
                    var edge         = new EdgeD(ve, we);
                    edges.Add(edge);
                }

                lineIterator++;
            }

            var digraph = new Digraph(v, e, edges);

            Console.WriteLine(digraph);

            var scc = new TarjanSCC(digraph);

            // number of connected components
            var m = scc.Count();

            Console.WriteLine($"{m} components");

            // compute list of vertices in each strong component
            var components = new Core.Collections.Queue <Integer> [m];

            for (var i = 0; i < m; i++)
            {
                components[i] = new Core.Collections.Queue <Integer>();
            }
            for (var i = 0; i < digraph.V; i++)
            {
                components[scc.Id(i)].Enqueue(i);
            }

            // print results
            for (var i = 0; i < m; i++)
            {
                foreach (int j in components[i])
                {
                    Console.Write($"{j} ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
Exemplo n.º 4
0
        public static void ShowCycles(int pos, Document document)
        {
            Dictionary <string, string> result = new Dictionary <string, string>();

            // Check if initial file is a grammar.
            ParsingResults pd_parser = ParsingResultsFactory.Create(document) as ParsingResults;

            if (pd_parser == null)
            {
                throw new LanguageServerException("A grammar file is not selected. Please select one first.");
            }
            Transform.ExtractGrammarType egt = new Transform.ExtractGrammarType();
            ParseTreeWalker.Default.Walk(egt, pd_parser.ParseTree);
            bool is_grammar = egt.Type == Transform.ExtractGrammarType.GrammarType.Parser ||
                              egt.Type == Transform.ExtractGrammarType.GrammarType.Combined ||
                              egt.Type == Transform.ExtractGrammarType.GrammarType.Lexer;

            if (!is_grammar)
            {
                throw new LanguageServerException("A grammar file is not selected. Please select one first.");
            }

            // Find all other grammars by walking dependencies (import, vocab, file names).
            HashSet <string> read_files = new HashSet <string>
            {
                document.FullPath
            };
            Dictionary <Workspaces.Document, List <TerminalNodeImpl> > every_damn_literal =
                new Dictionary <Workspaces.Document, List <TerminalNodeImpl> >();

            for (; ;)
            {
                int before_count = read_files.Count;
                foreach (string f in read_files)
                {
                    List <string> additional = ParsingResults.InverseImports.Where(
                        t => t.Value.Contains(f)).Select(
                        t => t.Key).ToList();
                    read_files = read_files.Union(additional).ToHashSet();
                }
                foreach (string f in read_files)
                {
                    var additional = ParsingResults.InverseImports.Where(
                        t => t.Key == f).Select(
                        t => t.Value);
                    foreach (var t in additional)
                    {
                        read_files = read_files.Union(t).ToHashSet();
                    }
                }
                int after_count = read_files.Count;
                if (after_count == before_count)
                {
                    break;
                }
            }

            // Construct graph of symbol usage.
            Transform.TableOfRules table = new Transform.TableOfRules(pd_parser, document);
            table.ReadRules();
            table.FindPartitions();
            table.FindStartRules();
            Digraph <string> graph = new Digraph <string>();

            foreach (Transform.TableOfRules.Row r in table.rules)
            {
                if (!r.is_parser_rule)
                {
                    continue;
                }
                graph.AddVertex(r.LHS);
            }
            foreach (Transform.TableOfRules.Row r in table.rules)
            {
                if (!r.is_parser_rule)
                {
                    continue;
                }
                List <string> j = r.RHS;
                //j.Reverse();
                foreach (string rhs in j)
                {
                    Transform.TableOfRules.Row sym = table.rules.Where(t => t.LHS == rhs).FirstOrDefault();
                    if (!sym.is_parser_rule)
                    {
                        continue;
                    }
                    DirectedEdge <string> e = new DirectedEdge <string>(r.LHS, rhs);
                    graph.AddEdge(e);
                }
            }
            List <string> starts           = new List <string>();
            List <string> parser_lhs_rules = new List <string>();

            foreach (Transform.TableOfRules.Row r in table.rules)
            {
                if (r.is_parser_rule)
                {
                    parser_lhs_rules.Add(r.LHS);
                    if (r.is_start)
                    {
                        starts.Add(r.LHS);
                    }
                }
            }

            IParseTree rule = null;
            IParseTree it   = pd_parser.AllNodes.Where(n =>
            {
                if (!(n is ANTLRv4Parser.ParserRuleSpecContext || n is ANTLRv4Parser.LexerRuleSpecContext))
                {
                    return(false);
                }
                Interval source_interval = n.SourceInterval;
                int a     = source_interval.a;
                int b     = source_interval.b;
                IToken ta = pd_parser.TokStream.Get(a);
                IToken tb = pd_parser.TokStream.Get(b);
                var start = ta.StartIndex;
                var stop  = tb.StopIndex + 1;
                return(start <= pos && pos < stop);
            }).FirstOrDefault();

            rule = it;
            var           k       = (ANTLRv4Parser.ParserRuleSpecContext)rule;
            var           tarjan  = new TarjanSCC <string, DirectedEdge <string> >(graph);
            List <string> ordered = new List <string>();
            var           sccs    = tarjan.Compute();

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Cycles in " + document.FullPath);
            var done = new List <IEnumerable <string> >();

            foreach (var scc in sccs)
            {
                if (scc.Value.Count() <= 1)
                {
                    continue;
                }
                if (!done.Contains(scc.Value))
                {
                    foreach (var s in scc.Value)
                    {
                        sb.Append(" ");
                        sb.Append(s);
                    }
                    sb.AppendLine();
                    sb.AppendLine();
                    done.Add(scc.Value);
                }
            }

            //var scc = sccs[k.RULE_REF().ToString()];
            //foreach (var v in scc)
            //{
            //    ordered.Add(v);
            //}
        }