Exemple #1
0
        //
        // Extract a minimal cycle or a filament
        //
        void ExtractPrimitive(Point v0, OrderedPointList heap)
        {
            List <Point> visited  = new List <Point>();
            List <Point> sequence = new List <Point>();

            sequence.Add(v0);

            // Create an initial line as (downward) vertical w.r.t. v0; v1 is based on the vertical line through v0
            Point v1    = GetFirstNeighbor(v0); //  GetClockwiseMost(new Point("", v0.X, v0.Y + 1), v0);
            Point vPrev = v0;
            Point vCurr = v1;

            int v0Index = graph.IndexOf(v0);
            int v1Index = graph.IndexOf(v1);

            // Loop until we have a cycle or we have a null (filament)
            while (vCurr != null && !vCurr.Equals(v0) && !visited.Contains(vCurr))
            {
                sequence.Add(vCurr);
                visited.Add(vCurr);
                Point vNext = GetTightestCounterClockwiseNeighbor(vPrev, vCurr);
                vPrev = vCurr;
                vCurr = vNext;
            }

            //
            // Filament: hit an endpoint
            //
            if (vCurr == null)
            {
                // Filament found, not necessarily rooted at v0.
                ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap);
            }
            //
            // Minimal cycle found.
            //
            else if (vCurr.Equals(v0))
            {
                MinimalCycle primitive = new MinimalCycle();

                primitive.AddAll(sequence);

                primitives.Add(primitive);

                if (Utilities.ATOMIC_REGION_GEN_DEBUG)
                {
                    Debug.WriteLine(primitive.ToString());
                }

                // Mark that these edges are a part of a cycle
                for (int p = 0; p < sequence.Count; p++)
                {
                    graph.MarkCycleEdge(sequence[p], sequence[p + 1 < sequence.Count ? p + 1 : 0]);
                }

                graph.RemoveEdge(v0, v1);

                //
                // Check filaments for v0 and v1
                //
                if (graph.nodes[v0Index].NodeDegree() == 1)
                {
                    // Remove the filament rooted at v0.
                    ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap);
                }

                //
                // indices may have changed; update.
                //
                v1Index = graph.IndexOf(v1);
                if (v1Index != -1)
                {
                    if (graph.nodes[v1Index].NodeDegree() == 1)
                    {
                        // Remove the filament rooted at v1.
                        ExtractFilament(v1, graph.nodes[v1Index].edges[0].target, heap);
                    }
                }
            }
            //
            // vCurr was visited earlier
            //
            else
            {
                // A cycle has been found, but is not guaranteed to be a minimal
                // cycle. This implies v0 is part of a filament. Locate the
                // starting point for the filament by traversing from v0 away
                // from the initial v1.
                while (graph.nodes[v0Index].NodeDegree() == 2)
                {
                    // Choose between the the two neighbors
                    if (graph.nodes[v0Index].edges[0].target.Equals(v1))
                    {
                        v1 = v0;
                        v0 = graph.nodes[v0Index].edges[1].target;
                    }
                    else
                    {
                        v1 = v0;
                        v0 = graph.nodes[v0Index].edges[0].target;
                    }

                    // Find the next v0 index
                    v0Index = graph.IndexOf(v0);
                }
                ExtractFilament(v0, v1, heap);
            }
        }
        //
        // Extract a minimal cycle or a filament
        //
        void ExtractPrimitive(Point v0, OrderedPointList heap)
        {
            List<Point> visited = new List<Point>();
            List<Point> sequence = new List<Point>();

            sequence.Add(v0);

            // Create an initial line as (downward) vertical w.r.t. v0; v1 is based on the vertical line through v0
            Point v1 = GetFirstNeighbor(v0); //  GetClockwiseMost(new Point("", v0.X, v0.Y + 1), v0);
            Point vPrev = v0;
            Point vCurr = v1;

            int v0Index = graph.IndexOf(v0);
            int v1Index = graph.IndexOf(v1);

            // Loop until we have a cycle or we have a null (filament)
            while (vCurr != null && !vCurr.Equals(v0) && !visited.Contains(vCurr))
            {
                sequence.Add(vCurr);
                visited.Add(vCurr);
                Point vNext = GetTightestCounterClockwiseNeighbor(vPrev, vCurr);
                vPrev = vCurr;
                vCurr = vNext;
            }

            //
            // Filament: hit an endpoint
            //
            if (vCurr == null)
            {
                // Filament found, not necessarily rooted at v0.
                ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap);
            }
            //
            // Minimal cycle found.
            //
            else if (vCurr.Equals(v0))
            {
                MinimalCycle primitive = new MinimalCycle();

                primitive.AddAll(sequence);

                primitives.Add(primitive);

                if (Utilities.ATOMIC_REGION_GEN_DEBUG)
                {
                    Debug.WriteLine(primitive.ToString());
                }

                // Mark that these edges are a part of a cycle
                for (int p = 0; p < sequence.Count; p++)
                {
                    graph.MarkCycleEdge(sequence[p], sequence[p+1 < sequence.Count ? p+1 : 0]);
                }

                graph.RemoveEdge(v0, v1);

                //
                // Check filaments for v0 and v1
                //
                if (graph.nodes[v0Index].NodeDegree() == 1)
                {
                    // Remove the filament rooted at v0.
                    ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap);
                }

                //
                // indices may have changed; update.
                //
                v1Index = graph.IndexOf(v1);
                if (v1Index != -1)
                {
                    if (graph.nodes[v1Index].NodeDegree() == 1)
                    {
                        // Remove the filament rooted at v1.
                        ExtractFilament(v1, graph.nodes[v1Index].edges[0].target, heap);
                    }
                }
            }
            //
            // vCurr was visited earlier
            //
            else
            {
                // A cycle has been found, but is not guaranteed to be a minimal
                // cycle. This implies v0 is part of a filament. Locate the
                // starting point for the filament by traversing from v0 away
                // from the initial v1.
                while (graph.nodes[v0Index].NodeDegree() == 2)
                {
                    // Choose between the the two neighbors
                    if (graph.nodes[v0Index].edges[0].target.Equals(v1))
                    {
                        v1 = v0;
                        v0 = graph.nodes[v0Index].edges[1].target;
                    }
                    else
                    {
                        v1 = v0;
                        v0 = graph.nodes[v0Index].edges[0].target;
                    }

                    // Find the next v0 index
                    v0Index = graph.IndexOf(v0);
                }
                ExtractFilament(v0, v1, heap);
            }
        }