/// <summary>
        /// Test the specified graph.
        /// </summary>
        /// <param name="graph">Graph to be tested.</param>
        public static void Test(Graph graph)
        {
            var graph_2 = (Graph)graph.Clone();

            var edges = graph.E
                        .Select(e => new WeightedEdge <Vertex> (e.U, e.V, e.W))
                        .ToList();

            var quickGraph = new UndirectedGraph <Vertex, WeightedEdge <Vertex> > ();

            quickGraph.AddVertexRange(graph.V);
            quickGraph.AddEdgeRange(edges);

            var customBoruvkaMst = BoruvkaMST.FindMST(graph);
            var customKruskalMst = KruskalMST.FindMST(graph_2);
            var quickGraphMst    = quickGraph.MinimumSpanningTreeKruskal(e => e.Weight);

            if (!(customBoruvkaMst.Length == customKruskalMst.Length &&
                  customKruskalMst.Length == quickGraphMst.Count()))
            {
                throw new Exception("Something wrong with the number of edges.");
            }

            var boruvkaWeight    = customBoruvkaMst.Select(e => new BigInteger(e.W)).Aggregate(BigInteger.Add);
            var kruskalWeight    = customKruskalMst.Select(e => new BigInteger(e.W)).Aggregate(BigInteger.Add);
            var quickGraphWeight = quickGraphMst.Select(e => new BigInteger(e.Weight)).Aggregate(BigInteger.Add);

            if (!(boruvkaWeight == kruskalWeight &&
                  kruskalWeight == quickGraphWeight))
            {
                throw new Exception("Something wrong with MST weight.");
            }
        }
예제 #2
0
        //Graph from Separability Generalizes Dirac's Theorem
        public static UndirectedGraph <int, Edge <int> > TestGraph1()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5, 6, 7 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(0, 1),
                new Edge <int>(0, 2),
                new Edge <int>(0, 4),
                new Edge <int>(0, 5),
                new Edge <int>(1, 2),
                new Edge <int>(1, 4),
                new Edge <int>(1, 5),
                new Edge <int>(2, 5),
                new Edge <int>(2, 6),
                new Edge <int>(3, 5),
                new Edge <int>(3, 6),
                new Edge <int>(4, 7),
                new Edge <int>(5, 7),
                new Edge <int>(6, 7)
            };

            g.AddEdgeRange(edges);

            return(g);
        }
예제 #3
0
        // Graph with 3-vertex moplex {0,1,2}, 6-vertex cycle, and "false" moplex triangle
        public static UndirectedGraph <int, Edge <int> > TestGraph2()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(0, 1),
                new Edge <int>(0, 2),
                new Edge <int>(0, 3),
                new Edge <int>(1, 2),
                new Edge <int>(1, 3),
                new Edge <int>(2, 3),
                new Edge <int>(3, 4),
                new Edge <int>(3, 10),
                new Edge <int>(4, 5),
                new Edge <int>(4, 6),
                new Edge <int>(5, 6),
                new Edge <int>(5, 8),
                new Edge <int>(6, 7),
                new Edge <int>(8, 9),
                new Edge <int>(9, 10)
            };

            g.AddEdgeRange(edges);

            return(g);
        }
        private void Initialize()
        {
            _graph = new UndirectedGraph <PointVertex, Edge <PointVertex> >();
            _nodes.Clear();
            foreach (Obstacle obstacle in _obstacles)
            {
                foreach (RotationTreeNode node in obstacle.Nodes)
                {
                    _nodes.Add(node);
                    _graph.AddVertex(new PointVertex(node.Point));
                }
                _graph.AddEdgeRange(obstacle.Segments.Select(s => new Edge <PointVertex>(new PointVertex(s.Point1.Point), new PointVertex(s.Point2.Point))));
            }
            foreach (Point point in _singlePoints)
            {
                Obstacle obstacle = _obstacles.FirstOrDefault(o => o.Contains(point));
                var      newPoint = new RotationTreeNode(obstacle, point, true);
                _graph.AddVertex(new PointVertex(point));
                _nodes.Add(newPoint);
            }

            double maxX = _nodes.Max(p => p.Point.X);

            _plusInf  = new RotationTreeNode(new Point(maxX + 100, double.PositiveInfinity));
            _minusInf = new RotationTreeNode(new Point(maxX + 100, double.NegativeInfinity));
            _plusInf.AddChild(_minusInf);
            foreach (RotationTreeNode node in _nodes.OrderByDescending(n => n))
            {
                _minusInf.AddChild(node);
            }
        }
        public UndirectedGraph <int, Edge <int> > GetFullGraph(int verticesCount)
        {
            var edgeSet = new HashSet <Edge <int> >(new EdgeComparer());

            if (verticesCount < 1)
            {
                throw new ArgumentException("There must be at lest 1 vertex in a graph");
            }
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(Enumerable.Range(0, verticesCount));

            foreach (var sourceVertex in g.Vertices)
            {
                foreach (var targetVertex in g.Vertices)
                {
                    if (sourceVertex == targetVertex)
                    {
                        continue;
                    }
                    edgeSet.Add(new Edge <int>(sourceVertex, targetVertex));
                }
            }
            g.AddEdgeRange(edgeSet);

            return(g);
        }
        public IsEulerianGraphAlgorithm(UndirectedGraph <TVertex, UndirectedEdge <TVertex> > graph)
        {
            var newGraph = new UndirectedGraph <TVertex, UndirectedEdge <TVertex> >(false, graph.EdgeEqualityComparer);

            newGraph.AddVertexRange(graph.Vertices);
            newGraph.AddEdgeRange(graph.Edges);
            EdgePredicate <TVertex, UndirectedEdge <TVertex> > isLoop = e => e.Source.Equals(e.Target);

            newGraph.RemoveEdgeIf(isLoop);
            this.graph = newGraph;
        }
