double GetInkgain(PolylinePoint pp, Dictionary <PointPair, Set <Metroline> > segsToPolylines, Point a, Point b, Point c)
        {
            Set <Metroline> abPolylines, bcPolylines, abcPolylines;

            FindPolylines(pp, segsToPolylines, out abPolylines, out bcPolylines, out abcPolylines);
            double gain = 0;
            //ink
            double oldInk = ink;
            double newInk = ink;
            double ab     = (a - b).Length;
            double bc     = (b - c).Length;
            double ac     = (a - c).Length;

            if (abPolylines.Count == abcPolylines.Count)
            {
                newInk -= ab;
            }
            if (bcPolylines.Count == abcPolylines.Count)
            {
                newInk -= bc;
            }
            if (!segsToPolylines.ContainsKey(new PointPair(a, c)) || segsToPolylines[new PointPair(a, c)].Count == 0)
            {
                newInk += ac;
            }
            gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings);

            //path lengths
            foreach (var metroline in abcPolylines)
            {
                double oldLength = polylineLength[metroline];
                double newLength = polylineLength[metroline];
                newLength -= ab + bc - ac;

                gain += CostCalculator.PathLengthsError(oldLength, newLength, metroline.IdealLength, bundlingSettings);
            }

            //radii
            double nowR     = GetCurrentHubRadius(metroGraphData.PointToStations[a]);
            double widthABC = metroGraphData.GetWidth(abcPolylines, bundlingSettings.EdgeSeparation);
            double widthABD = metroGraphData.GetWidth(abPolylines - abcPolylines, bundlingSettings.EdgeSeparation);
            double idealR   = HubRadiiCalculator.GetMinRadiusForTwoAdjacentBundles(nowR, a, c, b, widthABC, widthABD, metroGraphData, bundlingSettings);

            if (idealR > nowR)
            {
                gain -= CostCalculator.RError(idealR, nowR, bundlingSettings);
            }

            //check opposite side
            nowR = GetCurrentHubRadius(metroGraphData.PointToStations[c]);
            double widthCBD = metroGraphData.GetWidth(bcPolylines - abcPolylines, bundlingSettings.EdgeSeparation);

            idealR = HubRadiiCalculator.GetMinRadiusForTwoAdjacentBundles(nowR, c, b, a, widthCBD, widthABC, metroGraphData, bundlingSettings);
            if (idealR > nowR)
            {
                gain -= CostCalculator.RError(idealR, nowR, bundlingSettings);
            }

            return(gain);
        }
 SimulatedAnnealing(MetroGraphData metroGraphData, BundlingSettings bundlingSettings)
 {
     this.metroGraphData   = metroGraphData;
     this.bundlingSettings = bundlingSettings;
     costCalculator        = new CostCalculator(metroGraphData, bundlingSettings);
     cache = new IntersectionCache(metroGraphData, bundlingSettings, costCalculator, metroGraphData.Cdt);
 }
 public IntersectionCache(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, CostCalculator costCalculator, Cdt cdt) {
     Debug.Assert(cdt!=null);
     this.metroGraphData = metroGraphData;
     this.bundlingSettings = bundlingSettings;
     this.costCalculator = costCalculator;
     this.cdt = cdt;
 }
 public IntersectionCache(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, CostCalculator costCalculator, Cdt cdt)
 {
     Debug.Assert(cdt != null);
     this.metroGraphData   = metroGraphData;
     this.bundlingSettings = bundlingSettings;
     this.costCalculator   = costCalculator;
     this.cdt = cdt;
 }
