/// <summary> /// Computes a set of eulerian trail, starting at <paramref name="s"/> /// that spans the entire graph. /// </summary> /// <remarks> /// <para> /// This method computes a set of eulerian trail starting at <paramref name="s"/> /// that spans the entire graph.The algorithm outline is as follows: /// </para> /// <para> /// The algorithms iterates throught the Eulerian circuit of the augmented /// graph (the augmented graph is the graph with additional edges to make /// the number of odd vertices even). /// </para> /// <para> /// If the current edge is not temporary, it is added to the current trail. /// </para> /// <para> /// If the current edge is temporary, the current trail is finished and /// added to the trail collection. The shortest path between the /// start vertex <paramref name="s"/> and the target vertex of the /// temporary edge is then used to start the new trail. This shortest /// path is computed using the <see cref="BreadthFirstSearchAlgorithm"/>. /// </para> /// </remarks> /// <param name="s">start vertex</param> /// <returns>eulerian trail set, all starting at s</returns> /// <exception cref="ArgumentNullException">s is a null reference.</exception> /// <exception cref="Exception">Eulerian trail not computed yet.</exception> public EdgeCollectionCollection Trails(IVertex s) { if (s==null) throw new ArgumentNullException("s"); if (this.Circuit.Count==0) throw new Exception("Circuit is empty"); // find the first edge in the circuit. int i=0; for(i=0;i<this.Circuit.Count;++i) { IEdge e = this.Circuit[i]; if (TemporaryEdges.Contains(e)) continue; if (e.Source == s) break; } if (i==this.Circuit.Count) throw new Exception("Did not find vertex in eulerian trail?"); // create collections EdgeCollectionCollection trails = new EdgeCollectionCollection(); EdgeCollection trail = new EdgeCollection(); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(VisitedGraph); PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor(); bfs.RegisterPredecessorRecorderHandlers(vis); bfs.Compute(s); // go throught the edges and build the predecessor table. int start = i; for (;i<this.Circuit.Count;++i) { IEdge e = this.Circuit[i]; if (TemporaryEdges.Contains(e)) { // store previous trail and start new one. if(trail.Count != 0) trails.Add(trail); // start new trail // take the shortest path from the start vertex to // the target vertex trail = vis.Path(e.Target); } else trail.Add(e); } // starting again on the circuit for (i=0;i<start;++i) { IEdge e = this.Circuit[i]; if (TemporaryEdges.Contains(e)) { // store previous trail and start new one. if(trail.Count != 0) trails.Add(trail); // start new trail // take the shortest path from the start vertex to // the target vertex trail = vis.Path(e.Target); } else trail.Add(e); } // adding the last element if (trail.Count!=0) trails.Add(trail); return trails; }
/// <summary> /// Remove the edge (u,v) from the graph. /// If the graph allows parallel edges this remove all occurrences of /// (u,v). /// </summary> /// <param name="u">source vertex</param> /// <param name="v">target vertex</param> public override void RemoveEdge(IVertex u, IVertex v) { if (u == null) throw new ArgumentNullException("source vertex"); if (v == null) throw new ArgumentNullException("targetvertex"); EdgeCollection outEdges = VertexOutEdges[u]; EdgeCollection inEdges = VertexInEdges[v]; // marking edges to remove EdgeCollection removedEdges = new EdgeCollection(); foreach(IEdge e in outEdges) { if (e.Target == v) removedEdges.Add(e); } foreach(IEdge e in inEdges) { if (e.Source == u) removedEdges.Add(e); } //removing edges foreach(IEdge e in removedEdges) RemoveEdge(e); }
/// <summary> /// Merges the temporary circuit with the current circuit /// </summary> /// <returns>true if all the graph edges are in the circuit</returns> protected bool CircuitAugmentation() { EdgeCollection newC=new EdgeCollection(); int i,j; // follow C until w is found for(i=0;i<Circuit.Count;++i) { IEdge e = Circuit[i]; if (e.Source==CurrentVertex) break; newC.Add(e); } // follow D until w is found again for(j=0;j<TemporaryCircuit.Count;++j) { IEdge e = TemporaryCircuit[j]; newC.Add(e); OnCircuitEdge(e); if (e.Target==CurrentVertex) break; } TemporaryCircuit.Clear(); // continue C for(;i<Circuit.Count;++i) { IEdge e = Circuit[i]; newC.Add(e); } // set as new circuit circuit = newC; // check if contains all edges if (Circuit.Count == VisitedGraph.EdgesCount) return true; return false; }
/// <summary> /// Adds temporary edges to the graph to make all vertex even. /// </summary> /// <param name="g"></param> /// <returns></returns> public EdgeCollection AddTemporaryEdges(IMutableVertexAndEdgeListGraph g) { if (g==null) throw new ArgumentNullException("g"); // first gather odd edges. VertexCollection oddVertices = AlgoUtility.OddVertices(g); // check that there are an even number of them if (oddVertices.Count%2!=0) throw new Exception("number of odd vertices in not even!"); // add temporary edges to create even edges: EdgeCollection ec = new EdgeCollection(); bool found,foundbe,foundadjacent; while (oddVertices.Count > 0) { IVertex u = oddVertices[0]; // find adjacent odd vertex. found = false; foundadjacent = false; foreach(IEdge e in g.OutEdges(u)) { IVertex v = e.Target; if (v!=u && oddVertices.Contains(v)) { foundadjacent=true; // check that v does not have an out-edge towards u foundbe = false; foreach(IEdge be in g.OutEdges(v)) { if (be.Target==u) { foundbe = true; break; } } if (foundbe) continue; // add temporary edge IEdge tempEdge = g.AddEdge(v,u); // add to collection ec.Add(tempEdge); // remove u,v from oddVertices oddVertices.Remove(u); oddVertices.Remove(v); // set u to null found = true; break; } } if (!foundadjacent) { // pick another vertex if (oddVertices.Count<2) throw new Exception("Eulerian trail failure"); IVertex v = oddVertices[1]; IEdge tempEdge = g.AddEdge(u,v); // add to collection ec.Add(tempEdge); // remove u,v from oddVertices oddVertices.Remove(u); oddVertices.Remove(v); // set u to null found = true; } if (!found) { oddVertices.Remove(u); oddVertices.Add(u); } } temporaryEdges = ec; return ec; }
public void AddReversedEdges() { if (this.Augmented) { throw new InvalidOperationException("Graph already augmented"); } EdgeCollection edges = new EdgeCollection(); IEdgeEnumerator enumerator = this.VisitedGraph.get_Edges().GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); if (!this.reversedEdges.Contains(edge)) { IEdge edge2 = this.FindReversedEdge(edge); if (edge2 != null) { this.reversedEdges.set_Item(edge, edge2); if (!this.reversedEdges.Contains(edge2)) { this.reversedEdges.set_Item(edge2, edge); } } else { edges.Add(edge); } } } EdgeCollection.Enumerator enumerator2 = edges.GetEnumerator(); while (enumerator2.MoveNext()) { IEdge edge3 = enumerator2.get_Current(); if (!this.reversedEdges.Contains(edge3)) { IEdge edge4 = this.FindReversedEdge(edge3); if (edge4 != null) { this.reversedEdges.set_Item(edge3, edge4); } else { edge4 = this.VisitedGraph.AddEdge(edge3.get_Target(), edge3.get_Source()); this.augmentedEgdes.Add(edge4); this.reversedEdges.set_Item(edge3, edge4); this.reversedEdges.set_Item(edge4, edge3); this.OnReservedEdgeAdded(new EdgeEventArgs(edge4)); } } } this.augmented = true; }
public void RemoveInEdgeIf(IVertex u, IEdgePredicate pred) { if (u == null) { throw new ArgumentNullException("vertex u"); } if (pred == null) { throw new ArgumentNullException("predicate"); } EdgeCollection edges = this.VertexInEdges.get_Item(u); EdgeCollection edges2 = new EdgeCollection(); EdgeCollection.Enumerator enumerator = edges.GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); if (pred.Test(edge)) { edges2.Add(edge); } } EdgeCollection.Enumerator enumerator2 = edges2.GetEnumerator(); while (enumerator2.MoveNext()) { IEdge e = enumerator2.get_Current(); this.RemoveEdge(e); } }
public virtual void RemoveEdge(IVertex u, IVertex v) { if (u == null) { throw new ArgumentNullException("source vertex"); } if (v == null) { throw new ArgumentNullException("targetvertex"); } EdgeCollection edges = this.VertexOutEdges.get_Item(u); if (edges == null) { throw new EdgeNotFoundException(); } EdgeCollection edges2 = new EdgeCollection(); EdgeCollection.Enumerator enumerator = edges.GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); if (edge.get_Target() == v) { edges2.Add(edge); } } EdgeCollection.Enumerator enumerator2 = edges2.GetEnumerator(); while (enumerator2.MoveNext()) { IEdge edge2 = enumerator2.get_Current(); edges.Remove(edge2); } }
/// <summary> /// Remove all the edges from graph g for which the predicate pred /// returns true. /// </summary> /// <param name="pred">edge predicate</param> public virtual void RemoveEdgeIf(IEdgePredicate pred) { if (pred == null) throw new ArgumentNullException("predicate"); // marking edge for removal EdgeCollection removedEdges = new EdgeCollection(); foreach(IEdge e in Edges) { if (pred.Test(e)) removedEdges.Add(e); } // removing edges foreach(IEdge e in removedEdges) RemoveEdge(e); }
/// <summary> /// Remove the edge (u,v) from the graph. /// If the graph allows parallel edges this remove all occurrences of /// (u,v). /// </summary> /// <param name="u">source vertex</param> /// <param name="v">target vertex</param> public virtual void RemoveEdge(Vertex u, Vertex v) { if (u == null) throw new ArgumentNullException("u"); if (v == null) throw new ArgumentNullException("v"); this.version++; // getting out-edges EdgeCollection outEdges = this.vertexOutEdges[u]; // marking edges to remove EdgeCollection removedEdges = new EdgeCollection(); foreach(Edge e in outEdges) { if (e.Target == v) removedEdges.Add(e); } //removing out-edges foreach(Edge e in removedEdges) outEdges.Remove(e); removedEdges.Clear(); EdgeCollection inEdges = this.vertexInEdges[v]; foreach(Edge e in inEdges) { if (e.Source == u) removedEdges.Add(e); } //removing in-edges foreach(Edge e in removedEdges) inEdges.Remove(e); }
/// <summary> /// Remove all the out-edges of vertex u for which the predicate pred /// returns true. /// </summary> /// <param name="u">vertex</param> /// <param name="pred">edge predicate</param> public void RemoveInEdgeIf(Vertex u, IEdgePredicate pred) { if (u==null) throw new ArgumentNullException("vertex u"); if (pred == null) throw new ArgumentNullException("predicate"); EdgeCollection edges = this.vertexInEdges[u]; EdgeCollection removedEdges = new EdgeCollection(); foreach(Edge e in edges) { if (pred.Test(e)) removedEdges.Add(e); } foreach(Edge e in removedEdges) this.RemoveEdge(e); }
protected bool CircuitAugmentation() { EdgeCollection edges = new EdgeCollection(); int num = 0; while (num < this.Circuit.Count) { IEdge edge = this.Circuit.get_Item(num); if (edge.get_Source() == this.CurrentVertex) { break; } edges.Add(edge); num++; } for (int i = 0; i < this.TemporaryCircuit.Count; i++) { IEdge e = this.TemporaryCircuit.get_Item(i); edges.Add(e); this.OnCircuitEdge(e); if (e.get_Target() == this.CurrentVertex) { break; } } this.TemporaryCircuit.Clear(); while (num < this.Circuit.Count) { IEdge edge3 = this.Circuit.get_Item(num); edges.Add(edge3); num++; } this.circuit = edges; return (this.Circuit.Count == this.VisitedGraph.get_EdgesCount()); }
public EdgeCollectionCollection Trails(IVertex s) { if (s == null) { throw new ArgumentNullException("s"); } if (this.Circuit.Count == 0) { throw new Exception("Circuit is empty"); } int num = 0; num = 0; while (num < this.Circuit.Count) { IEdge edge = this.Circuit.get_Item(num); if (!this.TemporaryEdges.Contains(edge) && (edge.get_Source() == s)) { break; } num++; } if (num == this.Circuit.Count) { throw new Exception("Did not find vertex in eulerian trail?"); } EdgeCollectionCollection collections = new EdgeCollectionCollection(); EdgeCollection edges = new EdgeCollection(); BreadthFirstSearchAlgorithm algorithm = new BreadthFirstSearchAlgorithm(this.VisitedGraph); PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor(); algorithm.RegisterPredecessorRecorderHandlers(vis); algorithm.Compute(s); int num2 = num; while (num < this.Circuit.Count) { IEdge edge2 = this.Circuit.get_Item(num); if (this.TemporaryEdges.Contains(edge2)) { if (edges.Count != 0) { collections.Add(edges); } edges = vis.Path(edge2.get_Target()); } else { edges.Add(edge2); } num++; } for (num = 0; num < num2; num++) { IEdge edge3 = this.Circuit.get_Item(num); if (this.TemporaryEdges.Contains(edge3)) { if (edges.Count != 0) { collections.Add(edges); } edges = vis.Path(edge3.get_Target()); } else { edges.Add(edge3); } } if (edges.Count != 0) { collections.Add(edges); } return collections; }
public EdgeCollection AddTemporaryEdges(IMutableVertexAndEdgeListGraph g) { if (g == null) { throw new ArgumentNullException("g"); } VertexCollection vertexs = QuickGraph.Algorithms.AlgoUtility.OddVertices(g); if ((vertexs.Count % 2) != 0) { throw new Exception("number of odd vertices in not even!"); } EdgeCollection edges = new EdgeCollection(); while (vertexs.Count > 0) { IVertex vertex = vertexs.get_Item(0); bool flag = false; bool flag3 = false; IEdgeEnumerator enumerator = g.OutEdges(vertex).GetEnumerator(); while (enumerator.MoveNext()) { IVertex vertex2 = enumerator.get_Current().get_Target(); if ((vertex2 != vertex) && vertexs.Contains(vertex2)) { flag3 = true; bool flag2 = false; IEdgeEnumerator enumerator2 = g.OutEdges(vertex2).GetEnumerator(); while (enumerator2.MoveNext()) { if (enumerator2.get_Current().get_Target() == vertex) { flag2 = true; break; } } if (!flag2) { IEdge edge3 = g.AddEdge(vertex2, vertex); edges.Add(edge3); vertexs.Remove(vertex); vertexs.Remove(vertex2); flag = true; break; } } } if (!flag3) { if (vertexs.Count < 2) { throw new Exception("Eulerian trail failure"); } IVertex vertex3 = vertexs.get_Item(1); IEdge edge4 = g.AddEdge(vertex, vertex3); edges.Add(edge4); vertexs.Remove(vertex); vertexs.Remove(vertex3); flag = true; } if (!flag) { vertexs.Remove(vertex); vertexs.Add(vertex); } } this.temporaryEdges = edges; return edges; }
/// <summary> /// Augments the <see cref="VisitedGraph"/> with reversed edges. /// </summary> /// <exception cref="InvalidOperationException"> /// The graph has already been augmented. /// </exception> public void AddReversedEdges() { if (this.Augmented) throw new InvalidOperationException("Graph already augmented"); // step 1, find edges that need reversing EdgeCollection notReversedEdges = new EdgeCollection(); foreach (IEdge edge in this.VisitedGraph.Edges) { // if reversed already found, continue if (this.reversedEdges.Contains(edge)) continue; IEdge reversedEdge = this.FindReversedEdge(edge); if (reversedEdge != null) { // setup edge this.reversedEdges[edge] = reversedEdge; // setup reversed if needed if (!this.reversedEdges.Contains(reversedEdge)) this.reversedEdges[reversedEdge] = edge; continue; } // this edge has no reverse notReversedEdges.Add(edge); } // step 2, go over each not reversed edge, add reverse foreach (IEdge edge in notReversedEdges) { if (this.reversedEdges.Contains(edge)) continue; // already been added IEdge reversedEdge = this.FindReversedEdge(edge); if (reversedEdge != null) { this.reversedEdges[edge] = reversedEdge; continue; } // need to create one reversedEdge = this.VisitedGraph.AddEdge(edge.Target, edge.Source); this.augmentedEgdes.Add(reversedEdge); this.reversedEdges[edge] = reversedEdge; this.reversedEdges[reversedEdge] = edge; this.OnReservedEdgeAdded(new EdgeEventArgs(reversedEdge)); } this.augmented = true; }
public virtual void RemoveEdgeIf(IEdgePredicate pred) { if (pred == null) { throw new ArgumentNullException("predicate"); } EdgeCollection edges = new EdgeCollection(); VertexEdgesEnumerator enumerator = this.Edges.GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); if (pred.Test(edge)) { edges.Add(edge); } } EdgeCollection.Enumerator enumerator2 = edges.GetEnumerator(); while (enumerator2.MoveNext()) { IEdge e = enumerator2.get_Current(); this.RemoveEdge(e); } }
/// <summary> /// Remove the edge (u,v) from the graph. /// If the graph allows parallel edges this remove all occurrences of /// (u,v). /// </summary> /// <param name="u">source vertex</param> /// <param name="v">target vertex</param> public virtual void RemoveEdge(IVertex u, IVertex v) { if (u == null) throw new ArgumentNullException("source vertex"); if (v == null) throw new ArgumentNullException("targetvertex"); EdgeCollection edges = VertexOutEdges[u]; if (edges==null) throw new EdgeNotFoundException(); // marking edges to remove EdgeCollection removedEdges = new EdgeCollection(); foreach(IEdge e in edges) { if (e.Target == v) removedEdges.Add(e); } //removing edges foreach(IEdge e in removedEdges) edges.Remove(e); }
public override void RemoveEdge(IVertex u, IVertex v) { if (u == null) { throw new ArgumentNullException("source vertex"); } if (v == null) { throw new ArgumentNullException("targetvertex"); } EdgeCollection edges = base.VertexOutEdges.get_Item(u); EdgeCollection edges2 = this.VertexInEdges.get_Item(v); EdgeCollection edges3 = new EdgeCollection(); EdgeCollection.Enumerator enumerator = edges.GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); if (edge.get_Target() == v) { edges3.Add(edge); } } EdgeCollection.Enumerator enumerator2 = edges2.GetEnumerator(); while (enumerator2.MoveNext()) { IEdge edge2 = enumerator2.get_Current(); if (edge2.get_Source() == u) { edges3.Add(edge2); } } EdgeCollection.Enumerator enumerator3 = edges3.GetEnumerator(); while (enumerator3.MoveNext()) { IEdge e = enumerator3.get_Current(); this.RemoveEdge(e); } }
/// <summary> /// Remove all the out-edges of vertex u for which the predicate pred /// returns true. /// </summary> /// <param name="u">vertex</param> /// <param name="pred">edge predicate</param> public virtual void RemoveOutEdgeIf(IVertex u, IEdgePredicate pred) { if (u==null) throw new ArgumentNullException("vertex u"); if (pred == null) throw new ArgumentNullException("predicate"); EdgeCollection edges = VertexOutEdges[u]; EdgeCollection removedEdges = new EdgeCollection(); foreach(IEdge e in edges) if (pred.Test(e)) removedEdges.Add(e); foreach(IEdge e in removedEdges) RemoveEdge(e); }
public void ClearVertex(IVertex v) { if (v==null) throw new ArgumentNullException("v"); if (!this.ContainsVertex(v)) throw new ArgumentException("v is not part of the graph"); EdgeCollection edges = new EdgeCollection(); foreach(IEdge e in this.VisitedGraph.OutEdges(v)) edges.Add(e); foreach(IEdge e in this.VisitedGraph.InEdges(v)) edges.Add(e); foreach(IEdge e in edges) { if (this.VisitedGraph.ContainsEdge(e)) { RemoveEdge(e); } } }