예제 #7
0
    public int GetConnectedComponents()
    {
        var graph = new UndirectedGraph <Voxel, Edge <Voxel> >();

        graph.AddVertexRange(GetVoxels().Where(v => v.IsActive));
        graph.AddEdgeRange(GetFaces().Where(f => f.IsActive).Select(f => new Edge <Voxel>(f.Voxels[0], f.Voxels[1])));

        Dictionary <Voxel, int> components = new Dictionary <Voxel, int>();
        var count = QuickGraph.Algorithms.AlgorithmExtensions.ConnectedComponents(graph, components);

        return(count);
    }
 private UndirectedGraph<int, UndirectedEdge<int>> BuildGraph(int[] verticies, int[] edges)
 {
     var graph = new UndirectedGraph<int, UndirectedEdge<int>>();
     graph.AddVertexRange(verticies);
     var convEdges = new UndirectedEdge<int>[edges.Length / 2];
     for (int i = 0; i < edges.Length; i += 2)
     {
         convEdges[i / 2] = new UndirectedEdge<int>(edges[i], edges[i + 1]);
     }
     graph.AddEdgeRange(convEdges);
     return graph;
 }
예제 #9
0
        private UndirectedGraph <int, UndirectedEdge <int> > BuildGraph(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph <int, UndirectedEdge <int> >();

            graph.AddVertexRange(verticies);
            var convEdges = new UndirectedEdge <int> [edges.Length / 2];

            for (int i = 0; i < edges.Length; i += 2)
            {
                convEdges[i / 2] = new UndirectedEdge <int>(edges[i], edges[i + 1]);
            }
            graph.AddEdgeRange(convEdges);
            return(graph);
        }
 private int CalcBicliqueCount(int[] verticies, int[] edges)
 {
     var g = new UndirectedGraph<int, IEdge<int>>();
     g.AddVertexRange(verticies);
     var convEdges = new Edge<int>[edges.Length / 2];
     for (int i = 0; i < edges.Length; i += 2)
     {
         convEdges[i / 2] = new Edge<int>(edges[i], edges[i + 1]);
     }
     g.AddEdgeRange(convEdges);
     var algo = new BipartiteDimensionAlgorithm(g);
     algo.Compute();
     return algo.BipartiteDimensionValue;
 } 
예제 #11
0
        public IsHamiltonianGraphAlgorithm(UndirectedGraph <TVertex, UndirectedEdge <TVertex> > graph)
        {
            // Create new graph without parallel edges
            var newGraph = new UndirectedGraph <TVertex, UndirectedEdge <TVertex> >(false, graph.EdgeEqualityComparer);

            newGraph.AddVertexRange(graph.Vertices);
            newGraph.AddEdgeRange(graph.Edges);
            // Remove loops
            EdgePredicate <TVertex, UndirectedEdge <TVertex> > isLoop = e => e.Source.Equals(e.Target);

            newGraph.RemoveEdgeIf(isLoop);
            this.graph = newGraph;
            threshold  = newGraph.VertexCount / 2.0;
        }
예제 #12
0
        private List<List<int>> InducedPaths(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph<int, IEdge<int>>();

            graph.AddVertexRange(verticies);

            var graphEdges = new Edge<int>[edges.Length / 2];
            for (int i = 0; i < edges.Length; i += 2)
            {
                graphEdges[i / 2] = new Edge<int>(edges[i], edges[i + 1]);
            }
            graph.AddEdgeRange(graphEdges);

            return InducedPathAlgorithm.findInducedPaths(graph);
        }
        private UndirectedGraph <object, UndirectedEdge <object> > BuildGraph(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph <object, UndirectedEdge <object> >();

            graph.AddVertexRange(verticies.Cast <object>());
            var newEdges  = edges.Cast <object>().ToArray();
            var convEdges = new UndirectedEdge <object> [edges.Length / 2];

            for (int i = 0; i < newEdges.Length; i += 2)
            {
                convEdges[i / 2] = new UndirectedEdge <object>(newEdges[i], newEdges[i + 1]);
            }
            graph.AddEdgeRange(convEdges);
            return(graph);
        }
예제 #14
0
        //chordal graph, k = 0
        public static UndirectedGraph <int, Edge <int> > TestGraph7()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 0, 1, 2 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(0, 1),
                new Edge <int>(0, 2),
                new Edge <int>(1, 2),
            };

            g.AddEdgeRange(edges);

            return(g);
        }
예제 #15
0
        private List <List <int> > InducedPaths(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph <int, IEdge <int> >();

            graph.AddVertexRange(verticies);

            var graphEdges = new Edge <int> [edges.Length / 2];

            for (int i = 0; i < edges.Length; i += 2)
            {
                graphEdges[i / 2] = new Edge <int>(edges[i], edges[i + 1]);
            }
            graph.AddEdgeRange(graphEdges);

            return(InducedPathAlgorithm.findInducedPaths(graph));
        }
        private int CalcBicliqueCount(int[] verticies, int[] edges)
        {
            var g = new UndirectedGraph <int, IEdge <int> >();

            g.AddVertexRange(verticies);
            var convEdges = new Edge <int> [edges.Length / 2];

            for (int i = 0; i < edges.Length; i += 2)
            {
                convEdges[i / 2] = new Edge <int>(edges[i], edges[i + 1]);
            }
            g.AddEdgeRange(convEdges);
            var algo = new BipartiteDimensionAlgorithm(g);

            algo.Compute();
            return(algo.BipartiteDimensionValue);
        }
