private void AddEdge(RotationTreeNode p, RotationTreeNode q)
        {
            var pVertex = new PointVertex(p.Point);
            var qVertex = new PointVertex(q.Point);

            if (_graph.ContainsVertex(pVertex) && _graph.ContainsVertex(qVertex))
            {
                _graph.AddEdge(new Edge <PointVertex>(pVertex, qVertex));
            }
        }
Ejemplo n.º 2
0
        public void TestTargetAddEdge()
        {
            UndirectedGraph target = new UndirectedGraph();

            target.AddVertex("v1");
            target.AddVertex("v2");
            Assert.IsTrue(target.ContainsVertex("v1"));
            Assert.IsTrue(target.ContainsVertex("v2"));
            target.AddEdge("v1", "v2");
            Assert.IsTrue(target.ContainsEdge("v1", "v2"));
            Assert.IsTrue(target.ContainsEdge("v2", "v1"));
        }
Ejemplo n.º 3
0
        public void removeIsolatedVertices()
        {
            var graph = new UndirectedGraph <int, IEdge <int> >();

            graph.AddVertex(1);
            var edge = new EquatableEdge <int>(2, 3);

            graph.AddVerticesAndEdge(edge);
            graph.RemoveVertexIf(graph.IsAdjacentEdgesEmpty);
            Assert.IsTrue(graph.ContainsVertex(2));
            Assert.IsTrue(graph.ContainsEdge(edge));
            Assert.IsTrue(graph.ContainsEdge(2, 3));
            Assert.IsTrue(graph.ContainsEdge(3, 2));
            Assert.IsFalse(graph.ContainsVertex(1));
        }
