public bool MoveNext() { if (fixtureEn == null) { if (!vertexEn.MoveNext()) { return(false); } FixtureVertex v = vertexEn.Current as FixtureVertex; this.fixtureEn = v.Fixtures.GetEnumerator(); } while (!this.fixtureEn.MoveNext()) { if (!vertexEn.MoveNext()) { return(false); } FixtureVertex v = vertexEn.Current as FixtureVertex; this.fixtureEn = v.Fixtures.GetEnumerator(); } return(true); }
/// <summary> /// Returns the first vertex of the enumerable /// </summary> /// <param name="vertices">enumerable collection of <see cref="IVertex"/></param> /// <returns>first vertex if any, otherwise a null reference</returns> public static IVertex LastVertex(IVertexEnumerable vertices) { if (vertices == null) { throw new ArgumentNullException("vertices"); } IVertexEnumerator en = vertices.GetEnumerator(); IVertex current = null; while (en.MoveNext()) { current = en.Current; } return(current); }
/// <summary> /// Moves the cursor to the next Vertex. /// </summary> /// <returns>True if successful, false if the iteration ended.</returns> public bool MoveNext() { bool ok; do { ok = m_Enumerator.MoveNext(); if (!ok) { return(false); } }while(!m_Predicate.Test(m_Enumerator.Current)); return(true); }
/// <summary> /// Returns the first vertex of the enumerable /// </summary> /// <param name="vertices">enumerable collection of <see cref="IVertex"/></param> /// <returns>first vertex if any, otherwise a null reference</returns> public static IVertex FirstVertex(IVertexEnumerable vertices) { if (vertices == null) { throw new ArgumentNullException("vertices"); } IVertexEnumerator en = vertices.GetEnumerator(); if (!en.MoveNext()) { return(null); } else { return(en.Current); } }
/// <summary> /// Returns the first vertex of the enumerable that matches the predicate. /// </summary> /// <param name="vertices">enumerable collection of <see cref="IVertex"/></param> /// <param name="pred">vertex predicate</param> /// <returns>first vertex if any, otherwise a null reference</returns> public static IVertex FirstVertexIf(IVertexEnumerable vertices, IVertexPredicate pred) { if (vertices == null) { throw new ArgumentNullException("vertices"); } if (pred == null) { throw new ArgumentNullException("pred"); } IVertexEnumerator en = vertices.GetEnumerator(); while (en.MoveNext()) { if (pred.Test(en.Current)) { return(en.Current); } } return(null); }
//======================================================================= // remove excess flow, the "second phase" // This does a DFS on the reverse flow graph of nodes with excess flow. // If a cycle is found, cancel it. Unfortunately it seems that we can't // easily take advantage of DepthFirstSearchAlgorithm // Return the nodes with excess flow in topological order. // // Unlike the prefl_to_flow() implementation, we use // "color" instead of "distance" for the DFS labels // "parent" instead of nl_prev for the DFS tree // "topo_next" instead of nl_next for the topological ordering private void ConvertPreflowToFlow() { IVertex r, restart, u; IVertex bos = null, tos = null; VertexVertexDictionary parents = new VertexVertexDictionary(); VertexVertexDictionary topoNext = new VertexVertexDictionary(); foreach (IVertex v in VisitedGraph.Vertices) { //Handle self-loops foreach (IEdge a in VisitedGraph.OutEdges(v)) { if (a.Target == v) { ResidualCapacities[a] = Capacities[a]; } } //Initialize Colors[v] = GraphColor.White; parents[v] = v; current[v] = 0; } // eliminate flow cycles and topologically order the vertices IVertexEnumerator vertices = VisitedGraph.Vertices.GetEnumerator(); while (vertices.MoveNext()) { u = vertices.Current; if (Colors[u] == GraphColor.White && excessFlow[u] > 0 && u != src && u != sink) { r = u; Colors[r] = GraphColor.Gray; while (true) { for (; current[u] < VisitedGraph.OutDegree(u); ++current[u]) { IEdge a = VisitedGraph.OutEdges(u)[current[u]]; if (Capacities[a] == 0 && IsResidualEdge(a)) { IVertex v = a.Target; if (Colors[v] == GraphColor.White) { Colors[v] = GraphColor.Gray; parents[v] = u; u = v; break; } else if (Colors[v] == GraphColor.Gray) { //find minimum flow on the cycle double delta = ResidualCapacities[a]; while (true) { IEdge e = VisitedGraph.OutEdges(v)[current[v]]; delta = Math.Min(delta, ResidualCapacities[e]); if (v == u) { break; } else { v = e.Target; } } //remove delta flow units v = u; while (true) { a = VisitedGraph.OutEdges(v)[current[v]]; ResidualCapacities[a] -= delta; ResidualCapacities[ReversedEdges[a]] += delta; v = a.Target; if (v == u) { break; } } // back-out of DFS to the first saturated edge restart = u; for (v = VisitedGraph.OutEdges(u)[current[u]].Target; v != u; v = a.Target) { a = VisitedGraph.OutEdges(v)[current[v]]; if (Colors[v] == GraphColor.White || IsSaturated(a)) { Colors[VisitedGraph.OutEdges(v)[current[v]].Target] = GraphColor.White; if (Colors[v] != GraphColor.White) { restart = v; } } } if (restart != u) { u = restart; ++current[u]; break; } } } } if (current[u] == VisitedGraph.OutDegree(u)) { // scan of i is complete Colors[u] = GraphColor.Black; if (u != src) { if (bos == null) { bos = u; tos = u; } else { topoNext[u] = tos; tos = u; } } if (u != r) { u = parents[u]; ++current[u]; } else { break; } } } } } // return excess flows // note that the sink is not on the stack if (bos != null) { IEdgeEnumerator ai; for (u = tos; u != bos; u = topoNext[u]) { ai = VisitedGraph.OutEdges(u).GetEnumerator(); while (excessFlow[u] > 0 && ai.MoveNext()) { if (Capacities[ai.Current] == 0 && IsResidualEdge(ai.Current)) { PushFlow(ai.Current); } } } // do the bottom u = bos; ai = VisitedGraph.OutEdges(u).GetEnumerator(); while (excessFlow[u] > 0 && ai.MoveNext()) { if (Capacities[ai.Current] == 0 && IsResidualEdge(ai.Current)) { PushFlow(ai.Current); } } } }