예제 #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IsEulerianGraphAlgorithm{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="graph">Graph to check.</param>
        public IsEulerianGraphAlgorithm([NotNull] IUndirectedGraph <TVertex, TEdge> graph)
        {
            if (graph is null)
            {
                throw new ArgumentNullException(nameof(graph));
            }

            // Create new graph without parallel edges
            var newGraph = new UndirectedGraph <TVertex, TEdge>(
                false,
                graph.EdgeEqualityComparer);

            newGraph.AddVertexRange(graph.Vertices);
            newGraph.AddEdgeRange(graph.Edges);
            newGraph.RemoveEdgeIf(edge => edge.IsSelfEdge());

            _graph = newGraph;
        }
예제 #18
0
        //reordered testgraph 8 to test for weird cycle finder behavior
        public static UndirectedGraph <int, Edge <int> > TestGraph8reorder()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 4, 1, 2, 3, 0 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(3, 4),
                new Edge <int>(2, 4),
                new Edge <int>(1, 4),
                new Edge <int>(0, 1),
                new Edge <int>(0, 2),
                new Edge <int>(0, 3),
            };

            g.AddEdgeRange(edges);

            return(g);
        }
예제 #19
0
        private static UndirectedGraph <int, Edge <int> > GetGraph1()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new List <int> {
                0, 1, 2, 3, 4, 5
            });
            g.AddEdgeRange(new List <Edge <int> >
            {
                new Edge <int>(0, 1),
                new Edge <int>(0, 4),
                new Edge <int>(1, 2),
                new Edge <int>(1, 4),
                new Edge <int>(2, 3),
                new Edge <int>(2, 5),
                new Edge <int>(4, 5),
            });
            return(g);
        }
예제 #20
0
        // weird subset of testgraph14 with added edges, where findcycle2 finds cycle and 3 does not
        public static UndirectedGraph <int, Edge <int> > TestGraph15()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 22, 39, 95, 48, 73, 29, 65, 3, 68, 25, 30, 89, 85, 67, 18, 94, 72, 66, 62, 81, 20 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(3, 22),
                new Edge <int>(73, 22),
                new Edge <int>(39, 29),
                new Edge <int>(39, 20),
                new Edge <int>(95, 85),
                new Edge <int>(30, 95),
                new Edge <int>(48, 66),
                new Edge <int>(48, 62),
                new Edge <int>(18, 48),
                new Edge <int>(3, 73),
                new Edge <int>(73, 62),
                new Edge <int>(89, 73),
                new Edge <int>(29, 85),
                new Edge <int>(94, 65),
                new Edge <int>(89, 65),
                new Edge <int>(65, 68),
                new Edge <int>(65, 3),
                new Edge <int>(68, 72),
                new Edge <int>(25, 66),
                new Edge <int>(18, 25),
                new Edge <int>(89, 25),
                new Edge <int>(81, 30),
                new Edge <int>(89, 94),
                new Edge <int>(72, 67),
                new Edge <int>(67, 20),
                new Edge <int>(18, 66),
                new Edge <int>(66, 62),
                new Edge <int>(81, 20)
            };

            g.AddEdgeRange(edges);


            return(g);
        }
예제 #21
0
파일: Faster.cs 프로젝트: Madsen90/Pace17
        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));
        }
예제 #22
0
        // Graph where all vertices are moplexes
        public static UndirectedGraph <int, Edge <int> > TestGraph3()
        {
            var g = new UndirectedGraph <int, Edge <int> >();

            g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5 });
            var edges = new List <Edge <int> >
            {
                new Edge <int>(0, 3),
                new Edge <int>(0, 4),
                new Edge <int>(0, 5),
                new Edge <int>(1, 3),
                new Edge <int>(1, 4),
                new Edge <int>(1, 5),
                new Edge <int>(2, 3),
                new Edge <int>(2, 4),
                new Edge <int>(2, 5)
            };

            g.AddEdgeRange(edges);

            return(g);
        }
예제 #23
0
        private UndirectedGraph <int, Edge <int> > GetSampleForest(out int[] levels)
        {
            var forest      = new UndirectedGraph <int, Edge <int> >();
            int vertexCount = 19;

            levels = new int[vertexCount];
            forest.AddVertexRange(Enumerable.Range(0, vertexCount));

            levels[2] = levels[11] = levels[12] = 0;
            levels[1] = levels[3] = levels[13] = 1;
            levels[0] = levels[4] = levels[14] = 2;
            levels[5] = levels[7] = levels[9] = levels[15] = levels[17] = 3;
            levels[6] = levels[8] = levels[10] = levels[16] = levels[18] = 4;

            forest.AddEdgeRange(new List <Edge <int> >
            {
                new Edge <int>(0, 1),
                new Edge <int>(2, 1),
                new Edge <int>(2, 3),
                new Edge <int>(4, 3),
                new Edge <int>(4, 5),
                new Edge <int>(4, 7),
                new Edge <int>(4, 9),
                new Edge <int>(5, 6),
                new Edge <int>(7, 8),
                new Edge <int>(9, 10),
                new Edge <int>(12, 13),
                new Edge <int>(13, 14),
                new Edge <int>(14, 15),
                new Edge <int>(14, 17),
                new Edge <int>(17, 18),
                new Edge <int>(18, 16),
                new Edge <int>(15, 16),
            });

            return(forest);
        }
