Пример #1
0
        // "Dumb mutation" - just swap some elements
        private void mutateDumb(TSPSolution initial)
        {
            PermutationStandard current = new PermutationStandard(initial);

            current.swap(rnd.Next(current.size), rnd.Next(current.size));
            current.applyToTSPSolution(initial);
        }
Пример #2
0
        //returns number of updates to BSSF made during the exploration
        private void explore(SearchSpace current, PriorityQ q)
        {
            List <int> citiesRemaining = current.CitiesRemaining;
            bool       leaf            = true;

            //O()
            foreach (int city in citiesRemaining)
            {
                leaf = false;
                SearchSpace child = new SearchSpace(current, city);//O(n^2)
                statesCreated++;
                if (child.Bound < costOfBssf())
                {
                    q.Insert(child);
                }
                else
                {
                    statesPruned++;
                }
            }

            if (leaf)
            {
                TSPSolution possibleSoln = new TSPSolution(current.Route, Cities);
                if (possibleSoln.costOfRoute() < costOfBssf())
                {
                    bssf = possibleSoln;
                    solutionsFound++;
                }
            }
        }
Пример #3
0
        // performs local search (switches two points in the solution) and searches for better result
        private Boolean updateBssf(int[] route)
        {
            Boolean result = false;

            for (int i = 0; i < _size; i++)
            {
                for (int j = i + 1; j < _size; j++)
                {
                    int[] child = new int[route.Length];
                    Array.Copy(route, child, _size);
                    child[i] = route[j]; //switch two points
                    child[j] = route[i];
                    // check if child is a new local/global max
                    if (costOfRoute(child) < costOfRoute(myBssf))
                    {
                        myBssf = child;
                        if (costOfRoute(myBssf) < bssf.costOfRoute())
                        {
                            bssf = bssfFromIntArray(new ArrayList(myBssf));
                        }
                        result = true;
                    }
                }
            }
            return(result);
        }
Пример #4
0
        public TSPSolution solve(TSPInput input)
        {
            TSPSolution best = null;

            for (int r = 0; r < 5; ++r)
            {
                Console.WriteLine($@"== RUN:{r} ==");
                population.Clear();
                for (int i = 0; i < PopulationSize; ++i)
                {
                    population.Add(getRandomSolution(input));
                }
                run();

                var tmp = GetBest();
                Console.WriteLine($@"Distance: {tmp.totalDistance}");

                if (best == null || tmp.totalDistance < best.totalDistance)
                {
                    best = tmp;
                }
            }
            visualizer.draw(best);
            return(best);
        }
Пример #5
0
 public void solveAndShow()
 {
     solution = solver.solve(inp);
     solution.computeDistance();
     Length_label.Text = solution.totalDistance.ToString();
     vis.draw(solution);
 }
Пример #6
0
        /////////////////////////////////////////////////////////////////////////////////////////////
        // These additional solver methods will be implemented as part of the group project.
        ////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// finds the greedy tour starting from each city and keeps the best (valid) one
        /// </summary>
        /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns>
        public string[] greedySolveProblem()
        {
            string[] results = new string[3];

            // TODO: Add your implementation for a greedy solver here.
            Stopwatch timer = new Stopwatch();

            timer.Start();
            Route = new ArrayList();


            greedySolveSub();
            // At this point, we have all the cities.
            // We have a problem though. What if the last city does not go back to the first one???
            while (((City)Route[Route.Count - 1]).costToGetTo((City)Route[0]) == Double.PositiveInfinity)
            {
                greedySolveSub();
            }

            bssf = new TSPSolution(Route);
            timer.Stop();

            results[COST]  = costOfBssf().ToString();   // load results into array here, replacing these dummy values
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = "1";

            return(results);
        }
