/// <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); }
/// <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); }
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); }