예제 #24
0
파일: Program.cs 프로젝트: Madsen90/Pace17
        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);
        }
예제 #25
0
        private void Initialize()
        {
            _graph = new UndirectedGraph<PointVertex, Edge<PointVertex>>();
            _nodes.Clear();
            foreach (Obstacle obstacle in _obstacles)
            {
                foreach (RotationTreeNode node in obstacle.Nodes)
                {
                    _nodes.Add(node);
                    _graph.AddVertex(new PointVertex(node.Point));
                }
                _graph.AddEdgeRange(obstacle.Segments.Select(s => new Edge<PointVertex>(new PointVertex(s.Point1.Point), new PointVertex(s.Point2.Point))));
            }
            foreach (Point point in _singlePoints)
            {
                Obstacle obstacle = _obstacles.FirstOrDefault(o => o.Contains(point));
                var newPoint = new RotationTreeNode(obstacle, point, true);
                _graph.AddVertex(new PointVertex(point));
                _nodes.Add(newPoint);
            }

            double maxX = _nodes.Max(p => p.Point.X);
            _plusInf = new RotationTreeNode(new Point(maxX + 100, double.PositiveInfinity));
            _minusInf = new RotationTreeNode(new Point(maxX + 100, double.NegativeInfinity));
            _plusInf.AddChild(_minusInf);
            foreach (RotationTreeNode node in _nodes.OrderByDescending(n => n))
                _minusInf.AddChild(node);
        }
예제 #26
0
        public IUndirectedGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects)
        {
            var tree     = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false);
            var clusters = new List <Cluster <T> >();

            foreach (T dataObject in dataObjects)
            {
                var cluster = new Cluster <T>(dataObject)
                {
                    Description = dataObject.ToString()
                };
                clusters.Add(cluster);
                tree.AddVertex(cluster);
            }
            var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>();

            for (int i = 0; i < clusters.Count; i++)
            {
                for (int j = i + 1; j < clusters.Count; j++)
                {
                    double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First());
                    if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0)
                    {
                        throw new ArgumentException("Invalid distance between data objects.", "dataObjects");
                    }
                    distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance;
                }
            }

            while (clusters.Count > 2)
            {
                Dictionary <Cluster <T>, double> r = clusters.ToDictionary(c => c, c => clusters.Where(oc => oc != c).Sum(oc => distances[UnorderedTuple.Create(c, oc)] / (clusters.Count - 2)));
                int    minI = 0, minJ = 0;
                double minDist = 0, minQ = double.MaxValue;
                for (int i = 0; i < clusters.Count; i++)
                {
                    for (int j = i + 1; j < clusters.Count; j++)
                    {
                        double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])];
                        double q    = dist - r[clusters[i]] - r[clusters[j]];
                        if (q < minQ)
                        {
                            minQ    = q;
                            minDist = dist;
                            minI    = i;
                            minJ    = j;
                        }
                    }
                }

                Cluster <T> iCluster = clusters[minI];
                Cluster <T> jCluster = clusters[minJ];
                distances.Remove(UnorderedTuple.Create(iCluster, jCluster));

                var uCluster = new Cluster <T>();
                tree.AddVertex(uCluster);

                double iLen = (minDist / 2) + ((r[iCluster] - r[jCluster]) / 2);
                if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(iCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(iCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0)));
                }
                double jLen = minDist - iLen;
                if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(jCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(jCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0)));
                }

                foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster))
                {
                    UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster);
                    UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster);
                    distances[UnorderedTuple.Create(kCluster, uCluster)] = (distances[kiKey] + distances[kjKey] - minDist) / 2;
                    distances.Remove(kiKey);
                    distances.Remove(kjKey);
                }
                clusters.RemoveAt(minJ);
                clusters.RemoveAt(minI);
                clusters.Add(uCluster);
            }

            if (clusters.Count == 2)
            {
                tree.AddEdge(new ClusterEdge <T>(clusters[1], clusters[0], distances[UnorderedTuple.Create(clusters[0], clusters[1])]));
                clusters.RemoveAt(0);
            }

            var unrootedTree = new UndirectedGraph <Cluster <T>, ClusterEdge <T> >(false);

            unrootedTree.AddVertexRange(tree.Vertices);
            unrootedTree.AddEdgeRange(tree.Edges);
            return(unrootedTree);
        }
