/// <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 int CrossingMinimizationBetweenLayers( [NotNull, ItemNotNull] ref AlternatingLayer alternatingLayer, int actualLayerIndex, int nextLayerIndex, bool enableSameMeasureOptimization, int prevCrossCount, int phase) { // Decide which way we are sweeping (up or down) // Straight = down, reverse = up bool straightSweep = actualLayerIndex < nextLayerIndex; AlternatingLayer nextAlternatingLayer = alternatingLayer.Clone(); // 1 AppendSegmentsToAlternatingLayer(nextAlternatingLayer, straightSweep); // 2 ComputeMeasureValues(alternatingLayer, nextLayerIndex, straightSweep); nextAlternatingLayer.SetPositions(); // 3 nextAlternatingLayer = InitialOrderingOfNextLayer(nextAlternatingLayer, _layers[nextLayerIndex], straightSweep); // 4 PlaceQVertices(nextAlternatingLayer, _layers[nextLayerIndex], straightSweep); nextAlternatingLayer.SetPositions(); // 5 int crossCount = DoCrossCountingAndOptimization( alternatingLayer, nextAlternatingLayer, straightSweep, enableSameMeasureOptimization, phase == 2, prevCrossCount); // 6 nextAlternatingLayer.EnsureAlternatingAndPositions(); alternatingLayer = nextAlternatingLayer; return(crossCount); }
/// <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); }