Пример #7
0
        // Reset the problem instance
        private void resetData()
        {
            cities = new City[size];
            bssf   = null;

            if (mode == HardMode.Modes.Easy)
            {
                for (int i = 0; i < size; i++)
                {
                    cities[i] = new City(rnd.NextDouble(), rnd.NextDouble());
                }
            }
            else // Medium and hard
            {
                for (int i = 0; i < size; i++)
                {
                    cities[i] = new City(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble() * City.MAX_ELEVATION);
                }
            }

            HardMode mm = new HardMode(this.mode, this.rnd, cities);

            if (mode == HardMode.Modes.Hard)
            {
                int edgesToRemove = (int)(size * FRACTION_OF_PATHS_TO_REMOVE);
                mm.removePaths(edgesToRemove);
            }
            City.setModeManager(mm);
        }
Пример #8
0
        // "Smart mutation" - try to swap and improve the distance
        private void mutateSmart(TSPSolution initial)
        {
            PermutationStandard current = new PermutationStandard(initial);

            var start = current.eval();
            var best  = start;

            var bestX = 0;
            var bestY = 0;

            for (int i = 0; i < current.perm.Length; ++i)
            {
                for (int j = 0; j < current.perm.Length; ++j)
                {
                    current.swap(i, j);
                    var temp = current.eval();
                    current.swap(j, i);

                    if (temp < best)
                    {
                        best  = temp;
                        bestX = i;
                        bestY = j;
                    }
                }
            }

            if (best < start)
            {
                current.swap(bestX, bestY);
                current.applyToTSPSolution(initial);
            }
        }
Пример #9
0
        /////////////////////////////////////////////////////////////////////////////////////////////
        // These additional solver methods will be implemented as part of the group project.
        ////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// finds the greedy tour starting from each city and keeps the best (valid) one
        /// </summary>
        /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns>
        // O(n^3) - goes through each city for each city, with each city as a root node - n*n*n
        public string[] greedySolveProblem()
        {
            // initialize the vairables
            int count = 0;

            string[] results = new string[3];
            int[]    perm    = new int[Cities.Length];
            Route = new ArrayList();
            double    currSol = Double.PositiveInfinity;
            Stopwatch timer   = new Stopwatch();

            timer.Start();
            // for each city as a starting node, find the best greedy solution
            // greedy for one node - O(n^2), doing that for each city as a root:
            // O(n^3)
            for (int i = 0; i < Cities.Length; i++)
            {
                ArrayList   newRoute    = findGreedyPath(i);
                TSPSolution greedyRoute = new TSPSolution(newRoute);
                double      temp        = costOfBssf();
                if (temp < currSol)
                {
                    currSol = temp;
                    Route   = newRoute;
                    bssf    = greedyRoute;
                }
            }
            timer.Stop();

            results[COST]  = costOfBssf().ToString();                         // load results array
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = count.ToString();

            return(results);
        }
Пример #10
0
        public TSPSolution solve(TSPInput input)
        {
            GreedySolver s = new GreedySolver();

            best = s.solve(input).computeDistance() + 1;

            bestSolution = new int[input.nodesCount];
            List <int> current = new List <int>();

            current.Add(0);
            List <int> remaining = new List <int>();

            for (int i = 1; i < input.nodesCount; i++)
            {
                remaining.Add(i);
            }
            trySolve(input, current, remaining, 0);
            TSPSolution result = new TSPSolution(input);

            for (int i = 0; i < input.nodesCount - 1; i++)
            {
                result.setSuccessor(bestSolution[i], bestSolution[i + 1]);
            }
            result.setSuccessor(bestSolution[input.nodesCount - 1], 0);
            return(result);
        }
Пример #11
0
        public TSPSolution solve(TSPInput input)
        {
            Console.WriteLine("Hill climbing started");
            current     = initialize(input);
            currentBest = current.convertToTSPSol();
            visualizer.draw(currentBest);
            stop = false;
            int steps = 0;

            while (!stop)
            {
                steps++;
                goOneStep();
                if (steps % 10 == 0)
                {
                    currentBest = current.convertToTSPSol();
                    visualizer.draw(currentBest);
                    Console.WriteLine("Steps: " + steps + " Best distance: " + currentBest.totalDistance);
                }
            }
            Console.WriteLine("Search ended");
            currentBest = current.convertToTSPSol();
            visualizer.draw(currentBest);
            Console.WriteLine("Steps: " + steps + " Best distance: " + currentBest.totalDistance);
            return(currentBest);
        }