예제 #27
0
파일: Faster.cs 프로젝트: Madsen90/Pace17
        public static int FindVStar(Edge <int> missingEdge, HashSet <int> neighbourhood, UndirectedGraph <int, Edge <int> > graph)
        {
            var x         = missingEdge.Source;
            var y         = missingEdge.Target;
            var component = new UndirectedGraph <int, Edge <int> >();
            var visited   = new HashSet <int> {
                x
            };
            var complete = new List <List <int> >();

            component.AddVertexRange(neighbourhood);
            foreach (var v in neighbourhood)
            {
                component.AddEdgeRange(graph.AdjacentEdges(v).Where(e => component.ContainsVertex(e.GetOtherVertex(v)))); //adds edges not in component, however, since no target vertices will exist if not in the component, these edges will be ignored by QuickGraph
            }
            Queue <List <int> > q = new Queue <List <int> >();

            foreach (var e in component.AdjacentEdges(x))
            {
                var n = e.GetOtherVertex(x);
                var l = new List <int> {
                    x, n
                };
                q.Enqueue(l);
            }
            while (q.Count > 0)
            {
                var l = q.Dequeue();
                var n = l.Last();
                if (visited.Contains(n)) // What if they have same iteration number?
                {
                    continue;            // l is not cordless.
                }
                if (n == y)
                {
                    complete.Add(l); // The coordless path is complete
                    continue;
                }
                visited.Add(n);

                foreach (var e in graph.AdjacentEdges(n))
                {
                    var v = e.GetOtherVertex(n);
                    if (visited.Contains(v))
                    {
                        continue;
                    }
                    var l2 = CloneList(l);
                    l2.Add(v);
                    q.Enqueue(l2);
                }
            }
            complete.ForEach(l => l.Remove(y));
            List <int> vStars = complete.Select(l => l.Last()).ToList();

            if (vStars.Any())
            {
                int vStar = vStars.First();
                if (vStars.TrueForAll(v => v == vStar))
                {
                    return(vStar);
                }
            }

            return(-1);
        }
        public void Test_BronKerbosch()
        {
            var zipCodeList = XDocument.Load("XMLFile1.xml")
                              .Root.Element("SimpleCodeList")
                              .Elements("Row")
                              .Elements("Value")
                              .Elements("ComplexValue")
                              .Select(i => new
            {
                ZipCode      = (string)i.Element(ns3 + "zipCode"),
                LocationCode = (string)i.Element(ns3 + "locationCode"),
                CaseType     = (string)i.Element(ns3 + "caseType"),
                CaseCategory = (string)i.Element(ns3 + "caseCategory")
            })
                              .ToList();

            var categoryList = XDocument.Load("XMLFile2.xml")
                               .Root.Element("SimpleCodeList")
                               .Elements("Row")
                               .Elements("Value")
                               .Where(i => (string)i.Attribute("ColumnRef") == "code")
                               .Elements("SimpleValue")
                               .Select(i => (string)i)
                               .ToList();

            var zipCodes   = zipCodeList.Select(i => i.ZipCode).Where(i => i != null).Distinct().ToList();
            var locations  = zipCodeList.Select(i => i.LocationCode).Where(i => i != null).Distinct().ToList();
            var types      = zipCodeList.Select(i => i.CaseType).Where(i => i != null).Distinct().ToList();
            var categories = categoryList.Where(i => i != null).Distinct().ToList();

            SEquatableUndirectedEdge <string> CreateEdge(string item1, string item2)
            {
                return(Comparer <string> .Default.Compare(item1, item2) <= 0 ? new SEquatableUndirectedEdge <string>(item1, item2) : new SEquatableUndirectedEdge <string>(item2, item1));
            }

            var g = new UndirectedGraph <string, SEquatableUndirectedEdge <string> >();

            foreach (var zipCode in zipCodes)
            {
                g.AddVertex("ZIPCODE:" + zipCode);
            }

            foreach (var location in locations)
            {
                g.AddVertex("LOCATION:" + location);
            }

            foreach (var type in types)
            {
                g.AddVertex("TYPE:" + type);
            }

            foreach (var category in categories)
            {
                g.AddVertex("CATEGORY:" + category);
            }

            foreach (var items in zipCodeList.Where(i => i.CaseType != null).Distinct())
            {
                g.AddVertex("TYPE:" + items.CaseType);
            }

            foreach (var items in zipCodeList.Where(i => i.CaseCategory != null).Distinct())
            {
                g.AddVertex("CATEGORY:" + items.CaseCategory);
            }

            foreach (var zipcode in zipCodes)
            {
                foreach (var zipCode2 in zipCodes)
                {
                    if (zipcode != zipCode2)
                    {
                        g.AddVerticesAndEdge(CreateEdge("ZIPCODE:" + zipcode, "ZIPCODE:" + zipCode2));
                    }
                }
            }

            foreach (var location in locations)
            {
                foreach (var location2 in locations)
                {
                    if (location != location2)
                    {
                        g.AddVerticesAndEdge(CreateEdge("LOCATION:" + location, "LOCATION:" + location2));
                    }
                }
            }

            foreach (var type in types)
            {
                foreach (var type2 in types)
                {
                    if (type != type2)
                    {
                        g.AddVerticesAndEdge(CreateEdge("TYPE:" + type, "TYPE:" + type2));
                    }
                }
            }

            foreach (var category in categories)
            {
                foreach (var category2 in categories)
                {
                    if (category != category2)
                    {
                        g.AddVerticesAndEdge(CreateEdge("CATEGORY:" + category, "CATEGORY:" + category2));
                    }
                }
            }

            foreach (var zipCode in zipCodes)
            {
                foreach (var item in zipCodeList.Where(i => i.ZipCode == zipCode))
                {
                    if (item.LocationCode != null)
                    {
                        g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "LOCATION:" + item.LocationCode));
                    }
                    else
                    {
                        g.AddEdgeRange(types.Select(location => CreateEdge("ZIPCODE:" + zipCode, "LOCATION:" + location)));
                    }

                    if (item.CaseType != null)
                    {
                        g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "TYPE:" + item.CaseType));
                    }
                    else
                    {
                        g.AddEdgeRange(types.Select(type => CreateEdge("ZIPCODE:" + zipCode, "TYPE:" + type)));
                    }

                    if (item.CaseCategory != null)
                    {
                        g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "CATEGORY:" + item.CaseCategory));
                    }
                    else
                    {
                        g.AddEdgeRange(categories.Select(category => CreateEdge("ZIPCODE:" + zipCode, "CATEGORY:" + category)));
                    }
                }
            }

            foreach (var location in locations)
            {
                foreach (var item in zipCodeList.Where(i => i.LocationCode == location))
                {
                    if (item.ZipCode != null)
                    {
                        g.AddEdge(CreateEdge("LOCATION:" + location, "ZIPCODE:" + item.ZipCode));
                    }
                    else
                    {
                        g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("LOCATION:" + location, "ZIPCODE:" + zipCode)));
                    }

                    if (item.CaseType != null)
                    {
                        g.AddEdge(CreateEdge("LOCATION:" + location, "TYPE:" + item.CaseType));
                    }
                    else
                    {
                        g.AddEdgeRange(types.Select(type => CreateEdge("LOCATION:" + location, "TYPE:" + type)));
                    }

                    if (item.CaseCategory != null)
                    {
                        g.AddEdge(CreateEdge("LOCATION:" + location, "CATEGORY:" + item.CaseCategory));
                    }
                    else
                    {
                        g.AddEdgeRange(categories.Select(category => CreateEdge("LOCATION:" + location, "CATEGORY:" + category)));
                    }
                }
            }

            foreach (var type in types)
            {
                foreach (var item in zipCodeList.Where(i => i.CaseType == type))
                {
                    if (item.ZipCode != null)
                    {
                        g.AddEdge(CreateEdge("TYPE:" + type, "ZIPCODE:" + item.ZipCode));
                    }
                    else
                    {
                        g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("TYPE:" + type, "ZIPCODE:" + zipCode)));
                    }

                    if (item.LocationCode != null)
                    {
                        g.AddEdge(CreateEdge("TYPE:" + type, "LOCATION:" + item.LocationCode));
                    }
                    else
                    {
                        g.AddEdgeRange(locations.Select(location => CreateEdge("TYPE:" + type, "LOCATION:" + location)));
                    }

                    if (item.CaseCategory != null)
                    {
                        g.AddEdge(CreateEdge("TYPE:" + type, "CATEGORY:" + item.CaseCategory));
                    }
                    else
                    {
                        g.AddEdgeRange(categories.Select(category => CreateEdge("TYPE:" + type, "CATEGORY:" + category)));
                    }
                }
            }

            foreach (var category in categories)
            {
                foreach (var item in zipCodeList.Where(i => i.CaseCategory == category))
                {
                    if (item.ZipCode != null)
                    {
                        g.AddEdge(CreateEdge("CATEGORY:" + category, "ZIPCODE:" + item.ZipCode));
                    }
                    else
                    {
                        g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("CATEGORY:" + category, "ZIPCODE:" + zipCode)));
                    }

                    if (item.LocationCode != null)
                    {
                        g.AddEdge(CreateEdge("CATEGORY:" + category, "LOCATION:" + item.LocationCode));
                    }
                    else
                    {
                        g.AddEdgeRange(locations.Select(location => CreateEdge("CATEGORY:" + category, "LOCATION:" + location)));
                    }

                    if (item.CaseType != null)
                    {
                        g.AddEdge(CreateEdge("CATEGORY:" + category, "TYPE:" + item.CaseType));
                    }
                    else
                    {
                        g.AddEdgeRange(types.Select(type => CreateEdge("CATEGORY:" + category, "TYPE:" + type)));
                    }
                }
            }

            var sw = new Stopwatch();

            sw.Start();
            //var r1 = g.BronKerbosh();
            sw.Stop();
            TestContext.WriteLine($"MaximalCliques took {sw.Elapsed}.");
            sw.Reset();

            sw.Start();
            var r2 = g.BronKerboshDegeneracy();

            sw.Stop();
            TestContext.WriteLine($"MaximalCliquesDegeneracy took {sw.Elapsed}.");
            sw.Reset();

            sw.Start();
            var r3 = g.BronKerboshPivot();

            sw.Stop();
            TestContext.WriteLine($"MaximalCliquesPivot took {sw.Elapsed}.");
            sw.Reset();

            r2 = r2.Where(i => i.Any(j => j.StartsWith("ZIPCODE")) && i.Any(j => j.StartsWith("LOCATION")) && i.Any(j => j.StartsWith("TYPE")) && i.Any(j => j.StartsWith("CATEGORY"))).ToList();
            r3 = r3.Where(i => i.Any(j => j.StartsWith("ZIPCODE")) && i.Any(j => j.StartsWith("LOCATION")) && i.Any(j => j.StartsWith("TYPE")) && i.Any(j => j.StartsWith("CATEGORY"))).ToList();

            r2.Should().HaveCount(72);
            r3.Should().HaveCount(72);
        }