示例#5
0
        double Cost()
        {
            double cost = 0;

            foreach (var v in metroGraphData.VirtualNodes())
            {
                double idealR = v.cachedIdealRadius;
                cost += CostCalculator.RError(idealR, v.Radius, bundlingSettings);
            }
            return(cost);
        }
        double ComputeCostDeltaAfterEdgeGluing(Station node, Station a, Station b, Point newp)
        {
            double gain = 0;

            //ink
            double oldInk = metroGraphData.Ink;
            double newInk = metroGraphData.Ink - (node.Position - b.Position).Length - (node.Position - a.Position).Length +
                            (node.Position - newp).Length + (newp - a.Position).Length + (newp - b.Position).Length;

            gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings);

            //path lengths
            foreach (var metroline in metroGraphData.GetIjInfo(node, b).Metrolines)
            {
                double oldLength = metroline.Length;
                double newLength = metroline.Length - (node.Position - b.Position).Length +
                                   (node.Position - newp).Length + (newp - b.Position).Length;
                gain += CostCalculator.PathLengthsError(oldLength, newLength, metroline.IdealLength, bundlingSettings);
            }
            foreach (var metroline in metroGraphData.GetIjInfo(node, a).Metrolines)
            {
                double oldLength = metroline.Length;
                double newLength = metroline.Length - (node.Position - a.Position).Length +
                                   (node.Position - newp).Length + (newp - a.Position).Length;
                gain += CostCalculator.PathLengthsError(oldLength, newLength, metroline.IdealLength, bundlingSettings);
            }

            //also compute radii gain
            //double nowR = Math.Min(GetCurrentHubRadius(node), (node.Position - newp).Length);
            //double id2 = HubRadiiCalculator.CalculateIdealHubRadiusWithNeighbors(metroGraphData, bundlingSettings, node);
            double id2    = node.cachedIdealRadius;
            double nowR   = GetCurrentHubRadius(node);
            double idealR = HubRadiiCalculator.GetMinRadiusForTwoAdjacentBundles(nowR, node, node.Position, a, b, metroGraphData, bundlingSettings);

            if (idealR > nowR)
            {
                gain += CostCalculator.RError(idealR, nowR, bundlingSettings);
            }

            if (id2 > (node.Position - newp).Length && !node.IsRealNode)
            {
                gain -= CostCalculator.RError(id2, (node.Position - newp).Length, bundlingSettings);
            }

            return(gain);
        }
        double ComputeCostDeltaAfterNodeGluing(Station i, Station j, Dictionary <Station, Station> gluingMap)
        {
            double d = (i.Position - j.Position).Length;

            if (i.Radius >= d || j.Radius >= d)
            {
                return(1.0);
            }

            double gain = 0;

            //ink
            double oldInk = metroGraphData.Ink;
            double newInk = metroGraphData.Ink - (j.Position - i.Position).Length;

            foreach (var adj in i.Neighbors)
            {
                var k = Glued(adj, gluingMap);
                newInk -= (k.Position - i.Position).Length;
                newInk += (metroGraphData.RealEdgeCount(k, j) == 0 ? (k.Position - j.Position).Length : 0);
            }

            gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings);

            //path lengths
            foreach (var metroInfo in metroGraphData.MetroNodeInfosOfNode(i))
            {
                double oldLength = metroInfo.Metroline.Length;
                double newLength = metroInfo.Metroline.Length;

                PolylinePoint pi = metroInfo.PolyPoint;
                PolylinePoint pa = pi.Prev;
                PolylinePoint pb = pi.Next;

                newLength -= (pa.Point - i.Position).Length + (pb.Point - i.Position).Length;
                newLength += (pa.Point - j.Position).Length + (pb.Point - j.Position).Length;

                gain += CostCalculator.PathLengthsError(oldLength, newLength, metroInfo.Metroline.IdealLength,
                                                        bundlingSettings);
            }

            return(gain);
        }
        bool FixRouting(HashSet <Point> changedPoints)
        {
            stationsForOptimizations = GetStationsForOptimizations(changedPoints);

            cache.InitializeCostCache();

            double step   = MaxStep;
            double energy = double.PositiveInfinity;

            List <Point> x         = new List <Point>(metroGraphData.VirtualNodes().Select(v => v.Position));
            int          iteration = 0;

            while (iteration++ < MaxIterations)
            {
                bool coordinatesChanged = TryMoveNodes();
                //TimeMeasurer.DebugOutput("  #iter = " + iteration + " moved: " + cnt + "/" + metroGraphData.VirtualNodes().Count() + " step: " + step);

                if (iteration <= 1 && !coordinatesChanged)
                {
                    return(false);
                }
                if (!coordinatesChanged)
                {
                    break;
                }

                double oldEnergy = energy;
                energy = CostCalculator.Cost(metroGraphData, bundlingSettings);
                //TimeMeasurer.DebugOutput("energy: " + energy);

                step = UpdateMaxStep(step, oldEnergy, energy);
                List <Point> oldX = x;
                x = new List <Point>(metroGraphData.VirtualNodes().Select(v => v.Position));
                if (step < MinStep || Converged(step, oldX, x))
                {
                    break;
                }
            }

            //TimeMeasurer.DebugOutput("SA completed after " + iteration + " iterations");
            return(true);
        }
 SimulatedAnnealing(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) {
     this.metroGraphData = metroGraphData;
     this.bundlingSettings = bundlingSettings;
     costCalculator = new CostCalculator(metroGraphData, bundlingSettings);
     cache = new IntersectionCache(metroGraphData, bundlingSettings, costCalculator, metroGraphData.Cdt);
 }