Example #1
0
        // These two (ischordal + isclique) could probably be done a lot faster and better. See https://github.com/omid69/PEO-Verification
        public static bool IsChordal(MoplexAnalysis analysis)
        {
            var ordering = analysis.EleminationOrder;
            var labels   = analysis.NeighbourLabels;

            foreach (int i in ordering.Keys)
            {
                int v      = ordering[i];
                var clique = new HashSet <int>(labels[i].Where(j => j > v).Select(label => analysis.EleminationOrderRev[label]));

                clique.Add(i);
                if (!IsClique(clique, analysis.EleminationOrder, labels))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        public static bool IsChordal2(MoplexAnalysis analysis, UndirectedGraph <int, Edge <int> > graph)
        {
            var ordering = analysis.EleminationOrder;
            var labels   = analysis.NeighbourLabels;

            foreach (int v in ordering.Keys)
            {
                int o      = ordering[v];
                var clique = new HashSet <int>(labels[v].Where(j => j > o).Select(j => analysis.EleminationOrderRev[j]));
                clique.Add(v);
                if (!IsClique2(clique, graph))
                {
                    return(false);
                }
            }


            return(true);
        }
Example #3
0
        public static Tuple <int, HashSet <Edge <int> > > FindKKernel(UndirectedGraph <int, Edge <int> > graph, DateTime timeOfInit, Holder kernel)
        {
            int ret = -1;

            if (kernel.CC == 0)                                                        //no chordless cycles; i.e. the graph is chordal
            {
                if (IsChordal2(MoplexAnalysis.AnalyseGraph(graph, null, null), graph)) //hack - we really need to seperate
                {
                    return(new Tuple <int, HashSet <Edge <int> > >(0, new HashSet <Edge <int> >()));
                }
            }
            int k = kernel.CC - 1;
            HashSet <Edge <int> > retEdges = null;

            while (ret == -1)
            {
                k++;
                Kernel.Phase3(kernel, k);
                var g = new UndirectedGraph <int, Edge <int> >(false);
                foreach (var relevantV in kernel.A)
                {
                    var v = int.Parse(relevantV);
                    g.AddVertex(v);
                }
                foreach (var v in g.Vertices)
                {
                    g.AddEdgeRange(graph.AdjacentEdges(v));
                }
                // todo: connected components
                var time1 = DateTime.Now;
                var clone = CloneGraph(g);
                Console.WriteLine(k);
                var tup = FasterInner(clone, k, k * 2, new HashSet <int>(), null, null, new HashSet <Edge <int> >());
                ret      = tup.Item1;
                retEdges = tup.Item2;
                Console.WriteLine($"Took {(DateTime.Now - time1):c}");
                Console.WriteLine($"Cumulated {(DateTime.Now - timeOfInit):c}");
            }
            return(new Tuple <int, HashSet <Edge <int> > >(k - ret, retEdges));
        }
Example #4
0
        static void Main(string[] args)
        {
            //TestGraphs.testAllGraphs();
            TestGraphs.Tests();
            //var graph1 = parse(args[0], true);
            //var graph2 = parseFile(args[0], false);
            //var graph = TestGraphs.TestGraph8();
            //var k1 = Faster.Run(graph1);
            UndirectedGraph <int, Edge <int> > graph = null;

            if (args.Length > 0)
            {
                graph = ParseFile(args[0], false);
            }
            else
            {
                graph = ReadGraph();
            }
            DrawGraph.drawGraph(graph, new HashSet <Edge <int> >(), @"C:\Users\Frederik\Downloads\instances\1.dot");
            Tuple <int, HashSet <Edge <int> > > a = Faster.Run(graph);
            var k       = a.Item1;
            var edgeSet = a.Item2;

            //Idiot check
            graph.AddEdgeRange(edgeSet);
            var analysis = MoplexAnalysis.AnalyseGraph(graph, null, null);

            if (!Faster.IsChordal2(analysis, graph))
            {
                //var x = Faster.FindFourCycle2(graph);
                throw new Exception("Idiot check went terribly wrong");
            }
            //Console.WriteLine($"Graph: {args[0].Split('\\').Last()} has k={k}");
            //Console.ReadLine();
            PrintSolution(edgeSet);
        }
Example #5
0
        public static Tuple <int, HashSet <Edge <int> > > FasterInner(
            UndirectedGraph <int, Edge <int> > graph,
            int k,
            int r,
            HashSet <int> marked,
            List <Edge <int> > newlyAddedEdges,
            List <List <int> > prevMoplexes,
            HashSet <Edge <int> > addedEdges
            )
        {
            // Trivial cases
            if (k < 0 || r < -1)
            {
                return(new Tuple <int, HashSet <Edge <int> > >(-1, addedEdges));
            }

            var analysis = MoplexAnalysis.AnalyseGraph(graph, newlyAddedEdges, prevMoplexes);

            if (IsChordal2(analysis, graph))
            {
                return(new Tuple <int, HashSet <Edge <int> > >(k, addedEdges));
            }

            // Find four cycle
            List <int> cycle = FindFourCycle2(graph); //has to return four cycle in topological order

            if (cycle != null)
            {
                //if (FindFourCycle3(graph) == null) // || !FindFourCycle2(graph).SequenceEqual(FindFourCycle3(graph))) // only for debug
                //{
                //    var o = FindFourCycle1(graph);
                //    var a = FindFourCycle2(graph);
                //    var b = FindFourCycle3(graph);
                //}

                //foreach (var v in graph.Vertices)
                //{
                //    Console.WriteLine(v);
                //}
                //foreach (var e in graph.Edges)
                //{
                //    Console.WriteLine($"{e.Source} {e.Target}");
                //}

                //var graph1 = CloneGraph(graph); // maybe only clone once
                var clone       = CloneGraph(graph);
                var newEdge1    = new Edge <int>(cycle[0], cycle[3]);
                var newEdge2    = new Edge <int>(cycle[1], cycle[2]);
                var addedEdges1 = CloneSet(addedEdges);
                var addedEdges2 = CloneSet(addedEdges);
                addedEdges1.Add(newEdge1);
                addedEdges2.Add(newEdge2);
                graph.AddEdge(newEdge1);
                clone.AddEdge(newEdge2);
                var marked1 = new HashSet <int>(marked);
                var marked2 = new HashSet <int>(marked);
                var r1      = r;
                var r2      = r;

                if (marked.Contains(cycle[0]))
                {
                    marked1.Remove(cycle[0]);
                }
                else
                {
                    r1--;
                }
                if (marked.Contains(cycle[3]))
                {
                    marked1.Remove(cycle[3]);
                }
                else
                {
                    r1--;
                }
                if (marked.Contains(cycle[1]))
                {
                    marked2.Remove(cycle[1]);
                }
                else
                {
                    r2--;
                }
                if (marked.Contains(cycle[2]))
                {
                    marked2.Remove(cycle[2]);
                }
                else
                {
                    r2--;
                }
                var tup1 = FasterInner(graph, k - 1, r1, marked1, new List <Edge <int> > {
                    newEdge1
                }, analysis.Moplexes, addedEdges1);
                var k1   = tup1.Item1;
                var e1   = tup1.Item2;
                var tup2 = FasterInner(clone, k - 1, r2, marked2, new List <Edge <int> > {
                    newEdge2
                }, analysis.Moplexes, addedEdges2);
                var k2 = tup2.Item1;
                var e2 = tup2.Item2;
                if (k1 > k2)
                {
                    return(new Tuple <int, HashSet <Edge <int> > >(k1, e1));
                }
                return(new Tuple <int, HashSet <Edge <int> > >(k2, e2));
            }

            //find moplex with both marked and unmarked edges
            List <List <int> > markedAndUnmarked = analysis.Moplexes.Where(vl => vl.Any(marked.Contains)).Where(vl => vl.Any(v => !marked.Contains(v))).ToList();

            if (markedAndUnmarked.Count > 0)
            {
                foreach (var moplex in markedAndUnmarked)
                {
                    foreach (var vertex in moplex)
                    {
                        if (marked.Add(vertex))
                        {
                            r--;
                        }
                    }
                }
                return(FasterInner(graph, k, r, marked, null, analysis.Moplexes, addedEdges));
            }

            //simplicial moplex with only unmarked vertices
            List <List <int> > unmarkedMoplexes   = analysis.Moplexes.Where(vl => vl.TrueForAll(v => !marked.Contains(v))).ToList();
            List <List <int> > simplicialUnmarked = unmarkedMoplexes.Where(vl => IsClique2(Neighbourhood(vl, graph), graph)).ToList();

            if (simplicialUnmarked.Count > 0)
            {
                foreach (var neighbourhood in simplicialUnmarked)
                {
                    foreach (var v in neighbourhood)
                    {
                        graph.RemoveVertex(v);
                    }
                }
                return(FasterInner(graph, k, r, marked, null, analysis.Moplexes.Except(simplicialUnmarked).ToList(), addedEdges));
            }

            // Moplex with only unmarked vertices and neighbourhood only missing one edge
            Edge <int>    missingEdge         = null;
            HashSet <int> moplexNeighbourhood = null;

            foreach (var moplex in unmarkedMoplexes)
            {
                moplexNeighbourhood = new HashSet <int>(moplex.SelectMany(v => graph.AdjacentEdges(v).Select(e => e.GetOtherVertex(v))));
                foreach (var v in moplex)
                {
                    moplexNeighbourhood.Remove(v);
                }
                var missingEdges = MissingEdges(moplexNeighbourhood, analysis.NeighbourLabels);
                if (missingEdges.Count == 1)
                {
                    missingEdge = missingEdges.First();
                    break;
                }
            }
            if (missingEdge != null)
            {
                HashSet <int> moplexNeighbourhoodMarked = CloneSet(moplexNeighbourhood);
                var           vStar = FindVStar(missingEdge, moplexNeighbourhoodMarked, graph);
                if (vStar == -1)
                {
                    vStar = FindVStar(new Edge <int>(missingEdge.Target, missingEdge.Source), moplexNeighbourhoodMarked, graph); // switch x and y
                }
                marked.Remove(vStar);
                if (marked.Contains(missingEdge.Source))
                {
                    marked.Remove(missingEdge.Source);
                }
                else
                {
                    r--;
                }
                if (marked.Contains(missingEdge.Target))
                {
                    marked.Remove(missingEdge.Target);
                }
                else
                {
                    r--;
                }
                graph.AddEdge(missingEdge);
                var addedEdges1 = CloneSet(addedEdges);
                addedEdges1.Add(missingEdge);
                return(FasterInner(graph, k - 1, r, marked, new List <Edge <int> > {
                    missingEdge
                }, analysis.Moplexes, addedEdges1));
            }

            var markedMoplexes = analysis.Moplexes.Where(vl => vl.TrueForAll(v => marked.Contains(v))).ToList();

            if (markedMoplexes.Count == analysis.Moplexes.Count)
            {
                return(new Tuple <int, HashSet <Edge <int> > >(-1, null));
            }

            if (unmarkedMoplexes.Count > 0)
            {
                var moplex      = unmarkedMoplexes.First();
                var graph1      = CloneGraph(graph);
                var addedEdges1 = CloneSet(addedEdges);
                //branch 1:
                var marked1 = new HashSet <int>(marked);
                moplex.ForEach(v => marked1.Add(v));
                var r1   = r - (marked1.Count - marked.Count);
                var tup1 = FasterInner(graph1, k, r1, marked1, null, analysis.Moplexes, addedEdges1);
                var b1   = tup1.Item1;
                var e1   = tup1.Item2;
                //branch 2:
                var graph2        = CloneGraph(graph);
                var addedEdges2   = CloneSet(addedEdges);
                var neighbourhood = new HashSet <int>();
                foreach (var v in moplex)
                {
                    var vAdj = graph.AdjacentEdges(v);
                    foreach (var e in vAdj)
                    {
                        neighbourhood.Add(e.GetOtherVertex(v));
                    }
                }
                var missingEdges = MissingEdges(neighbourhood, analysis.NeighbourLabels);
                graph2.AddEdgeRange(missingEdges);
                foreach (var e in missingEdges)
                {
                    addedEdges2.Add(e);
                }
                var k2   = k - (missingEdges.Count);
                var tup2 = FasterInner(graph2, k2, r, marked, missingEdges, analysis.Moplexes, addedEdges2);
                var b2   = tup2.Item1;
                var e2   = tup2.Item2;
                if (b1 > -1 && b1 < b2)
                {
                    return(new Tuple <int, HashSet <Edge <int> > >(b1, e1));
                }
                return(new Tuple <int, HashSet <Edge <int> > >(b2, e2));
            }



            return(new Tuple <int, HashSet <Edge <int> > >(-1, null)); //should never happen
        }
Example #6
0
        public static void Tests()
        {
            //Kernel tests
            //TestGraph 1
            var noKernel   = Faster.Run(TestGraph1());
            var withKernel = Faster.RunWithKernel(TestGraph1());

            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph1");
            }
            var noKernelTestGraph   = TestGraph1();
            var withKernelTestGraph = TestGraph1();

            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            var noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            var withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);

            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph1");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph1");
            }

            //TestGraph2
            noKernel   = Faster.Run(TestGraph2());
            withKernel = Faster.RunWithKernel(TestGraph2());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph2");
            }
            noKernelTestGraph   = TestGraph2();
            withKernelTestGraph = TestGraph2();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph2");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph2");
            }

            //TestGraph3
            noKernel   = Faster.Run(TestGraph3());
            withKernel = Faster.RunWithKernel(TestGraph3());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph3");
            }
            noKernelTestGraph   = TestGraph3();
            withKernelTestGraph = TestGraph3();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph3");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph3");
            }

            //TestGraph4
            noKernel   = Faster.Run(TestGraph4());
            withKernel = Faster.RunWithKernel(TestGraph4());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph4");
            }
            noKernelTestGraph   = TestGraph4();
            withKernelTestGraph = TestGraph4();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph4");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph4");
            }

            //TestGraph5
            noKernel   = Faster.Run(TestGraph5());
            withKernel = Faster.RunWithKernel(TestGraph5());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph5");
            }
            noKernelTestGraph   = TestGraph5();
            withKernelTestGraph = TestGraph5();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph5");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph5");
            }

            //TestGraph6
            noKernel   = Faster.Run(TestGraph6());
            withKernel = Faster.RunWithKernel(TestGraph6());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph6");
            }
            noKernelTestGraph   = TestGraph6();
            withKernelTestGraph = TestGraph6();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph6");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph6");
            }


            //TestGraph7
            noKernel   = Faster.Run(TestGraph7());
            withKernel = Faster.RunWithKernel(TestGraph7());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph7");
            }
            noKernelTestGraph   = TestGraph7();
            withKernelTestGraph = TestGraph7();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph7");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph7");
            }


            //TestGraph8
            noKernel   = Faster.Run(TestGraph8());
            withKernel = Faster.RunWithKernel(TestGraph8());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph8");
            }
            noKernelTestGraph   = TestGraph8();
            withKernelTestGraph = TestGraph8();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph8");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph8");
            }


            //TestGraph9
            noKernel   = Faster.Run(TestGraph9());
            withKernel = Faster.RunWithKernel(TestGraph9());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph9");
            }
            noKernelTestGraph   = TestGraph9();
            withKernelTestGraph = TestGraph9();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph9");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph9");
            }


            //TestGraph10
            noKernel   = Faster.Run(TestGraph10());
            withKernel = Faster.RunWithKernel(TestGraph10());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph10");
            }
            noKernelTestGraph   = TestGraph10();
            withKernelTestGraph = TestGraph10();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph10");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph10");
            }


            //TestGraph11
            noKernel   = Faster.Run(TestGraph11());
            withKernel = Faster.RunWithKernel(TestGraph11());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph11");
            }
            noKernelTestGraph   = TestGraph11();
            withKernelTestGraph = TestGraph11();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph11");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph11");
            }


            //TestGraph12
            noKernel   = Faster.Run(TestGraph12());
            withKernel = Faster.RunWithKernel(TestGraph12());
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test TestGraph12");
            }
            noKernelTestGraph   = TestGraph12();
            withKernelTestGraph = TestGraph12();
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal TestGraph12");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal TestGraph12");
            }

            //Test of external graph20.graph
            var graph1 = Program.ParseFile(@"..\..\testdata\20.graph", false);
            var graph2 = Program.ParseFile(@"..\..\testdata\20.graph", false);

            noKernel   = Faster.Run(graph1);
            withKernel = Faster.RunWithKernel(graph2);
            if (noKernel.Item1 != withKernel.Item1)
            {
                throw new Exception("different k in kernel test graph20.graph");
            }
            noKernelTestGraph   = Program.ParseFile(@"..\..\testdata\20.graph", false);
            withKernelTestGraph = Program.ParseFile(@"..\..\testdata\20.graph", false);
            noKernelTestGraph.AddEdgeRange(noKernel.Item2);
            withKernelTestGraph.AddEdgeRange(withKernel.Item2);
            noKernelAnalysis   = MoplexAnalysis.AnalyseGraph(noKernelTestGraph, null, null);
            withKernelAnalysis = MoplexAnalysis.AnalyseGraph(withKernelTestGraph, null, null);
            if (!Faster.IsChordal2(noKernelAnalysis, noKernelTestGraph))
            {
                throw new Exception("nokernel is not chordal graph20.graph");
            }
            if (!Faster.IsChordal2(withKernelAnalysis, withKernelTestGraph))
            {
                throw new Exception("withkernel is not chordal graph20.graph");
            }


            Console.WriteLine("kernel tests succeeded");

            //v* tests
            var analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph2(), null, null);
            var vStar    = Faster.FindVStar(new Edge <int>(0, 7), new HashSet <int>(TestGraphs.TestGraph2().Vertices), TestGraphs.TestGraph2());

            if (vStar != 6)
            {
                throw new Exception("Error in VStar");
            }

            analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph8(), null, null);
            if (analysis.Moplexes.Count != 5)
            {
                throw new Exception("Error in findmoplex without previous");
            }

            analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph9(), new List <Edge <int> > {
                new Edge <int>(0, 4)
            }, analysis.Moplexes);
            if (analysis.Moplexes.Count != 3)
            {
                throw new Exception("Error in findmoplex with previous");
            }


            analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph10(), null, null);
            if (analysis.Moplexes.Count != 2)
            {
                throw new Exception("Error in findmoplex without previous");
            }

            analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph5(), null, null);
            if (analysis.Moplexes.Count != 4)
            {
                throw new Exception("Error in findmoplex without previous");
            }

            analysis = MoplexAnalysis.AnalyseGraph(TestGraphs.TestGraph11(), new List <Edge <int> > {
                new Edge <int>(0, 4)
            }, analysis.Moplexes);
            if (analysis.Moplexes.Count != 3)
            {
                throw new Exception("Error in findmoplex without previous");
            }

            //four cycle test
            var a = Faster.FindFourCycle1(TestGraphs.TestGraph2());
            var b = Faster.FindFourCycle2(TestGraphs.TestGraph2());
            var c = Faster.FindFourCycle3(TestGraphs.TestGraph2());

            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph4());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph4());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph4());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph5());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph5());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph5());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph6());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph6());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph6());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            //var g = TestGraph8reorder(); //weirdness test TODO needs fix or convincing argument for why not
            //a = Faster.FindFourCycle1(g);
            //b = Faster.FindFourCycle2(g);
            //c = Faster.FindFourCycle3(g);
            //if (a != b && !a.SequenceEqual(b))
            //    throw new Exception("difference between findFourCycle1 & 2");
            //if (a != c && !a.SequenceEqual(c))
            //    throw new Exception("difference between findFourCycle1 & 3");

            a = Faster.FindFourCycle1(TestGraphs.TestGraph8());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph8());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph8());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph13());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph13());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph13());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph14());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph14());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph14());
            if (a != b && !a.SequenceEqual(b))
            {
                throw new Exception("difference between findFourCycle1 & 2");
            }
            if (a != c && !a.SequenceEqual(c))
            {
                throw new Exception("difference between findFourCycle1 & 3");
            }
            a = Faster.FindFourCycle1(TestGraphs.TestGraph15());
            b = Faster.FindFourCycle2(TestGraphs.TestGraph15());
            c = Faster.FindFourCycle3(TestGraphs.TestGraph15());
            // In this graph, the rithms find different cycles. I believe this to be ok, so have disabled the sequenceequal
            if (a != null && a.Count != 4)
            {
                throw new Exception("error in findFourCycle1");
            }
            if (b != null && b.Count != 4)
            {
                throw new Exception("error in findFourCycle2");
            }
            if (c != null && c.Count != 4)
            {
                throw new Exception("error in findFourCycle1ยจ3");
            }
            if ((a == b && a != c) || (b == c && b != a))
            {
                throw new Exception("difference between cycle rithms");
            }



            // Too big k test
            (var k1, var ret1) = Faster.FasterInner(TestGraphs.TestGraph8(), 8, 16, new HashSet <int>(), null, null, new HashSet <Edge <int> >());
            (var k2, var ret2) = Faster.Run(TestGraphs.TestGraph8());
            if ((8 - k1) != k2)
            {
                throw new Exception("Wrong result if k is started too big");
            }
        }