Пример #12
0
        public void draw(TSPSolution sol, bool clear = true)
        {
            draw(sol.inp, clear);
            int j = 0, previous = 0;

            for (int i = 0; i < sol.inp.nodesCount; i++)
            {
                TSPPoint first = sol.inp.getPoint(j), second = sol.inp.getPoint(sol.getSuccessor(j, previous));
                Pen      pen = Pens.BlueViolet;
                for (int k = 0; k < sol.inp.nodesCount; k++)
                {
                    if (Edge.isCrossing(first, second, sol.inp.getPoint(k), sol.inp.getPoint(sol.getSuccessor(k))) &&
                        Edge.isCrossing(sol.inp.getPoint(k), sol.inp.getPoint(sol.getSuccessor(k)), first, second))
                    {
                        pen = Pens.Red;
                        break;
                    }
                }
                //TODO vybarvit cervene ty co se krizi - hotovo
                g.DrawLine(pen, (float)(first.x * xStretch + nodeSize / 2), (float)(first.y * yStretch + nodeSize / 2),
                           (float)(second.x * xStretch + nodeSize / 2), (float)(second.y * yStretch + nodeSize / 2));
                int pom = j;
                j        = sol.getSuccessor(j, previous);
                previous = pom;
            }
            screen.Refresh();
        }
Пример #13
0
        /// <summary>
        /// Reset the problem instance.
        /// </summary>
        private void resetData()
        {
            Cities = new City[_size];
            Route  = new List <int>(_size);
            bssf   = null;

            if (_mode == HardMode.Modes.Easy)
            {
                for (int i = 0; i < _size; i++)
                {
                    Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble());
                }
            }
            else // Medium and hard
            {
                for (int i = 0; i < _size; i++)
                {
                    Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble() * City.MAX_ELEVATION);
                }
            }

            HardMode mm = new HardMode(this._mode, this.rnd, Cities);

            if (_mode == HardMode.Modes.Hard)
            {
                int edgesToRemove = (int)(_size * FRACTION_OF_PATHS_TO_REMOVE);
                mm.removePaths(edgesToRemove);
            }
            City.setModeManager(mm);

            cityBrushStyle          = new SolidBrush(Color.Black);
            cityBrushStartStyle     = new SolidBrush(Color.Red);
            routePenStyle           = new Pen(Color.Blue, 1);
            routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
        }
Пример #14
0
        public string[] greedySolveProblem()
        {
            string[] results = new string[3];
            var      watch   = System.Diagnostics.Stopwatch.StartNew();

            for (int i = 0; i < Cities.Length; i++)
            {
                TSPSolution temp       = greedySolveProblem(i);
                double      tempLength = temp.costOfRoute();
                double      bssfLength = costOfBssf();
                if (bssf == null)
                {
                    bssf = temp;
                }
                else
                {
                    if (temp.costOfRoute() < costOfBssf())
                    {
                        bssf = temp;
                    }
                }
            }

            results[COST]  = bssf.costOfRoute().ToString();   // load results into array here, replacing these dummy values
            results[TIME]  = watch.Elapsed.ToString();
            results[COUNT] = "1";
            return(results);
        }
Пример #15
0
        //gets BSSF using random cycle
        private void defaultGetBSSF()
        {
            int i, swap, temp, count = 0;

            int[] perm = new int[Cities.Length];
            Route = new List <int>();
            Random rnd = new Random();

            do
            {
                for (i = 0; i < perm.Length; i++)                                 // create a random permutation template
                {
                    perm[i] = i;
                }
                for (i = 0; i < perm.Length; i++)
                {
                    swap = i;
                    while (swap == i)
                    {
                        swap = rnd.Next(0, Cities.Length);
                    }
                    temp       = perm[i];
                    perm[i]    = perm[swap];
                    perm[swap] = temp;
                }
                Route.Clear();
                for (i = 0; i < Cities.Length; i++)                            // Now build the route using the random permutation
                {
                    Route.Add(perm[i]);
                }
                bssf = new TSPSolution(Route, Cities);
                count++;
            } while (costOfBssf() == double.PositiveInfinity);                // until a valid route is found
        }
