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)); } }
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")); }
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)); }
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); }
/// <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); }
/// <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; }
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); }
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); }
// 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); }
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); }
/// <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> >()); }
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); }
/// <summary> /// Содержится ли вершина? /// </summary> /// <param name="v"></param> /// <returns></returns> internal bool ContainsVertex(T v) { lock (GraphLocker) return(Graph.ContainsVertex(v)); }
// 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); }
// 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); }