/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="step"></param> /// <param name="baryCenter"></param> /// <param name="byRealPosition"></param> /// <returns>The index of the layer which is not ordered by <paramref name="baryCenter"/> anymore. /// If all of the layers ordered, and phase2 sweep done it returns with -1.</returns> protected int SugiyamaPhase2Sweep(int start, int end, int step, BaryCenter baryCenter, bool byRealPosition) { CrossCount crossCountDirection = baryCenter == BaryCenter.Up ? CrossCount.Up : CrossCount.Down; for (int i = start; i != end; i += step) { var layer = _layers[i]; //switch the vertices with the same barycenters, if and only if there will be less barycenters layer.Measure(baryCenter, byRealPosition); layer.FindBestPermutation(crossCountDirection); if (byRealPosition) { HorizontalPositionAssignmentOnLayer(i, baryCenter); CopyPositionsSilent(false); } else { CopyPositions(); } OnIterationEnded(" Phase 2 sweepstep finished [" + baryCenter + "-barycentering on layer " + i + "]"); if (i + step != end) { var nextLayer = _layers[i + step]; if (!nextLayer.IsOrderedByBaryCenters(baryCenter, byRealPosition)) { return(i + step); } } } return(-1); }
/// <summary> /// Sweeps in one direction in the 1st Phase of the Sugiyama's algorithm. /// </summary> /// <param name="start">The index of the layer where the sweeping starts.</param> /// <param name="end">The index of the layer where the sweeping ends.</param> /// <param name="step">Stepcount.</param> /// <param name="baryCenter">Kind of the barycentering (Up/Down-barycenter).</param> /// <param name="dirty">If this is a dirty sweep</param> /// <param name="byRealPosition"></param> /// <returns></returns> protected bool SugiyamaPhase1Sweep(int start, int end, int step, BaryCenter baryCenter, bool dirty, bool byRealPosition) { bool hasOptimization = false; CrossCount crossCounting = baryCenter == BaryCenter.Up ? CrossCount.Up : CrossCount.Down; bool sourceByMeasure = crossCounting == CrossCount.Down; for (int i = start; i != end; i += step) { var layer = _layers[i]; int modifiedCrossing = 0; int originalCrossing = 0; if (!dirty) { //get the count of the edge crossings originalCrossing = layer.CalculateCrossCount(crossCounting); } //measure the vertices by the given barycenter layer.Measure(baryCenter, byRealPosition); if (!dirty) { //get the modified crossing count modifiedCrossing = layer.CalculateCrossCount(crossCounting, sourceByMeasure, !sourceByMeasure); } if (modifiedCrossing < originalCrossing || dirty) { layer.SortByMeasure(); hasOptimization = true; } if (byRealPosition) { HorizontalPositionAssignmentOnLayer(i, baryCenter); CopyPositionsSilent(false); } else { CopyPositions(); } OnIterationEnded(" Phase 1 sweepstep finished [" + baryCenter + "-barycentering on layer " + i + "]"); } return(hasOptimization); }
public int CalculateCrossCount(CrossCount crossCountDirection, bool sourcesByMeasure, bool targetsByMeasure) { int crossCount = 0; bool calculateUpCrossings = (crossCountDirection & CrossCount.Up) == CrossCount.Up; bool calculateDownCrossings = (crossCountDirection & CrossCount.Down) == CrossCount.Down; if (calculateUpCrossings) { crossCount += CalculateCrossings(UpEdges, sourcesByMeasure, targetsByMeasure); } if (calculateDownCrossings) { crossCount += CalculateCrossings(DownEdges, sourcesByMeasure, targetsByMeasure); } return(crossCount); }
public int CalculateCrossCount(CrossCount crossCountDirection) { return(CalculateCrossCount(crossCountDirection, false, false)); }
/// <summary> /// Changes the order of the vertices with the same measure. /// It does that in the brute-force way (every permutation will be analyzed). /// Vertices should be sorted by it's measures. /// </summary> public void FindBestPermutation(CrossCount crossCounting) { int bestKnownCrossCount = CalculateCrossCount(crossCounting); //get the vertices with the same index var verticesWithSameMeasure = new List <SugiVertex>(); int startIndex, endIndex; for (startIndex = 0; startIndex < Count; startIndex = endIndex + 1) { for (endIndex = startIndex + 1; endIndex < Count && this[startIndex].Measure == this[endIndex].Measure; endIndex++) { } endIndex -= 1; if (endIndex > startIndex) { for (int i = startIndex; i <= endIndex; i++) { verticesWithSameMeasure.Add(this[i]); } } } //save the original positions SavePositionsToTemp(); //null PermutationIndex foreach (var v in this) { v.PermutationIndex = 0; } //create initial permutation for (int i = 0; i < verticesWithSameMeasure.Count; i++) { verticesWithSameMeasure[i].PermutationIndex = 0; } while (Permutate(verticesWithSameMeasure)) { //sort the vertices with the same measure by barycenter Sort(MeasureAndPermutationIndexComparer.Instance); ReassignPositions(); int newCrossCount = CalculateCrossCount(crossCounting); if (newCrossCount < bestKnownCrossCount) { SavePositionsToTemp(); bestKnownCrossCount = newCrossCount; } } //the best solution is in the temp LoadPositionsFromTemp(); Sort(PositionComparer.Instance); ReassignPositions(); }