Пример #16
0
        public string[] fancySolveProblem()
        {
            string[] results = new string[3];
            Route = new ArrayList();
            GeneticSolver geneticSolver = new GeneticSolver(ref Cities);

            geneticSolver.solve();
            ArrayList newRoute = new ArrayList();

            byte[] gene = geneticSolver.getBestRoute();
            //Console.WriteLine(string.Join(",", gene));
            for (int i = 0; i < gene.Length; i++)
            {
                newRoute.Add(Cities[gene[i]]);
            }
            TSPSolution solution = new TSPSolution(newRoute);

            bssf  = solution;
            Route = newRoute;

            //results[COST]  = geneticSolver.getCost();
            results[COST]  = costOfBssf().ToString();
            results[TIME]  = geneticSolver.getTime();
            results[COUNT] = geneticSolver.getCount();

            return(results);
        }
Пример #17
0
        public string[] fancySolveProblem()
        {
            string[] results = new string[3];

            // implement simulated annealing
            string[] origResults = defaultSolveProblem();
            double   origCost    = Convert.ToDouble(origResults[COST]);
            //City start = (City)Route[0];
            double bestCostSoFar = origCost;
            double tempBestCost  = origCost;
            int    temperature   = 10000;

            while (temperature != 0)
            {
                Random    rand      = new Random();
                int       random    = rand.Next(0, Cities.Length);
                int       random2   = rand.Next(0, Cities.Length);
                City      one       = (City)Route[random];
                City      two       = (City)Route[random2];
                ArrayList copyRoute = new ArrayList();
                for (int i = 0; i < Route.Count; i++)
                {
                    if (i == random)
                    {
                        copyRoute.Add(two);
                    }
                    else if (i == random2)
                    {
                        copyRoute.Add(one);
                    }
                    else
                    {
                        copyRoute.Add(Route[i]);
                    }
                }
                TSPSolution temp = new TSPSolution(copyRoute);
                double      var  = temp.costOfRoute();
                if (temp.costOfRoute() != Double.PositiveInfinity)
                {
                    if (isAcceptable(tempBestCost, temp.costOfRoute(), temperature))
                    {
                        Route        = copyRoute;
                        tempBestCost = temp.costOfRoute();
                        if (tempBestCost < bestCostSoFar)
                        {
                            bestCostSoFar = tempBestCost;
                            bssf          = temp;
                        }
                    }
                }

                temperature -= 5;
            }


            results[COST]  = bssf.costOfRoute().ToString();       // load results into array here, replacing these dummy values
            results[TIME]  = "-1";
            results[Count] = "-1";
            return(results);
        }
Пример #18
0
        private TSPSolution solve(TSPInput input, bool hasEdge = false, int startNode = 0, int endNode = 0)
        {
            TSPSolution result = null;

            if (hasEdge)
            {
                result = new TSPSolutionPath(input, startNode, endNode);
            }
            else
            {
                result = new TSPSolution(input);
            }
            succ = new List <List <int> >();
            edge predefinedEdge = default;

            edgesUsed = 0;
            List <edge> edges = new List <edge>();

            for (int i = 0; i < input.nodesCount; i++)
            {
                succ.Add(new List <int>());
                for (int j = 0; j < i; j++)
                {
                    edge ed = new edge(i, j, input.getDistance(i, j));
                    if (hasEdge && (startNode == i && endNode == j) || (startNode == j && endNode == i))
                    {
                        predefinedEdge = ed;
                    }
                    else
                    {
                        edges.Add(ed);
                    }
                }
            }
            if (hasEdge)
            {
                addToSolution(predefinedEdge);
            }

            edges.Sort((a, b) => (int)(a.distance - b.distance));
            int index = -1;

            while (edgesUsed < input.nodesCount)
            {
                index++;
                edge e = edges[index];
                if (succ[e.node1].Count >= 2 || succ[e.node2].Count >= 2)
                {
                    continue;
                }
                if (createsCycle(e) && edgesUsed != input.nodesCount - 1)
                {
                    continue;
                }
                addToSolution(e);
            }
            addEdgesToResult(result);
            return(result);
        }