예제 #29
0
        public void RemoveEdges()
        {
            int verticesRemoved = 0;
            int edgesRemoved    = 0;

            var graph = new UndirectedGraph <int, Edge <int> >();

            graph.VertexRemoved += v =>
            {
                Assert.IsNotNull(v);
                ++verticesRemoved;
            };

            graph.EdgeRemoved += e =>
            {
                Assert.IsNotNull(e);
                // ReSharper disable once AccessToModifiedClosure
                ++edgesRemoved;
            };

            var edge12         = new Edge <int>(1, 2);
            var edge13         = new Edge <int>(1, 3);
            var edge13Bis      = new Edge <int>(1, 3);
            var edge14         = new Edge <int>(1, 4);
            var edge24         = new Edge <int>(2, 4);
            var edge31         = new Edge <int>(3, 1);
            var edge33         = new Edge <int>(3, 3);
            var edgeNotInGraph = new Edge <int>(3, 2);

            graph.AddVertexRange(new[] { 1, 2, 3, 4 });
            graph.AddEdgeRange(new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 });

            Assert.AreEqual(0, graph.RemoveEdges(Enumerable.Empty <Edge <int> >()));
            CheckCounters(0);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 });

            Assert.AreEqual(2, graph.RemoveEdges(new[] { edge12, edge13Bis }));
            CheckCounters(2);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge13, edge14, edge24, edge31, edge33 });

            Assert.AreEqual(2, graph.RemoveEdges(new[] { edge13, edge14, edgeNotInGraph }));
            CheckCounters(2);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge24, edge31, edge33 });

            Assert.AreEqual(3, graph.RemoveEdges(new[] { edge24, edge31, edge33 }));
            CheckCounters(3);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertNoEdge(graph);

            #region Local function

            void CheckCounters(int expectedRemovedEdges)
            {
                Assert.AreEqual(0, verticesRemoved);
                Assert.AreEqual(expectedRemovedEdges, edgesRemoved);
                edgesRemoved = 0;
            }

            #endregion
        }
