/// <summary>
        /// Sweeps between the <paramref name="startLayerIndex"/> and <paramref name="endLayerIndex"/>
        /// in the way represented by the step
        /// </summary>
        /// <param name="startLayerIndex">The index of the start layer (where the sweeping starts from).</param>
        /// <param name="endLayerIndex">The index of the last layer (where the sweeping ends).</param>
        /// <param name="step">Increment or decrement of the layer index. (1 or -1)</param>
        /// <returns>The number of the edge crossings.</returns>
        private int Sweeping(int startLayerIndex, int endLayerIndex, int step, bool enableSameMeasureOptimization, out bool changed, ref int phase)
        {
            int crossings = 0;

            changed = false;
            if (_alternatingLayers.Length > 0)
            {
                AlternatingLayer alternatingLayer;
                if (_alternatingLayers[startLayerIndex] == null)
                {
                    alternatingLayer = new AlternatingLayer();
                    alternatingLayer.AddRange(_layers[startLayerIndex].OfType <IData>());
                    alternatingLayer.EnsureAlternatingAndPositions();
                    AddAlternatingLayerToSparseCompactionGraph(alternatingLayer, startLayerIndex);
                    _alternatingLayers[startLayerIndex] = alternatingLayer;
                }
                else
                {
                    alternatingLayer = _alternatingLayers[startLayerIndex];
                }

                OutputAlternatingLayer(alternatingLayer, startLayerIndex, 0);
                for (int i = startLayerIndex; i != endLayerIndex; i += step)
                {
                    int ci             = Math.Min(i, i + step);
                    int prevCrossCount = _crossCounts[ci];

                    if (_alternatingLayers[i + step] != null)
                    {
                        alternatingLayer.SetPositions();
                        _alternatingLayers[i + step].SetPositions();
                        prevCrossCount   = DoCrossCountingAndOptimization(alternatingLayer, _alternatingLayers[i + step], (i < i + step), false, (phase == 2), int.MaxValue);
                        _crossCounts[ci] = prevCrossCount;
                    }

                    int crossCount = CrossingMinimizationBetweenLayers(ref alternatingLayer, i, i + step, enableSameMeasureOptimization, prevCrossCount, phase);

                    if (crossCount < prevCrossCount || phase == 2 || changed)
                    {
                        /* set the sparse compaction graph */
                        AddAlternatingLayerToSparseCompactionGraph(alternatingLayer, i + step);
                        ReplaceLayer(alternatingLayer, i + step);
                        _alternatingLayers[i + step] = alternatingLayer;
                        OutputAlternatingLayer(alternatingLayer, i + step, crossCount);
                        _crossCounts[i] = crossCount;
                        crossings      += crossCount;
                        changed         = true;
                    }
                    else
                    {
                        Debug.WriteLine("Layer " + (i + step) + " has not changed.");
                        alternatingLayer = _alternatingLayers[i + step];
                        crossings       += prevCrossCount;
                    }
                }
            }

            return(crossings);
        }
        private static AlternatingLayer InitialOrderingOfNextLayer(IEnumerable <IData> alternatingLayer, IEnumerable <SugiVertex> nextLayer, bool straightSweep)
        {
            //get the list of the containers and vertices
            var segmentContainerStack = new Stack <ISegmentContainer>(alternatingLayer.OfType <ISegmentContainer>().Reverse());
            var ignorableVertexType   = straightSweep ? VertexTypes.QVertex : VertexTypes.PVertex;
            var vertexStack           = new Stack <SugiVertex>(nextLayer.Where(v => v.Type != ignorableVertexType).OrderBy(v => v.MeasuredPosition).Reverse());
            var newAlternatingLayer   = new AlternatingLayer();

            while (vertexStack.Count > 0 && segmentContainerStack.Count > 0)
            {
                var vertex           = vertexStack.Peek();
                var segmentContainer = segmentContainerStack.Peek();
                if (vertex.MeasuredPosition <= segmentContainer.Position)
                {
                    newAlternatingLayer.Add(vertexStack.Pop());
                }
                else if (vertex.MeasuredPosition >= (segmentContainer.Position + segmentContainer.Count - 1))
                {
                    newAlternatingLayer.Add(segmentContainerStack.Pop());
                }
                else
                {
                    vertexStack.Pop();
                    segmentContainerStack.Pop();
                    var k = (int)Math.Ceiling(vertex.MeasuredPosition - segmentContainer.Position);
                    ISegmentContainer sc1, sc2;
                    segmentContainer.Split(k, out sc1, out sc2);
                    newAlternatingLayer.Add(sc1);
                    newAlternatingLayer.Add(vertex);
                    sc2.Position = segmentContainer.Position + k;
                    segmentContainerStack.Push(sc2);
                }
            }

            if (vertexStack.Count > 0)
            {
                newAlternatingLayer.AddRange(vertexStack.OfType <IData>());
            }
            if (segmentContainerStack.Count > 0)
            {
                newAlternatingLayer.AddRange(segmentContainerStack.OfType <IData>());
            }

            return(newAlternatingLayer);
        }