Пример #19
0
 public void applyToTSPSolution(TSPSolution sol)
 {
     for (int i = 0; i < size - 1; i++)
     {
         sol.setSuccessor(perm[i], perm[i + 1]);
     }
     sol.setSuccessor(perm[size - 1], perm[0]);
 }
Пример #20
0
        public string[] fancySolveProblem()
        {
            string[] results = new string[3];
            //set initial bssf
            initialBssf = true;
            greedySolveProblem();
            //defaultSolveProblem();
            Console.WriteLine("---------------");
            Console.WriteLine("Initial bssf cost: " + bssf.costOfRoute().ToString());
            Stopwatch timer = new Stopwatch();
            // TODO bssf = output of greedy algorithm
            int  numCities = Cities.Length;
            int  solutions = 0;
            bool improved  = true;

            timer.Start();
            // while(bestChild.route < bssf.route
            while (improved)
            {
                long time = timer.ElapsedMilliseconds;
                if (time > time_limit)
                {
                    Console.WriteLine("Fancy timed out");
                    break;
                }
                improved = false;
                for (int i = 0; i < numCities - 1; i++)
                {
                    for (int k = 0; k < numCities - 1; k++)
                    {
                        if (i == k)
                        {
                            continue;
                        }
                        // swap i and k
                        TSPSolution checkSolution = swap(i, k);
                        solutions++;
                        double cost = checkSolution.costOfRoute();
                        // check to see if it's a better solution than best child
                        if (cost < bssf.costOfRoute())
                        {
                            // if so, set best child be a solutionn
                            bssf     = checkSolution;
                            improved = true;
                        }
                        //if didn't improve, found local optimum
                    }
                }
            }
            Console.WriteLine("K-opt cost: " + bssf.costOfRoute().ToString());
            Console.WriteLine("Number of solutions: " + solutions);
            timer.Stop();
            results[COST]  = bssf.costOfRoute().ToString();               // load results into array here, replacing these dummy values
            results[TIME]  = timer.Elapsed.TotalSeconds.ToString();
            results[COUNT] = solutions.ToString();

            return(results);
        }
Пример #21
0
 public PermutationStandard(TSPSolution sol) : this(sol.inp)
 {
     perm[0] = 0;
     perm[1] = sol.getSuccessor(perm[0]);
     for (int i = 1; i < size - 1; i++)
     {
         perm[i + 1] = sol.getSuccessor(perm[i], perm[i - 1]);
     }
 }
Пример #22
0
        public string[] fancySolveProblem()
        {
            string[]  results = new string[3];
            Stopwatch timer = new Stopwatch();
            int       i, swap, temp, count = 0;

            int[] perm = new int[Cities.Length];
            Route = new ArrayList();
            Random rnd = new Random();

            timer.Start();

            const int ITERATIONS = 1000000;

            for (int iteration = 0; iteration < ITERATIONS; ++iteration)
            {
                do
                {
                    for (i = 0; i < perm.Length; i++)                                 // create a random permutation template
                    {
                        perm[i] = i;
                    }
                    for (i = 0; i < perm.Length; i++)
                    {
                        swap = i;
                        while (swap == i)
                        {
                            swap = rnd.Next(0, Cities.Length);
                        }
                        temp       = perm[i];
                        perm[i]    = perm[swap];
                        perm[swap] = temp;
                    }
                    Route.Clear();
                    for (i = 0; i < Cities.Length; i++)                            // Now build the route using the random permutation
                    {
                        Route.Add(Cities[perm[i]]);
                    }

                    TSPSolution solution = new TSPSolution(Route);
                    if (solution.costOfRoute() < costOfBssf() || costOfBssf() == -1)
                    {
                        bssf = solution;
                    }
                    count++;
                } while (costOfBssf() == double.PositiveInfinity);                // until a valid route is found
            }

            timer.Stop();

            results[COST]  = costOfBssf().ToString();                         // load results array
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = count.ToString();

            return(results);
        }