예제 #30
0
        // troublesome component from instances/5.graph without two single-edge-connected-components which should have no minfil edges
        public static UndirectedGraph <int, Edge <int> > TestGraph14()
        {
            var g     = new UndirectedGraph <int, Edge <int> >();
            var edges = new List <Edge <int> >
            {
                new Edge <int>(29, 9),
                new Edge <int>(39, 29),
                new Edge <int>(9, 85),
                new Edge <int>(39, 20),
                new Edge <int>(39, 91),
                new Edge <int>(39, 4),
                new Edge <int>(47, 39),
                new Edge <int>(39, 97),
                new Edge <int>(95, 85),
                new Edge <int>(67, 20),
                new Edge <int>(72, 67),
                new Edge <int>(81, 20),
                new Edge <int>(68, 72),
                new Edge <int>(81, 30),
                new Edge <int>(74, 81),
                new Edge <int>(48, 75),
                new Edge <int>(18, 48),
                new Edge <int>(48, 60),
                new Edge <int>(75, 62),
                new Edge <int>(18, 70),
                new Edge <int>(18, 82),
                new Edge <int>(18, 66),
                new Edge <int>(18, 60),
                new Edge <int>(34, 18),
                new Edge <int>(18, 49),
                new Edge <int>(66, 62),
                new Edge <int>(73, 62),
                new Edge <int>(25, 66),
                new Edge <int>(34, 49),
                new Edge <int>(10, 34),
                new Edge <int>(25, 49),
                new Edge <int>(65, 93),
                new Edge <int>(94, 65),
                new Edge <int>(65, 3),
                new Edge <int>(89, 65),
                new Edge <int>(65, 68),
                new Edge <int>(46, 93),
                new Edge <int>(89, 94),
                new Edge <int>(3, 22),
                new Edge <int>(89, 25),
                new Edge <int>(89, 73),
                new Edge <int>(46, 80),
                new Edge <int>(77, 46),
                new Edge <int>(46, 52),
                new Edge <int>(91, 1),
                new Edge <int>(4, 91),
                new Edge <int>(4, 43),
                new Edge <int>(25, 10),
                new Edge <int>(73, 22),
                new Edge <int>(30, 95),
                new Edge <int>(74, 55),
            };

            foreach (var edge in edges)
            {
                if (!g.ContainsVertex(edge.Source))
                {
                    g.AddVertex(edge.Source);
                }
                if (!g.ContainsVertex(edge.Target))
                {
                    g.AddVertex(edge.Target);
                }
            }
            g.AddEdgeRange(edges);

            return(g);
        }