Beispiel #3
0
        /// <summary>
        /// Sweeps between the <paramref name="startLayerIndex"/> and <paramref name="endLayerIndex"/>
        /// in the way represented by the step.
        /// </summary>
        /// <param name="startLayerIndex">The index of the start layer (where the sweeping starts from).</param>
        /// <param name="endLayerIndex">The index of the last layer (where the sweeping ends).</param>
        /// <param name="step">Increment or decrement of the layer index. (1 or -1)</param>
        /// <param name="enableSameMeasureOptimization">Indicates if the same measure optimization is enabled.</param>
        /// <param name="changed">Indicates if layer has changed or not.</param>
        /// <param name="phase">Algorithm phase.</param>
        /// <returns>The number of the edge crossings.</returns>
        private int Sweeping(
            int startLayerIndex,
            int endLayerIndex,
            int step,
            bool enableSameMeasureOptimization,
            out bool changed,
            ref int phase)
        {
            int crossings = 0;

            changed = false;

            AlternatingLayer alternatingLayer;
            AlternatingLayer layer = _alternatingLayers[startLayerIndex];

            if (layer is null)
            {
                alternatingLayer = new AlternatingLayer();
                alternatingLayer.AddRange(
                    _layers[startLayerIndex]
#if !SUPPORTS_ENUMERABLE_COVARIANT
                    .OfType <IData>()
#endif
                    );
                alternatingLayer.EnsureAlternatingAndPositions();
                AddAlternatingLayerToSparseCompactionGraph(alternatingLayer, startLayerIndex);
                _alternatingLayers[startLayerIndex] = alternatingLayer;
            }
            else
            {
                alternatingLayer = layer;
            }

            for (int i = startLayerIndex; i != endLayerIndex; i += step)
            {
                int ci             = Math.Min(i, i + step);
                int prevCrossCount = _crossCounts[ci];

                AlternatingLayer nextAlternatingLayer = _alternatingLayers[i + step];
                if (nextAlternatingLayer != null)
                {
                    alternatingLayer?.SetPositions();
                    nextAlternatingLayer.SetPositions();
                    prevCrossCount = DoCrossCountingAndOptimization(
                        alternatingLayer,
                        nextAlternatingLayer,
                        i < i + step,
                        false,
                        phase == 2,
                        int.MaxValue);
                    _crossCounts[ci] = prevCrossCount;
                }

                int crossCount = CrossingMinimizationBetweenLayers(
                    ref alternatingLayer,
                    i, i + step,
                    enableSameMeasureOptimization,
                    prevCrossCount,
                    phase);

                if (crossCount < prevCrossCount || phase == 2 || changed)
                {
                    // Set the sparse compaction graph
                    AddAlternatingLayerToSparseCompactionGraph(alternatingLayer, i + step);
                    ReplaceLayer(alternatingLayer, i + step);
                    _alternatingLayers[i + step] = alternatingLayer;
                    _crossCounts[i] = crossCount;
                    crossings      += crossCount;
                    changed         = true;
                }
                else
                {
                    alternatingLayer = nextAlternatingLayer;
                    crossings       += prevCrossCount;
                }
            }

            return(crossings);
        }
Beispiel #4
0
        private static AlternatingLayer InitialOrderingOfNextLayer(
            [NotNull, ItemNotNull] AlternatingLayer alternatingLayer,
            [NotNull, ItemNotNull] IEnumerable <SugiVertex> nextLayer,
            bool straightSweep)
        {
            Debug.Assert(alternatingLayer != null);
            Debug.Assert(nextLayer != null);

            // Get the list of the containers and vertices
            var         segmentContainerStack = new Stack <ISegmentContainer>(alternatingLayer.OfType <ISegmentContainer>().Reverse());
            VertexTypes ignorableVertexType   = straightSweep ? VertexTypes.QVertex : VertexTypes.PVertex;
            var         vertexStack           = new Stack <SugiVertex>(
                nextLayer
                .Where(v => v.Type != ignorableVertexType)
                .OrderBy(v => v.MeasuredPosition)
                .Reverse());
            var newAlternatingLayer = new AlternatingLayer();

            while (vertexStack.Count > 0 && segmentContainerStack.Count > 0)
            {
                SugiVertex        vertex           = vertexStack.Peek();
                ISegmentContainer segmentContainer = segmentContainerStack.Peek();
                if (vertex.MeasuredPosition <= segmentContainer.Position)
                {
                    newAlternatingLayer.Add(vertexStack.Pop());
                }
                else if (vertex.MeasuredPosition >= segmentContainer.Position + segmentContainer.Count - 1)
                {
                    newAlternatingLayer.Add(segmentContainerStack.Pop());
                }
                else
                {
                    vertexStack.Pop();
                    segmentContainerStack.Pop();
                    int k = (int)Math.Ceiling(vertex.MeasuredPosition - segmentContainer.Position);
                    segmentContainer.Split(k, out ISegmentContainer container1, out ISegmentContainer container2);
                    newAlternatingLayer.Add(container1);
                    newAlternatingLayer.Add(vertex);
                    container2.Position = segmentContainer.Position + k;
                    segmentContainerStack.Push(container2);
                }
            }

            if (vertexStack.Count > 0)
            {
                newAlternatingLayer.AddRange(
                    vertexStack
#if !SUPPORTS_ENUMERABLE_COVARIANT
                    .OfType <IData>()
#endif
                    );
            }

            if (segmentContainerStack.Count > 0)
            {
                newAlternatingLayer.AddRange(
                    segmentContainerStack
#if !SUPPORTS_ENUMERABLE_COVARIANT
                    .OfType <IData>()
#endif
                    );
            }

            return(newAlternatingLayer);
        }