Пример #23
0
        /////////////////////////////////////////////////////////////////////////////////////////////
        // These additional solver methods will be implemented as part of the group project.
        ////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// finds the greedy tour starting from each city and keeps the best (valid) one
        /// </summary>
        /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns>
        public string[] greedySolveProblem()
        {
            string[] results = new string[3];

            GreedySolver greedy = new GreedySolver(Cities, bssf, results);

            bssf = greedy.Solve();

            return(results);
        }
Пример #24
0
 private TSPSolution bssfFromIntArray(ArrayList intArray)
 {
     Route = new ArrayList();
     foreach (int i in intArray)
     {
         Route.Add(Cities[i]);
     }
     bssf = new TSPSolution(Route);
     return(bssf);
 }
Пример #25
0
 private void initializeBSSF()
 {
     Route = new ArrayList();
     for (int x = 0; x < Cities.Length; x++)
     {
         Route.Add(Cities[x]);
     }
     Route.Add(Cities[0]);
     bssf = new TSPSolution(Route);
 }
Пример #26
0
 private bool isShorterToSwap(Edge e1, Edge e2, TSPSolution sol, bool firstChoice)
 {
     if (firstChoice)
     {
         return(sol.inp.getDistance(e1.from, e2.from) + sol.inp.getDistance(e1.to, e2.to)
                < e1.weight + e2.weight);
     }
     return(sol.inp.getDistance(e1.from, e2.to) + sol.inp.getDistance(e1.to, e2.from)
            < e1.weight + e2.weight);
 }
Пример #27
0
        public static TSPSolution GetNew(TSPSolution parent1, TSPSolution parent2)
        {
            PermutationStandard ps1 = new PermutationStandard(parent1);
            PermutationStandard ps2 = new PermutationStandard(parent2);
            PermutationStandard tmp = new PermutationStandard(parent2);

            // Keep track of elements, which have not been moved yet
            List <bool> moved = new List <bool>(tmp.size);

            for (int i = 0; i < tmp.size; ++i)
            {
                moved.Add(false);
            }

            // starting point of the cycle - first unmoved element
            moved[0] = true;

            while (moved.Contains(false))
            {
                Cycle cycle = new Cycle();

                int start = moved.IndexOf(false);

                // find the cycle
                while (!cycle.IsComplete())
                {
                    int through = ps2.perm[start];
                    int to      = 0;
                    for (int i = 0; i < ps1.perm.Length; ++i)
                    {
                        if (ps1.perm[i] == through)
                        {
                            to = i;
                        }
                    }

                    cycle.Add(start, to);
                    start = to;
                }

                // elements from ps1 where the cycle goes
                foreach (var startingPoint in cycle.GetStartingPoints())
                {
                    tmp.perm[startingPoint] = ps1.perm[startingPoint];
                    moved[startingPoint]    = true;
                }

                // swap ps1 and ps2
                var swap = ps1;
                ps1 = ps2;
                ps2 = swap;
            }

            return(tmp.convertToTSPSol());
        }
Пример #28
0
        public TSPSolution solve(TSPInput input)
        {
            computeSpanningTree(input);
            TSPSolution result = new TSPSolution(input);

            visited.Clear();
            labelTreePreOrder(0, result);
            result.setSuccessor(lastNodeLabeled, 0);
            return(result);
            //return null;
        }
Пример #29
0
        public TSPSolution convertToTSPSol()
        {
            TSPSolution sol = new TSPSolution(input);

            for (int i = 0; i < size - 1; i++)
            {
                sol.setSuccessor(perm[i], perm[i + 1]);
            }
            sol.setSuccessor(perm[size - 1], perm[0]);
            return(sol);
        }
Пример #30
0
        /// <summary>
        ///  solve the problem.  This is the entry point for the solver when
        ///  the run button is clicked
        /// right now it just picks a simple solution.
        /// </summary>
        public void solveProblem()
        {
            IDictionary <Tuple <City, City>, double> EdgeRatings = RateEdges();

            Route = FindRoute(EdgeRatings);
            bssf  = new TSPSolution(Route);
            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            // do a refresh.
            Program.MainForm.Invalidate();
        }