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);
                }
Beispiel #2
0
        /// <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);
            }
Beispiel #4
0
        /// <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);
            }
        }
Beispiel #5
0
        /// <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);
                    }
                }
            }
        }