예제 #31
0
        private static List <List <int> > FindMoplexes(
            UndirectedGraph <int, Edge <int> > graph,
            Dictionary <int, int> revOrdering,
            Dictionary <int, int> ordering,
            Dictionary <int, List <int> > labels,
            List <Edge <int> > newlyAddedEdges,
            List <List <int> > prevMoplexes)
        {
            var moplexes = new List <List <int> >();

            var hasBeenChecked = new List <int>();

            if (newlyAddedEdges != null) //newly added edge means that the moplexes effected must be recalculated.
            {
                if (prevMoplexes != null)
                {
                    foreach (var e in newlyAddedEdges)
                    {
                        var validMoplexes = prevMoplexes.Where(moplex => //this should not work!?!?! We add moplexes if they are not effected by the first edge
                                                               e.Source != moplex.First() &&
                                                               e.Target != moplex.First() &&
                                                               graph.AdjacentEdges(moplex.First())
                                                               .Select(edge => edge.GetOtherVertex(moplex.First()))
                                                               .All(v => v != e.Source && v != e.Target)
                                                               ).ToList();
                        moplexes.AddRange(validMoplexes);
                        hasBeenChecked.AddRange(validMoplexes.SelectMany(i => i).Distinct());
                    }
                }
            }
            else if (prevMoplexes != null)  // no newly added edge, so previously calculated moplex must still be relevant.
            {
                moplexes.AddRange(prevMoplexes);
                hasBeenChecked.AddRange(prevMoplexes.SelectMany(m => m).ToList());
            }


            // Start finding new moplexes
            foreach (var v in labels.Keys)
            {
                if (hasBeenChecked.Contains(v)) // no vertex can be part of multiple moplexes
                {
                    continue;
                }

                //equal neighbourhood check
                var potMoplex = new List <int>();
                foreach (var i in labels.Keys)
                {
                    if (labels[i] != null && labels[i].SequenceEqual(labels[v]))
                    {
                        potMoplex.Add(i);
                    }
                }


                //find neighbourhood excl. the potential moplex, i.e. the seperator
                var seperator = labels[v].Select(l => revOrdering[l]).Except(potMoplex).ToList();


                // Check that the seperator is minimal - i.e. check all vertices in the seperator is connected to all components
                // First: Remove seperator and moplex from graph (temporarily)
                var tempRemove = new List <Edge <int> >();
                foreach (int mv in potMoplex)
                {
                    tempRemove.AddRange(graph.AdjacentEdges(mv));
                    graph.RemoveVertex(mv);
                }

                foreach (var sv in seperator)
                {
                    tempRemove.AddRange(graph.AdjacentEdges(sv));
                    graph.RemoveVertex(sv);
                }

                // Find connected components in the new graph
                var a = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <int, Edge <int> >(graph);
                a.Compute();
                var nodeToComponentDic = a.Components;

                // Add the seperator and potential moplex again
                graph.AddVertexRange(seperator);
                graph.AddVertexRange(potMoplex);
                graph.AddEdgeRange(tempRemove);

                var isMoplex = false;
                foreach (var sepNode in seperator) // Find the components connected to each of the seperator vertices
                {
                    HashSet <int> connectedComponents = new HashSet <int>();
                    foreach (var e in graph.AdjacentEdges(sepNode))
                    {
                        var neighbour = e.GetOtherVertex(sepNode);
                        if (potMoplex.Contains(neighbour))
                        {
                            continue;                                  //not a component, since it was removed at the time
                        }
                        if (nodeToComponentDic.ContainsKey(neighbour)) //else neighbour is also seperator TODO: error here, Not anymore I think
                        {
                            int c;
                            nodeToComponentDic.TryGetValue(neighbour, out c);
                            connectedComponents.Add(c);
                        }
                    }
                    if (connectedComponents.Count < a.ComponentCount || a.ComponentCount == 0)
                    {
                        isMoplex = false;
                        break;
                    }
                    isMoplex = true;
                }

                if (isMoplex)
                {
                    moplexes.Add(potMoplex);
                }


                // To ensure no dublicates
                foreach (var n in potMoplex)
                {
                    hasBeenChecked.Add(n);
                }
            }
            return(moplexes);
        }
예제 #32
0
        // troublesome component from instances/5.graph
        public static UndirectedGraph <int, Edge <int> > TestGraph13()
        {
            var g     = new UndirectedGraph <int, Edge <int> >();
            var edges = new List <Edge <int> >
            {
                new Edge <int>(29, 9),
                new Edge <int>(39, 29),
                new Edge <int>(9, 85),
                new Edge <int>(39, 20),
                new Edge <int>(39, 91),
                new Edge <int>(39, 4),
                new Edge <int>(47, 39),
                new Edge <int>(39, 97),
                new Edge <int>(37, 85),
                new Edge <int>(95, 85),
                new Edge <int>(26, 59),
                new Edge <int>(53, 26),
                new Edge <int>(24, 53),
                new Edge <int>(67, 20),
                new Edge <int>(72, 67),
                new Edge <int>(81, 20),
                new Edge <int>(68, 72),
                new Edge <int>(81, 30),
                new Edge <int>(74, 81),
                new Edge <int>(48, 75),
                new Edge <int>(18, 48),
                new Edge <int>(48, 60),
                new Edge <int>(75, 62),
                new Edge <int>(18, 70),
                new Edge <int>(18, 82),
                new Edge <int>(18, 66),
                new Edge <int>(18, 60),
                new Edge <int>(34, 18),
                new Edge <int>(18, 49),
                new Edge <int>(66, 62),
                new Edge <int>(73, 62),
                new Edge <int>(24, 50),
                new Edge <int>(24, 5),
                new Edge <int>(24, 47),
                new Edge <int>(83, 24),
                new Edge <int>(50, 86),
                new Edge <int>(13, 83),
                new Edge <int>(86, 56),
                new Edge <int>(25, 66),
                new Edge <int>(34, 49),
                new Edge <int>(10, 34),
                new Edge <int>(25, 49),
                new Edge <int>(65, 93),
                new Edge <int>(94, 65),
                new Edge <int>(65, 3),
                new Edge <int>(89, 65),
                new Edge <int>(65, 68),
                new Edge <int>(46, 93),
                new Edge <int>(89, 94),
                new Edge <int>(3, 22),
                new Edge <int>(89, 25),
                new Edge <int>(89, 73),
                new Edge <int>(46, 80),
                new Edge <int>(77, 46),
                new Edge <int>(46, 52),
                new Edge <int>(17, 0),
                new Edge <int>(92, 17),
                new Edge <int>(17, 45),
                new Edge <int>(0, 15),
                new Edge <int>(45, 12),
                new Edge <int>(45, 8),
                new Edge <int>(45, 19),
                new Edge <int>(45, 32),
                new Edge <int>(15, 54),
                new Edge <int>(91, 1),
                new Edge <int>(4, 91),
                new Edge <int>(4, 43),
                new Edge <int>(12, 37),
                new Edge <int>(25, 10),
                new Edge <int>(73, 22),
                new Edge <int>(30, 95),
                new Edge <int>(74, 55),
                new Edge <int>(56, 21),
                new Edge <int>(56, 42),
                new Edge <int>(21, 27),
                new Edge <int>(42, 99)
            };

            foreach (var edge in edges)
            {
                if (!g.ContainsVertex(edge.Source))
                {
                    g.AddVertex(edge.Source);
                }
                if (!g.ContainsVertex(edge.Target))
                {
                    g.AddVertex(edge.Target);
                }
            }
            g.AddEdgeRange(edges);

            return(g);
        }