Ejemplo n.º 4
0
        static public UndirectedGraph <GraphXVertex, GraphXTaggedEdge <GraphXVertex, int> > GetUnderectedGraphFromDot(string dotSource)
        {
            var vertexFun = VertexFactory.Name;
            var edgeFun   = EdgeFactory <GraphXVertex> .Weighted(0);

            var graph  = Graph.LoadDot(dotSource, vertexFun, edgeFun);
            var ugraph = new UndirectedGraph <GraphXVertex, GraphXTaggedEdge <GraphXVertex, int> >();

            foreach (var i in graph.Vertices)
            {
                if (!ugraph.ContainsVertex(i))
                {
                    ugraph.AddVertex(i);
                }
            }
            foreach (var i in graph.Edges)
            {
                var z = ugraph.Edges.FirstOrDefault(x => (x.Source == i.Target) && (x.Target == i.Source));
                if (ugraph.Edges.FirstOrDefault(x => (x.Source == i.Target) && (x.Target == i.Source)) == null)
                {
                    ugraph.AddEdge(i);
                }
            }
            return(ugraph);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Schedule execution of transaction
        /// </summary>
        void Scheduler()
        {
            //  How to improve this loop?
            //  https://github.com/ethereum/go-ethereum/blob/master/core/state_processor.go#L58
            //
            //  Execution strategy(experimental)
            //  1. tranform the dependency of Resource(R) into graph of related Transactions(T)
            //  2. find the T(ransaction) which connects to the most neightbours
            //  3. execute the T(ransaction), and removes this node from the graph
            //  4. check to see if this removal leads to graph split
            //  5. if YES, we can parallel execute the transactions from the splitted graph
            //  6  if NO, goto step 2

            // build the graph
            UndirectedGraph <IHash, Edge <IHash> > graph = new UndirectedGraph <IHash, Edge <IHash> >(false);

            this.mut.WaitOne();
            foreach (var grp in pending)
            {
                foreach (var tx in grp.Value)
                {
                    if (!graph.ContainsVertex(tx.GetHash()))
                    {
                    }
                    graph.AddVertex(tx.GetHash());
                }

                foreach (var tx in grp.Value)
                {
                    foreach (var neighbour in grp.Value)
                    {
                        if (!tx.Equals(neighbour))
                        {
                            graph.AddEdge(new Edge <IHash>(tx.GetHash(), neighbour.GetHash()));
                        }
                    }
                }
            }


            // TODO : maintain a heap for tracking the most connected vertex
            // execute the transaction, and remove it from the graph

            // reset
            pending = new Dictionary <IHash, List <ITransaction> >();
            this.mut.ReleaseMutex();

            // TODO: parallel execution on root nodes;
        }
        Triangulate(UndirectedGraph <int, IEdge <int> > tree, int root = 0)
        {
            Dictionary <(int source, int target), int> innerVerticesCount = new Dictionary <(int source, int target), int>();
            UndirectedGraph <int, IEdge <int> >        res = new UndirectedGraph <int, IEdge <int> >();

            if (tree.IsVerticesEmpty)
            {
                return(res, innerVerticesCount);
            }
            if (!tree.ContainsVertex(root))
            {
                throw new ArgumentException("root");
            }

            // create counter-clockwise combinatorial embedding
            // assumes vertices are numbered as in BFS
            // so it's proper to add them to list in order they are stored internally
            UndirectedGraph <int, IEdge <int> > G         = tree.Clone();
            Dictionary <int, List <int> >       embedding = new Dictionary <int, List <int> >(); // TODO: what if graph vertices are only subgraph? this assumption may be wrong

            foreach (int i in G.Vertices)
            {
                embedding.Add(i, new List <int>());
                foreach (int v in G.AdjacentVertices(i))
                {
                    embedding[i].Add(v);
                }
            }

            foreach (int v in tree.Vertices)
            {
                int[] neighbors = new int[embedding[v].Count];
                embedding[v].CopyTo(neighbors);

                int prev = neighbors[0];
                for (int i = 1; i < neighbors.Length; i++)
                {
                    int curr = neighbors[i];
                    TryAddEdge(prev, curr, v, ref G, ref res, ref embedding, ref innerVerticesCount);
                    prev = curr;
                }
                if (neighbors.Length > 2)
                {
                    TryAddEdge(prev, neighbors[0], v, ref G, ref res, ref embedding, ref innerVerticesCount);
                }
            }

            return(res, innerVerticesCount);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Schedule execution of transaction
        /// </summary>
        void Scheduler()
        {
            //  Execution strategy(experimental)
            //  1. tranform the dependency of Resource(R) into graph of related Transactions(T)
            //  2. find the T(ransaction) which connects to the most neightbours
            //  3. execute the T(ransaction), and removes this node from the graph
            //  4. check to see if this removal leads to graph split
            //  5. if YES, we can parallel execute the transactions from the splitted graph
            //  6  if NO, goto step 2

            // build the graph
            UndirectedGraph <IHash, Edge <IHash> > graph = new UndirectedGraph <IHash, Edge <IHash> >(false);

            //Dictionary<IHash, int> neiCount=new Dictionary<IHash, int>();
            this.mut.WaitOne();
            foreach (var grp in pending)
            {
                foreach (var tx in grp.Value)
                {
                    if (graph.ContainsVertex(tx.GetHash()))
                    {
                        continue;
                    }
                    graph.AddVertex(tx.GetHash());
                }

                foreach (var tx in grp.Value)
                {
                    foreach (var neighbour in grp.Value)
                    {
                        if (!tx.Equals(neighbour))
                        {
                            graph.AddEdge(new Edge <IHash>(tx.GetHash(), neighbour.GetHash()));
                        }
                    }
                }
            }

            ExecuteGraph(graph);


            // reset
            pending = new Dictionary <IHash, List <ITransaction> >();
            this.mut.ReleaseMutex();

            // TODO: parallel execution on root nodes;
        }
Ejemplo n.º 8
0
        public static (Dictionary <int, int>, Dictionary <int, List <int> >) LexBFS(UndirectedGraph <int, Edge <int> > graph, int start)
        {
            if (!graph.ContainsVertex(start))
            {
                start = graph.Vertices.Min();
            }
            var labels  = new Dictionary <int, List <int> >();
            var indeces = new Dictionary <int, int>();

            foreach (var v in graph.Vertices)
            {
                labels[v]  = new List <int>();
                indeces[v] = -1;
            }

            int next = start;

            for (int i = graph.VertexCount; i > 0; i--)
            {
                indeces[next] = i;
                labels[next].Add(i);
                //Console.WriteLine($"next: {next}");
                foreach (Edge <int> outEdge in graph.AdjacentEdges(next))
                {
                    var neighbour = outEdge.GetOtherVertex(next);
                    //Console.WriteLine($"Neighbour: {neighbour}, Labels.length: {labels.Length}, rounds: {rounds}, graph.containsVertex(neighbour): {graph.ContainsVertex(neighbour)}");
                    labels[neighbour].Add(i);
                }

                int max = -1;
                foreach (int j in labels.Keys)
                {
                    if (indeces[j] == -1 && (max == -1 || LexComp(labels[j], labels[max]) > 0))
                    {
                        max = j;
                    }
                }
                next = max;
            }
            return(indeces, labels);
        }
Ejemplo n.º 9
0
        public static (int[], List <int>[]) LexBFS2(UndirectedGraph <int, Edge <int> > graph, int start)
        {
            if (!graph.ContainsVertex(start))
            {
                start = graph.Vertices.Min();
            }
            List <int>[] labels = new List <int> [graph.VertexCount];
            //Console.WriteLine($"New lables list of size {labels.Length}");
            int[] indeces = new int[graph.VertexCount];

            for (int i = 0; i < graph.VertexCount; i++)
            {
                labels[i] = new List <int>();
            }

            int next = start;

            for (int i = graph.VertexCount; i > 0; i--)
            {
                indeces[next] = i;
                labels[next].Add(i);
                //Console.WriteLine($"next: {next}");
                foreach (Edge <int> outEdge in graph.AdjacentEdges(next))
                {
                    var neighbour = outEdge.GetOtherVertex(next);
                    //Console.WriteLine($"Neighbour: {neighbour}, Labels.length: {labels.Length}, rounds: {rounds}, graph.containsVertex(neighbour): {graph.ContainsVertex(neighbour)}");
                    labels[neighbour].Add(i);
                }

                int max = -1;
                for (int j = 0; j < labels.Length; j++)
                {
                    if (indeces[j] == 0 && (max == -1 || LexComp(labels[j], labels[max]) > 0))
                    {
                        max = j;
                    }
                }
                next = max;
            }
            return(indeces, labels);
        }
Ejemplo n.º 10
0
        // Tested
        public static bool TryGetRootForVertex(UndirectedGraph <int, Edge <int> > forest, int vertex,
                                               int[] verticesLevels, out int rootVertex, out List <Edge <int> > pathToRoot)
        {
            pathToRoot = new List <Edge <int> >();
            rootVertex = -1;
            if (forest.ContainsVertex(vertex) == false || verticesLevels[vertex] == -1)
            {
                return(false);
            }

            while (verticesLevels[vertex] != 0)
            {
                int higherVertex = -1;
                foreach (var edge in forest.AdjacentEdges(vertex))
                {
                    int targetVertex = GetTargetVertex(edge, vertex);
                    if (verticesLevels[targetVertex] == -1)
                    {
                        continue;
                    }
                    if (verticesLevels[targetVertex] == verticesLevels[vertex] - 1)
                    {
                        higherVertex = targetVertex;
                        pathToRoot.Add(edge);
                        vertex = higherVertex;
                        break;
                    }
                }
                if (higherVertex == -1)
                {
                    return(false);
                }
            }
            rootVertex = vertex;
            return(true);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// </summary>
        /// <param name="g"></param>
        /// <param name="currentMatching"></param>
        /// <returns></returns>
        private static List <Edge <int> > FindAugmentingPath(UndirectedGraph <int, Edge <int> > g, List <Edge <int> > currentMatching, out Edge <int> connectingTreesEdge)
        {
            //connectingTreesEdge = null;
            var F = new UndirectedGraph <int, Edge <int> >(); //Forest F
            HashSet <Edge <int> > usedEdges = new HashSet <Edge <int> >(new EdgeComparer());
            var vertices = new List <int>(g.Vertices).ToArray();
            var edges    = new List <Edge <int> >(g.Edges).ToArray();

            bool[] verticesUsed   = new bool[g.VertexCount];
            int[]  verticesLevels = new int[g.VertexCount];
            for (int i = 0; i < verticesLevels.Length; i++)
            {
                verticesLevels[i] = -1;
            }

            if (vertices.Length != verticesUsed.Length)
            {
                throw new InvalidOperationException();
            }
            var isMatched = new bool[g.VertexCount];

            foreach (var edge in currentMatching)
            {
                isMatched[edge.Source] = true;
                isMatched[edge.Target] = true;
                usedEdges.Add(edge);
            }
            for (int i = 0; i < isMatched.Length; i++)
            {
                if (isMatched[i] == false)
                {
                    F.AddVertex(i);
                    verticesLevels[i] = 0;
                }
            }

            var verticesInF = new HashSet <int>(F.Vertices);

            while (verticesInF.Count != 0)
            {
                int v = verticesInF.First();
                foreach (var tempVertex in F.Vertices)
                {
                    if (verticesUsed[tempVertex] == false)
                    {
                        verticesInF.Add(tempVertex);
                    }
                }
                if (verticesUsed[v])
                {
                    continue;
                }
                verticesUsed[v] = true;
                verticesInF.Remove(v);

                if (verticesLevels[v] != -1 && verticesLevels[v] % 2 == 1)
                {
                    continue;
                }
                foreach (var edgeVW in g.AdjacentEdges(v))
                {
                    if (usedEdges.Contains(edgeVW))
                    {
                        continue;
                    }
                    int w = edgeVW.Target;
                    if (w == v)
                    {
                        w = edgeVW.Source;
                    }
                    if (!F.ContainsVertex(w))
                    {
                        foreach (var matchedEdge in currentMatching)
                        {
                            if (!(matchedEdge.Source == w || matchedEdge.Target == w))
                            {
                                continue;
                            }
                            int x = GetTargetVertex(matchedEdge, w);
                            if (x == -1)
                            {
                                throw new ArgumentException();
                            }
                            verticesLevels[w] = verticesLevels[v] + 1;
                            verticesLevels[x] = verticesLevels[w] + 1;
                            F.AddVerticesAndEdge(edgeVW);
                            F.AddVerticesAndEdge(matchedEdge);
                        }
                        if (F.EdgeCount == 0)
                        {
                            throw new ArgumentException();
                        }
                    }
                    else
                    {
                        //connectingTreesEdge = edgeVW;
                        if (verticesLevels[w] == -1)
                        {
                            throw new ArgumentException();
                        }
                        if (verticesLevels[w] % 2 == 1)
                        {
                            //In this case we do nothing
                        }
                        else
                        {
                            bool vHasRoot = TryGetRootForVertex(F, v, verticesLevels, out int rootForV, out List <Edge <int> > pathToVRoot);
                            bool wHasRoot = TryGetRootForVertex(F, w, verticesLevels, out int rootForW, out List <Edge <int> > pathToWRoot);
                            if (!vHasRoot || !wHasRoot)
                            {
                                throw new ArgumentException();
                            }
                            if (rootForV != rootForW)
                            {
                                Stack <Edge <int> > vRootPath = new Stack <Edge <int> >(pathToVRoot);
                                Queue <Edge <int> > wRootPath = new Queue <Edge <int> >(pathToWRoot);
                                var augmentingPath            = new List <Edge <int> >();

                                while (vRootPath.Count != 0)
                                {
                                    augmentingPath.Add(vRootPath.Pop());
                                }
                                augmentingPath.Add(edgeVW);
                                while (wRootPath.Count != 0)
                                {
                                    augmentingPath.Add(wRootPath.Dequeue());
                                }
                                connectingTreesEdge = edgeVW;
                                if (augmentingPath.Count % 2 == 0)
                                {
                                    throw new ArgumentException();
                                }
                                return(augmentingPath);
                            }
                            else
                            {
                                Stack <int> stack   = new Stack <int>();
                                var         visited = new Dictionary <int, bool>();
                                foreach (var vertex in F.Vertices)
                                {
                                    visited.Add(vertex, false);
                                }
                                //var blossom = new Stack<Edge<int>>();
                                bool pathFound = DFSSearch(v, w, F, out List <Edge <int> > blossom);
                                if (!pathFound)
                                {
                                    throw new ArgumentException();
                                }

                                blossom.Add(edgeVW);
                                TestResult blossomCorrectResult = VerifyBlossom(blossom, currentMatching);
                                if (!blossomCorrectResult.IsCorrect)
                                {
                                    throw new ArgumentException(blossomCorrectResult.ErrorMessage);
                                }

                                var contractedMatching = ContractMatching(currentMatching, blossom);
                                var contractedGraph    = ContractGraph(g, blossom, out int superVertex, currentMatching);

                                var contractedAugmentingPath = FindAugmentingPath(contractedGraph, contractedMatching, out Edge <int> edgeBetweenTrees);
                                if (contractedAugmentingPath.Count == 0)
                                {
                                    connectingTreesEdge = null;
                                    return(contractedAugmentingPath);
                                }

                                // LiftAugmentingPath should return some edge
                                var liftedAugmentingPath = LiftAugmentingPath(contractedAugmentingPath, blossom, g, edgeBetweenTrees, superVertex, currentMatching);
                                if (liftedAugmentingPath.Count % 2 == 0)
                                {
                                    throw new ArgumentException();
                                }
                                //connectingTreesEdge = liftedEdgeBetweenTrees;
                                connectingTreesEdge = edgeVW;
                                return(liftedAugmentingPath);
                            }
                        }
                    }
                    usedEdges.Add(edgeVW);
                }
                verticesInF.Remove(v);
                verticesUsed[v] = true;
            }
            connectingTreesEdge = null;
            return(new List <Edge <int> >());
        }
Ejemplo n.º 13
0
        Triangulate(UndirectedGraph <int, IEdge <int> > tree, int root = 0)
        {
            UndirectedGraph <int, IEdge <int> >        res = new UndirectedGraph <int, IEdge <int> >();
            Dictionary <(int source, int target), int> innerVerticesCount = new Dictionary <(int source, int target), int>();

            if (tree.IsVerticesEmpty)
            {
                return(res, innerVerticesCount);
            }
            if (!tree.ContainsVertex(root))
            {
                throw new ArgumentException("root");
            }

            UndirectedGraph <int, IEdge <int> > G = tree.Clone();
            // create counter-clockwise combinatorial embedding
            // assumes vertices are numbered as in BFS
            // so it's proper to add them to list in order they are stored internally
            Dictionary <int, List <int> > embedding = new Dictionary <int, List <int> >();

            for (int i = 0; i < G.VertexCount; i++)
            {
                embedding.Add(i, new List <int>());
                foreach (int v in G.AdjacentVertices(i))
                {
                    embedding[i].Add(v);
                }
            }

            // BFS
            Queue <int> q = new Queue <int>();

            bool[] enqueued = new bool[G.VertexCount];
            q.Enqueue(root);
            enqueued[root] = true;
            while (q.Count > 0)
            {
                int p = q.Dequeue();

                int[] neighbors = new int[embedding[p].Count];
                embedding[p].CopyTo(neighbors);

                int first = neighbors[0];
                if (!enqueued[first])
                {
                    q.Enqueue(first);
                    enqueued[first] = true;
                }
                int prev = first;
                int curr = -1;
                for (int i = 1; i < neighbors.Length; i++)
                {
                    curr = neighbors[i];
                    TryAddEdge(prev, curr, p, ref G, ref res, ref embedding, ref innerVerticesCount);
                    prev = curr;

                    if (!enqueued[curr])
                    {
                        q.Enqueue(curr);
                        enqueued[curr] = true;
                    }
                }
                if (neighbors.Length > 2)
                {
                    TryAddEdge(curr, first, p, ref G, ref res, ref embedding, ref innerVerticesCount);
                }
            }
            return(res, innerVerticesCount);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Содержится ли вершина?
 /// </summary>
 /// <param name="v"></param>
 /// <returns></returns>
 internal bool ContainsVertex(T v)
 {
     lock (GraphLocker)
         return(Graph.ContainsVertex(v));
 }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
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);
        }