コード例 #1
0
ファイル: ProblemAndSolver.cs プロジェクト: tnelsonw/TSP
        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);
        }
コード例 #2
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);
        }
コード例 #3
0
 /// <summary>
 ///  return the cost of the best solution so far.
 /// </summary>
 /// <returns></returns>
 public double costOfBssf()
 {
     if (bssf != null)
     {
         return(bssf.costOfRoute());
     }
     else
     {
         return(-1D);
     }
 }
コード例 #4
0
 /// <summary>
 ///  return the cost of the best solution so far.
 /// </summary>
 /// <returns></returns>
 public double costOfBssf()
 {
     if (bssf != null)
     {
         return(bssf.costOfRoute());
     }
     else
     {
         return(Double.PositiveInfinity);
     }
 }
コード例 #5
0
        public void solveProblem()
        {
            timer = new Stopwatch();
            timer.Start();
            counter = 0;
            max     = 0;

            Console.Out.WriteLine();
            initializeSolver();
            stack.Push(new TSPSolution(Cities[0]));

            bool debug = true;

            while (stack.Count != 0 && (timer.Elapsed.TotalSeconds <= 20 || debug))
            {
                counter++;
                if (stack.Count > max)
                {
                    max = stack.Count;
                }
                updateUI();
                TSPSolution parent = stack.Pop();
                if (parent.getBound() >= bssf.costOfRoute())
                {
                    continue;
                }
                //if (parent.isCrossed())
                //    continue;
                List <TSPSolution> children = parent.makeChildren();
                foreach (TSPSolution child in children)
                {
                    if (child.getBound() < bssf.costOfRoute())
                    {
                        if (child.isSolution())
                        {
                            Console.Out.WriteLine("Solution: {0}", child.costOfRoute());
                            bssf = child;
                        }
                        else
                        {
                            stack.Push(child);
                        }
                    }
                    // else discard it (don't explore)
                }
            }

            timer.Stop();
            updateUI();
        }
コード例 #6
0
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// </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[] bBSolveProblem()
        {
            string[]  results = new string[3];
            Stopwatch timer   = new Stopwatch();

            timer.Start();
            //Obtain a BSSF by using a GREEDY approach.
            int startCity = 0;

            bssf = new TSPSolution(GenerateInitialBSSF(ref startCity));
            //Make an initial Matrix
            int cityCount = Cities.Length;

            double[,] initialMatrix = GetInitialMatrix(cityCount);
            //Put start city in list
            ArrayList startingRoute = new ArrayList();

            startingRoute.Add(Cities[startCity]);
            //Make Start node
            int         lowerBound    = 0;
            List <bool> citiesVisited = InitializeCitiesVisitedList(startCity, cityCount);
            NodeState   startNode     = new NodeState(initialMatrix, lowerBound, startingRoute, startCity, citiesVisited);

            startNode.ReduceMatrixAndUpdateLowerBound(cityCount);
            Console.WriteLine("Initial BSSF: " + bssf.costOfRoute().ToString());

            List <NodeState> priorityQueue = new List <NodeState>();

            priorityQueue.Add(null);
            priorityQueue.Add(startNode);

            //Now we are ready to execute the branch and bound algorithm
            int MaxNodeStateAmount     = 1;
            int BSSFupdates            = 0;
            int TotalNodeStates        = 1;
            int TotalNodeStatesPrunned = 0;

            BranchAndBound(ref priorityQueue, ref MaxNodeStateAmount, ref BSSFupdates, ref TotalNodeStates, ref TotalNodeStatesPrunned, startCity, ref timer);

            timer.Stop();

            Console.WriteLine("Max NodeState Amount: " + MaxNodeStateAmount.ToString());
            Console.WriteLine("Total Node States: " + TotalNodeStates.ToString());
            Console.WriteLine("Total Node States Prunned: " + TotalNodeStatesPrunned.ToString() + "\r\n");
            results[COST]  = bssf.costOfRoute().ToString();
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = BSSFupdates.ToString();

            return(results);
        }
コード例 #7
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()
        {
            stopwatch = new Stopwatch();
            stopwatch.Start();
            bssf = generateInitialBSSF();
            State s = initState();

            agenda = new PriorityQueue <double, State>();
            agenda.Add(new KeyValuePair <double, State>(s.boundValue / s.path.Count, s));

            maxSize = 0;
            while (!agenda.IsEmpty && stopwatch.ElapsedMilliseconds < 60000 && bssf.costOfRoute() != s.boundValue)
            {
                if (agenda.Count > maxSize)
                {
                    maxSize = agenda.Count;
                }
                State u = agenda.Dequeue().Value;
                if (u.boundValue < bssf.costOfRoute())
                {
                    if (stopwatch.ElapsedMilliseconds % 5000 == 0)
                    {
                        updateUI();
                    }
                    ArrayList children = generateChildren(u);
                    foreach (State w in children)
                    {
                        if (w.boundValue < bssf.costOfRoute())
                        {
                            if (w.path.Count == Cities.Length)
                            {
                                bssf   = bssfFromIntArray(w.path);
                                myBssf = (int[])w.path.ToArray(System.Type.GetType("System.Int32"));
                                while (updateBssf(myBssf))
                                {
                                    ;
                                }
                                updateUI();
                            }
                            else
                            {
                                agenda.Add(new KeyValuePair <double, State>(w.boundValue / w.path.Count, w));
                            }
                        }
                    }
                }
            }
            updateUI();
        }
コード例 #8
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++;
                }
            }
        }
コード例 #9
0
ファイル: ProblemAndSolver.cs プロジェクト: tlyon3/TSP
        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);
        }
コード例 #10
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);
        }
コード例 #11
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();
        }
コード例 #12
0
 public double getFinalTourLength(City[] cities)
 {
     try
     {
         TSPSolution solution = new TSPSolution(indexToCities(cities, pathSoFar));
         return(solution.costOfRoute());
     }
     catch
     {
         return(Double.PositiveInfinity);
     }
 }
コード例 #13
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 solveProblemBAndB()
        {//O((2^(8n^2 + 9n + 2log(n)))(2^n)) == O((n^2)(2^n)
            BranchAndBound branchAndBoundAlgorithm = new BranchAndBound();

            Route = branchAndBoundAlgorithm.RunTSP(Cities);
            bssf  = new TSPSolution(Route);

            Program.MainForm.tbCostOfTour.Text  = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = branchAndBoundAlgorithm.bAndBTime.TotalSeconds.ToString();
            Program.MainForm.tspOther.Text      = "maxQueueCount: " + branchAndBoundAlgorithm.maxQueueCount + ", bssfUpdatesAmt: " + branchAndBoundAlgorithm.bssfUpdatesAmt + ", totalStatesCreated: " + branchAndBoundAlgorithm.totalStatesCreated + ", prunedAmt: " + branchAndBoundAlgorithm.prunedAmt + ", time: " + branchAndBoundAlgorithm.bAndBTime.TotalSeconds.ToString() + ", cost: " + bssf.costOfRoute();
            // do a refresh.
            Program.MainForm.Invalidate();
        }
コード例 #14
0
        public void solveProblemGreedy()
        {
            Greedy greedyAlgorithm = new Greedy(Cities);

            Route = greedyAlgorithm.RunGreedyTSP();

            bssf = new TSPSolution(Route);
            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text  = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = greedyAlgorithm.time.TotalSeconds.ToString();
            // do a refresh.
            Program.MainForm.Invalidate();
        }
コード例 #15
0
        //TODO - BROKEN/INCORRECT
        //returns number of solutions considered
        private int greedyCalcBSSF()
        {
            defaultGetBSSF();
            //for each starting city:
            //Route.add(startingCityIndex)
            //for cities remaining
            //get the smallest outgoing edge and add that to route
            //remove it from cities remaining
            //if this route's cost is < costBSSF
            //bssf = this route's soln

            int solutionsConsidered = 0;

            for (int i = 0; i < _size; i++)
            {
                Route.Add(i);
                List <int> citiesRemaining = initCityIndices();
                citiesRemaining.Remove(i);

                //build greedy route for starting city Cities[i]
                while (citiesRemaining.Count > 0)
                {
                    //get closest edge
                    int    minCity = citiesRemaining[0];
                    double minCost = Cities[Route.Last()].costToGetTo(Cities[minCity]);
                    for (int c = 1; c < citiesRemaining.Count; c++)
                    {
                        double costToC = Cities[Route.Last()].costToGetTo(Cities[c]);
                        if (costToC < minCost)
                        {
                            minCity = c;
                            minCost = costToC;
                        }
                    }
                    //add closest edge to route and remove from remaining cities
                    Route.Add(minCity);
                    citiesRemaining.Remove(minCity);
                }

                //keep if it's better than BSSF
                TSPSolution candidate = new TSPSolution(Route, Cities);
                if (candidate.costOfRoute() < costOfBssf())
                {
                    bssf = candidate;
                    solutionsConsidered++;
                }
            }

            return(solutionsConsidered);
        }
コード例 #16
0
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// </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[] bBSolveProblem()
        {
            string[]      results = new string[3];
            int           count   = 0;
            Stopwatch     timer   = new Stopwatch();
            PriorityQueue queue   = new PriorityQueue();

            timer.Start();

            greedySolveProblem();

            queue.Insert(new PartialPath(CalculateInitialMatrix(), Cities));

            /* While there are still partial paths on the queue,
             * the best one is popped off and its children are generated.
             * Those that are better than the bssf are added to the queue.
             */
            while (timer.Elapsed.TotalMilliseconds < time_limit && !queue.Empty())
            {
                PartialPath currentNode = queue.DeleteMin();
                if (currentNode.FullPath && currentNode.CompletePath)
                {
                    TSPSolution potentialSolution = new TSPSolution(currentNode.Path);
                    if (potentialSolution.costOfRoute() < costOfBssf())
                    {
                        bssf = potentialSolution;
                        count++;
                    }
                }
                else if (currentNode.LowerBound < costOfBssf())
                {
                    GenerateChildren(currentNode, queue);
                }
            }

            timer.Stop();

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

            Console.WriteLine("Branch & Bound Size: " + Cities.Length + " Random: " + Seed + " Path: " + costOfBssf().ToString() + " Time: " + timer.Elapsed.ToString());


            return(results);
        }
コード例 #17
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()
        {
            int x;

            Route = new ArrayList();
            // this is the trivial solution.
            for (x = 0; x < Cities.Length; x++)
            {
                Route.Add(Cities[Cities.Length - x - 1]);
            }
            // call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
            bssf = new TSPSolution(Route);
            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            // do a refresh.
            Program.MainForm.Invalidate();
        }
コード例 #18
0
        public void random()
        {
            // start our timer
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            Route = new ArrayList();
            // this is the trivial solution.
            for (int x = 0; x < Cities.Length; x++)
            {
                Route.Add(Cities[x]);
            }
            // call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
            bssf = new TSPSolution(Route);

            Program.MainForm.tbCostOfTour.Text  = "" + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = Convert.ToString(timer.Elapsed);
        }
コード例 #19
0
        public string[] fancySolveProblem()
        {
            string[] results = new string[3];
            var      watch   = System.Diagnostics.Stopwatch.StartNew();

            pher = new double[Cities.Length, Cities.Length];

            int iteration = 0;
            int updates   = 0;

            initializePher();

            while (iteration < NUM_ITERATIONS)
            {
                initializeAnts();
                for (int i = 0; i < numAnts; i++)
                {
                    doCircut(ants[i]);
                }
                PherDecay();
                pherUpdate();
                TSPSolution tempSolution = getShortestTour();
                if (bssf == null)
                {
                    updates++;
                    bssf = tempSolution;
                }
                if (tempSolution.costOfRoute() <= bssf.costOfRoute())
                {
                    updates++;
                    bssf = tempSolution;
                }
                iteration++;
            }

            watch.Stop();

            results[COST]  = bssf.costOfRoute().ToString();   // load results into array here, replacing these dummy values
            results[TIME]  = watch.Elapsed.ToString();
            results[COUNT] = updates.ToString();

            return(results);
        }
コード例 #20
0
        // quick_solution, not using initial state cost matrix
        public void quick_solution()
        {
            int x;
            int currIndex = 0;

            Route = new ArrayList();

            //Get the next neighbor greedily based on lowest cost
            //While our Route list size is less than the number of cities (meaning we finish once we get to all the cities)
            while (Route.Count < Cities.Length)
            {
                //Get an arbitrarily large minimum cost
                minCost = double.MaxValue;

                //Loop through all the cities to find the one with the least cost
                for (x = 0; x < Cities.Length; x++)
                {
                    //Make sure we're not trying to check against ourself, because that would definitely be the minimum cost and kind of ruin this whole thing.....
                    if (x != currIndex)
                    {
                        //Make sure the Route list doesn't already contain the city we're trying to add. If it does, it won't be a tour so we don't want to use it again
                        if (!Route.Contains(Cities[x]))
                        {
                            //Get the cost from the current index to the next index. If it's less than what we have, make the 'minCost' equal to our 'currCost' and choose our new minimum index
                            currCost = Cities[currIndex].costToGetTo(Cities[x]);
                            if (currCost < minCost)
                            {
                                minCost  = currCost;
                                minIndex = x;
                            }
                        }
                    }
                }
                //Once we found the city with the lowest cost that is still not in the tour, we have to add that city to our Route
                currIndex = minIndex;
                Route.Add(Cities[currIndex]);
            }

            //Once we have a complete tour, we need to calculate the cost of it and make it our initial BSSF
            bssf = new TSPSolution(Route);
            BSSF = bssf.costOfRoute();
        }
コード例 #21
0
        public void randomSolve()
        {
            timer = new Stopwatch();
            timer.Start();

            Random rand    = new Random();
            double randNum = rand.Next(0, Cities.Length);

            Route = new ArrayList(Cities.Length);
            List <double> randNums = new List <double>();

            randNums.Add(randNum);
            Route.Add(Cities[Convert.ToInt32(randNum)]);
            for (int i = 0; i < Cities.Length - 1; i++)
            {
                int startNode = Convert.ToInt32(randNums[randNums.Count - 1]);
                int size      = randNums.Count;
                while (size == randNums.Count)
                {
                    randNum = rand.Next(0, Cities.Length);
                    if (randNums.Contains(randNum) || Cities[startNode].costToGetTo(Cities[Convert.ToInt32(randNum)]) == double.PositiveInfinity)
                    {
                        randNum = rand.Next(0, Cities.Length);
                    }
                    else
                    {
                        randNums.Add(randNum);
                        Route.Add(Cities[Convert.ToInt32(randNum)]);
                    }
                }
            }

            bssf = new TSPSolution(Route);
            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            TimeSpan ts = timer.Elapsed;

            Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString();
            // do a refresh.
            Program.MainForm.Invalidate();
        }
コード例 #22
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()
        {
            //this function is pretty simple really just an n^2 complexity due to the two for loops and n for space for the path I need.
            Stopwatch timer = new Stopwatch();

            timer.Start();
            HashSet <City> alreadyvisted = new HashSet <City>();

            string[] results     = new string[3];
            City     currentcity = Cities[0];
            City     BestCity    = Cities[1];

            Route.Clear();
            for (int i = 0; i < Cities.Length; i++)
            {
                int number = -1;
                for (int j = 0; j < Cities.Length; j++)
                {
                    if (!Route.Contains(Cities[j]))
                    {
                        if (currentcity.costToGetTo(Cities[j]) < currentcity.costToGetTo(BestCity))
                        {
                            BestCity = Cities[j];
                            number   = j;
                        }
                    }
                }
                currentcity = BestCity;
                Route.Add(currentcity);
                BestCity = new City(100000000, 10000000);
            }

            bssf = new TSPSolution(Route);
            timer.Stop();
            results[COST]  = Convert.ToString(bssf.costOfRoute());   // load results into array here, replacing these dummy values
            results[TIME]  = Convert.ToString(timer.Elapsed.TotalSeconds);
            results[COUNT] = "1";

            return(results);
        }
コード例 #23
0
        private GSCitizen getRandomSolution()
        {
            int i, swap, temp, count = 0;

            string[]    results  = new string[3];
            int[]       perm     = new int[Cities.Length];
            ArrayList   solution = new ArrayList();
            TSPSolution tspSolution;
            List <int>  route = new List <int>();

            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;
                }
                solution.Clear();
                for (i = 0; i < Cities.Length; i++)                                            // Now build the route using the random permutation
                {
                    solution.Add(Cities[perm[i]]);
                    route.Add(perm[i]);
                }
                tspSolution = new TSPSolution(solution);
                count++;
            } while (tspSolution.costOfRoute() == double.PositiveInfinity);                            // until a valid route is found

            return(new GSCitizen(route));
        }
コード例 #24
0
        //Creates an initial path greedily. Time complexity is O(n^2) because it goes through each city (or edge) in the list to find the smallest edge cost.
        //Space complexity is O(n) because it creates a list the size of the number of cities.
        private double createGreedyBssf()
        {
            Route = new ArrayList();
            Route.Add(Cities[0]);
            int currCityIndex = 0;

            while (Route.Count < Cities.Length)
            {
                double minVal   = double.MaxValue;
                int    minIndex = 0;

                for (int i = 0; i < Cities.Length; i++)
                {
                    if (currCityIndex != i)
                    {
                        if (!Route.Contains(Cities[i]))
                        {
                            double currCost = Cities[currCityIndex].costToGetTo(Cities[i]);
                            if (currCost < minVal)
                            {
                                if (Route.Count == Cities.Length - 1 && Cities[i].costToGetTo(Cities[0]) == double.MaxValue)
                                {
                                    continue;
                                }
                                minVal   = currCost;
                                minIndex = i;
                            }
                        }
                    }
                }
                currCityIndex = minIndex;
                Route.Add(Cities[currCityIndex]);
            }
            bssf = new TSPSolution(Route);
            return(bssf.costOfRoute());
        }
コード例 #25
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()
        {
            int x;

            Route = new ArrayList();
            // this is the trivial solution.
            for (x = 0; x < Cities.Length; x++)
            {
                Route.Add(Cities[Cities.Length - x - 1]);
            }

            bssf = new TSPSolution(Route);
            double bssfCost = bssf.costOfRoute();

            BranchAndBound  bBound = new BranchAndBound(Cities, bssfCost);
            PathCalculation result = bBound.CalculatePath();

            City[] path = result.Cities;

            if (path != null)
            {
                bssf     = new TSPSolution(new ArrayList(path));
                bssfCost = bssf.costOfRoute();
            }

            // PLEASE NOTE: If the program times out, then the "TIMED OUT" flag will appear.
            Program.MainForm.tbElapsedTime.Text = (path == null && result.ElapsedTime > (30 * 1000) ? "TIMED OUT: " : "") + result.ElapsedTime / 1000;

            Program.MainForm.tbNumberOfSolutions.Text = (path == null ? 0 : result.NumberOfBSSFUpdates).ToString();

            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text = " " + bssfCost;

            // do a refresh.
            Program.MainForm.Invalidate();
        }
コード例 #26
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()
        {
            //start the time
            Stopwatch timer = new Stopwatch();

            timer.Start();

            //Farthest Insertion Algorithm
            ArrayList bssfRoute = new ArrayList();
            int       m         = 0;
            int       r         = 0;
            double    maxCost   = 0;

            //Find initial vertices to add to subgraph
            for (int k = 0; k < Cities.Length; ++k)
            {
                for (int j = k + 1; j < Cities.Length; ++j)
                {
                    double cost = Cities[k].costToGetTo(Cities[j]);
                    if (maxCost < cost)
                    {
                        m       = k;
                        r       = j;
                        maxCost = cost;
                    }
                }
            }

            bssfRoute.Add(m);
            bssfRoute.Add(r);
            int    first = 0;
            int    last  = 0;
            double minCost;

            //Run until all cities are accounted for
            while (bssfRoute.Count < Cities.Length)
            {
                maxCost = 0;
                m       = 0;
                //Find the vertex that is farthest away from any vertex in the sub-graph
                foreach (int inBssf in bssfRoute)
                {
                    for (int k = 0; k < Cities.Length; ++k)
                    {
                        //Only add if we haven't visited and the cost is larger
                        if (!bssfRoute.Contains(k) && maxCost <
                            Cities[k].costToGetTo(Cities[inBssf]))
                        {
                            m       = k;
                            maxCost = Cities[k].costToGetTo(Cities[inBssf]);
                        }
                    }
                }
                //Find the arc(i,j) that has the cheapest cost to insert the newest vertex
                minCost = double.PositiveInfinity;
                for (int k = 0; k < bssfRoute.Count; ++k)
                {
                    int kIndex = (int)bssfRoute[k];
                    int j      = k + 1;
                    if (j == bssfRoute.Count)
                    {
                        j = 0;
                    }
                    int    jIndex = (int)bssfRoute[j];
                    double cost   = findMinCost(kIndex, jIndex, m);
                    if (cost < minCost)
                    {
                        first   = kIndex;
                        last    = j;
                        minCost = cost;
                    }
                }
                bssfRoute.Insert(last, m);
            }

            //Convert indexes to Route of cities
            int bssfchangecounter = 0;

            Route = new ArrayList();
            foreach (int k in bssfRoute)
            {
                Route.Add(Cities[k]);
            }

            bssf = new TSPSolution(Route);

            double  bssfCost   = bssf.costOfRoute();
            Boolean hasChanged = true;
            Boolean didChange  = false;

            //Check to see if swapping any two vertices produces a better route
            while (hasChanged)
            {
                hasChanged = false;
                didChange  = false;
                ArrayList holder = (ArrayList)Route.Clone();
                for (int i = 0; i < holder.Count; ++i)
                {
                    for (int j = i + 1; j < holder.Count; ++j)
                    {
                        ArrayList temporary = (ArrayList)holder.Clone();
                        City      c         = (City)temporary[i];
                        temporary[i] = temporary[j];
                        temporary[j] = c;
                        TSPSolution newBssf = new TSPSolution(temporary);
                        if (bssfCost > newBssf.costOfRoute())
                        {
                            hasChanged = true;
                            didChange  = true;
                            holder     = (ArrayList)temporary.Clone();
                            bssfCost   = newBssf.costOfRoute();
                        }
                    }
                }
                if (didChange)
                {
                    Route = (ArrayList)holder.Clone();
                    bssf  = new TSPSolution(Route);
                    bssfchangecounter++;
                }
            }
            Console.WriteLine("bssf changed " + bssfchangecounter + " number of times");
            //update the BSSF
            bssf     = new TSPSolution(Route);
            bssfCost = bssf.costOfRoute();

            //Prepare to start Branch and Bound
            //create matrix of distances
            double totalCosts = 0;

            double[,] matrix = new double[Cities.Length, Cities.Length];
            for (int i = 0; i < Cities.Length; i++)
            {
                matrix[i, i] = double.PositiveInfinity;
                for (int j = i + 1; j < Cities.Length; j++)
                {
                    double cost = Cities[i].costToGetTo(Cities[j]);
                    matrix[i, j] = cost;
                    matrix[j, i] = cost;
                    totalCosts  += cost;
                }
            }

            //get children of initial state
            ArrayList childrenIndexes = new ArrayList();

            for (int i = 1; i < Cities.Length; i++)
            {
                childrenIndexes.Add(i);
            }

            //generate initial state
            State s = new State(0, childrenIndexes, (double[, ])matrix.Clone(),
                                new ArrayList(), 0, 0, Cities, 0);

            //bound on initial state
            double bound = s.lowerBound;

            //initial state onto queue
            TSP.PriorityQueue <double, State> q =
                new TSP.PriorityQueue <double, State>();
            q.Enqueue(bound - DEFAULT_SIZE * s.depthIntoSolution, s);

            int maxSize = 0;

            int numberofstatescreated = 1;

            //Branch and Bound: 30 second time limit
            while (!q.IsEmpty && timer.Elapsed.Seconds < 30)
            {
                if (q.Count > maxSize)
                {
                    maxSize = q.Count;
                }

                State u = q.Dequeue().Value;

                //lazy pruning
                if (u.lowerBound < bssfCost)
                {
                    ArrayList childStates = u.generateChildrenStates();
                    numberofstatescreated += childStates.Count;
                    foreach (State w in childStates)
                    {
                        if (timer.Elapsed.Seconds > 30)
                        {
                            break;
                        }
                        //only deal with child state if bound is lower than bssf
                        if (w.lowerBound < bssfCost)
                        {
                            if (w.solutionFound && w.currentCost < bssfCost)
                            {
                                bssfCost  = w.currentCost;
                                bssfRoute = w.pathSoFar;
                            }
                            else
                            {
                                double cBound = w.lowerBound;
                                q.Enqueue(w.lowerBound - DEFAULT_SIZE *
                                          w.depthIntoSolution, w);
                            }
                        }
                    }
                }
            }
            Console.WriteLine("States created " + numberofstatescreated);
            Console.WriteLine("Max number of states stored = " + maxSize);
            Console.WriteLine("Numnber of states pruned = " + (numberofstatescreated - maxSize));

            timer.Stop();

            bssf = new TSPSolution(Route);

            //write out solution
            Program.MainForm.tbCostOfTour.Text = " "
                                                 + bssf.costOfRoute();
            TimeSpan ts          = timer.Elapsed;
            string   elapsedTime = String.Format("{0:00}:{1:00}",
                                                 ts.Minutes, ts.Seconds);

            Program.MainForm.tbElapsedTime.Text = elapsedTime;
            Program.MainForm.Invalidate();

            Console.WriteLine(ToStringSolution());
        }
コード例 #27
0
        public string[] fancySolveProblem()
        {
            string[] results = new string[3];

            Stopwatch timer = new Stopwatch();

            timer.Start();

            ArrayList[] population = new ArrayList[population_size];

            //Get initial population
            for (int i = 0; i < population_size; i++)
            {
                defaultSolveProblem();
                population[i] = bestIndexRoute;
            }

            Console.WriteLine(population);
            RouletteWheel wheel       = new RouletteWheel(population, Cities);
            int           generations = 0;

            while (timer.ElapsedMilliseconds <= time_limit)
            {
                generations++;
                ArrayList[] newPopulation = new ArrayList[population_size];
                for (int i = 0; i < population_size - 10; i++)
                {
                    ArrayList parent   = wheel.getRandomMember();
                    int[]     childArr = crossingOver(convertToArr(parent));
                    ArrayList child    = new ArrayList();
                    child.AddRange(childArr);
                    if (isValidRoute(child))
                    {
                        newPopulation[i] = child;
                    }
                    else
                    {
                        i--;
                    }
                }

                // select a few parents to live on
                for (int i = population_size - 10; i < population_size; i++)
                {
                    ArrayList parent = wheel.getRandomMember();
                    newPopulation[i] = parent;
                }

                population = newPopulation;
            }

            Console.WriteLine("generations: " + generations);

            timer.Stop();

            ArrayList bestSolution = new ArrayList();

            foreach (int index in new RouletteWheel(population, Cities).getBestMember())
            {
                bestSolution.Add(Cities[index]);
            }
            bssf = new TSPSolution(bestSolution);

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

            return(results);
        }
コード例 #28
0
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// </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>
        // This algorithm implements a greedy approach, 10,000 random attempts, and the branch and bound approach with pruning of leaf
        // nodes that have values grater than the current BSSF.
        // O = greedy + 10,000*random + branch and bound
        // = O(n^3 + 10000*n + (2^n)*(n^2) = O((n^2)*(2^n))
        public string[] bBSolveProblem()
        {
            // initialize the variables
            int count = 0;

            string[] results = new string[3];
            int[]    perm    = new int[Cities.Length];
            Route = new ArrayList();
            Stopwatch timer        = new Stopwatch();
            int       maxStates    = 0;
            int       totalStates  = 0;
            int       statesPruned = 0;

            // start the timer
            timer.Start();
            // start BSSF as positive infinity;
            double currSol = Double.PositiveInfinity;
            // see if the BSSF updates with the greedy algorithm
            // Finding greedy solution = O(n^3)
            double greedySol = Convert.ToDouble(greedySolveProblem()[0]);

            if (greedySol < currSol)
            {
                currSol = greedySol;
                count  += 1;
            }
            // attempt updating the BSSF with 10,000 random solutions
            // finding random solution = O(n)
            for (int cycleRand = 0; cycleRand < 10000; cycleRand++)
            {
                double tempSol = Convert.ToInt32(defaultSolveProblem()[0]);
                if (tempSol < currSol)
                {
                    currSol = tempSol;
                    count  += 1;
                }
            }
            // create the List of nodes
            List <DistMatrix> children = new List <DistMatrix>();

            // initialize the first node in the list (root node)
            children.Add(new DistMatrix(Cities));

            // while there are nodes in the node list
            while (children.Count > 0)
            {
                // check if the timer has passed 60 seconds
                timer.Stop();
                long time = timer.ElapsedMilliseconds / 1000;
                if (time >= 60)
                {
                    // if it has passed 60 seconds, break out of the while loop
                    break;
                }
                timer.Start();

                // Find the next node - O(n)
                if (maxStates < children.Count)
                {
                    maxStates = children.Count;
                }
                // collect the variables to find the best child node
                DistMatrix currNode   = children[0];
                double     best       = children[0].b;
                int        numVisited = children[0].visited.Count;
                // for each child node, check if it is optimal
                for (int i = 0; i < children.Count; i++)
                {
                    double value     = children[i].b;
                    int    visited   = children[i].visited.Count;
                    double diffValue = value - best;
                    int    diffVisit = visited - numVisited;
                    // used this little algorithm to try and balance breadth and depth
                    if (value < best * (1 + (diffVisit / .75)))
                    {
                        currNode   = children[i];
                        best       = children[i].b;
                        numVisited = children[i].visited.Count;
                    }
                }
                // remove that node from the list of possiblities
                children.RemoveAt(children.IndexOf(currNode));
                // if the child node has not reached the end
                if (!currNode.finished())
                {
                    // get the list of nodes that haven't been visited
                    List <int> nextChildren;
                    nextChildren = currNode.returnNodesLeft();
                    // create a child object for each of those nodes - O(n^2) happening 2^n times
                    // for the worst case scenario where each leaf must be reached in the tree.
                    // This gives a O((n^2)*(2^n))
                    for (int i = 0; i < nextChildren.Count; i++)
                    {
                        DistMatrix child = new DistMatrix(nextChildren[i], currNode);
                        children.Add(new DistMatrix(nextChildren[i], currNode));
                        totalStates += 1;
                    }
                }
                // if the node is a leaf, check if it's better than the current BSSF
                //O(n) to check each one, with O(n) to check if any need removing after
                // an update on the BSSF.
                else
                {
                    if (currNode.b < currSol)
                    {
                        // if it is better, replace the current BSSF
                        ArrayList   tempRoute = buildRoute(currNode.visited);
                        TSPSolution test      = new TSPSolution(tempRoute);
                        if (test.costOfRoute() < currSol)
                        {
                            Route.Clear();
                            Route   = buildRoute(currNode.visited);
                            bssf    = null;
                            bssf    = new TSPSolution(Route);
                            currSol = costOfBssf();
                            count  += 1;
                        }
                        // filter any children that has a b greater than the current bssf.
                        // remove those children in hopes of speeding up the algorithm
                    }
                }
                for (int i = 0; i < children.Count; i++)
                {
                    if (children[i].b > currSol)
                    {
                        children.RemoveAt(i);
                        statesPruned += 1;
                        i--;
                    }
                }
            }

            // Stop the time and report the results.
            timer.Stop();
            results[COST]  = costOfBssf().ToString(); // load results array
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = count.ToString();
            Console.WriteLine("Max States: {0}, Total States: {1}, Total Pruned: {2}", maxStates, totalStates, statesPruned);
            return(results);
        }
コード例 #29
0
ファイル: ProblemAndSolver.cs プロジェクト: tlyon3/TSP
        /////////////////////////////////////////////////////////////////////////////////////////////
        // 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];
            double     bestCost = double.MaxValue;

            this.bssf = null;
            int       count = 0;
            Stopwatch timer = new Stopwatch();

            timer.Start();
            for (int i = 0; i < Cities.Length; i++)
            {
                if (timer.ElapsedMilliseconds >= time_limit)
                {
                    break;
                }
                ArrayList citiesLeft  = new ArrayList(Cities);
                ArrayList route       = new ArrayList();
                City      currentCity = (City)citiesLeft[i];
                citiesLeft.RemoveAt(i);
                route.Add(currentCity);
                while (citiesLeft.Count > 0)
                {
                    double minDistance = Double.PositiveInfinity;
                    City   nextCity    = null;
                    for (int j = 0; j < citiesLeft.Count; j++)
                    {
                        City   city     = (City)citiesLeft[j];
                        double distance = currentCity.costToGetTo(city);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            nextCity    = city;
                        }
                    }
                    if (nextCity == null)
                    {
                        break;
                    }
                    else
                    {
                        route.Add(nextCity);
                        citiesLeft.Remove(nextCity);
                        currentCity = nextCity;
                    }
                }
                if (route.Count == Cities.Length)
                {
                    TSPSolution tour = new TSPSolution(route);
                    if (tour.costOfRoute() < bestCost)
                    {
                        count++;
                        this.bssf = tour;
                        bestCost  = tour.costOfRoute();
                    }
                }
            }
            timer.Stop();

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

        }
コード例 #30
0
        //**********************************************BBAlgorithm*********************************************************************************
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// </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[] bBSolveProblem()
        {
            string[] results = new string[3];

            // TODO: Add your implementation for a branch and bound solver here.
            //Initalize variables. Takes O(1) space and time
            int numOfCitiesLeft        = Cities.Length;
            int numOfSolutions         = 0;
            int numOfStatesCreated     = 0;
            int numOfStatesNotExpanded = 0;

            //Initalize time variable for stopping the algorithm after the default of 60 seconds. Takes O(1) space and time
            DateTime start = DateTime.Now;
            DateTime end   = start.AddSeconds(time_limit / 1000);

            //Create initial root state and set its priority to its lower bound. Takes O(n^2) space and time as discussed above
            TSPState initialState = createInitialState();

            numOfStatesCreated++;
            initialState.setPriority(calculateKey(numOfCitiesLeft - 1, initialState.getLowerBound()));

            //Create initial BSSF greedily
            double bssfBound = createGreedyBssf();

            PriorityQueue queue = new PriorityQueue(Cities.Length);

            queue.insert(initialState);

            // Branch and Bound until the queue is empty, we have exceeded the time limit, or we found the optimal solution

            /* This loop will have a iterate 2^n times approximately with expanding and pruning for each state, then for each state it
             * does O(n^2) work by reducing the matrix, so over all O((n^2)*(2^n)) time and space as well as it creates a nxn
             * matrix for each state*/
            while (!queue.isEmpty() && DateTime.Now < end && queue.getMinLB() != bssfBound)
            {
                // Grab the next state in the queue
                TSPState currState = queue.deleteMin();

                // check if lower bound is less than the BSSF, else prune it
                if (currState.getLowerBound() < bssfBound)
                {
                    // Branch and create the child states
                    for (int i = 0; i < Cities.Length; i++)
                    {
                        // First check that we haven't exceeded the time limit
                        if (DateTime.Now >= end)
                        {
                            break;
                        }

                        // Make sure we are only checking cities that we haven't checked already
                        if (currState.getPath().Contains(Cities[i]))
                        {
                            continue;
                        }

                        // Create the State
                        double[,] oldCostMatrix = currState.getCostMatrix();
                        double[,] newCostMatrix = new double[Cities.Length, Cities.Length];
                        // Copy the old array in the new one to modify the new without affecting the old
                        for (int k = 0; k < Cities.Length; k++)
                        {
                            for (int l = 0; l < Cities.Length; l++)
                            {
                                newCostMatrix[k, l] = oldCostMatrix[k, l];
                            }
                        }
                        City   lastCityinCurrState = (City)currState.getPath()[currState.getPath().Count - 1];
                        double oldLB = currState.getLowerBound();
                        setUpMatrix(ref newCostMatrix, Array.IndexOf(Cities, lastCityinCurrState), i, ref oldLB);
                        double    newLB   = oldLB + reduceMatrix(ref newCostMatrix);
                        ArrayList oldPath = currState.getPath();
                        ArrayList newPath = new ArrayList();
                        foreach (City c in oldPath)
                        {
                            newPath.Add(c);
                        }
                        newPath.Add(Cities[i]);
                        TSPState childState = new TSPState(ref newPath, ref newLB, ref newCostMatrix);
                        numOfStatesCreated++;

                        // Prune States larger than the BSSF
                        if (childState.getLowerBound() < bssfBound)
                        {
                            City   firstCity      = (City)childState.getPath()[0];
                            City   lastCity       = (City)childState.getPath()[childState.getPath().Count - 1];
                            double costToLoopBack = lastCity.costToGetTo(firstCity);

                            // If we found a solution and it goes back from last city to first city
                            if (childState.getPath().Count == Cities.Length && costToLoopBack != double.MaxValue)
                            {
                                childState.setLowerBound(childState.getLowerBound() + costToLoopBack);
                                bssf      = new TSPSolution(childState.getPath());
                                bssfBound = bssf.costOfRoute();
                                numOfSolutions++;
                                numOfStatesNotExpanded++; // this state is not expanded because it is not put on the queue
                            }
                            else
                            {
                                // Set the priority for the state and add the new state to the queue
                                numOfCitiesLeft = Cities.Length - childState.getPath().Count;
                                childState.setPriority(calculateKey(numOfCitiesLeft, childState.getLowerBound()));
                                queue.insert(childState);
                            }
                        }
                        else
                        {
                            numOfStatesNotExpanded++; // States that are pruned are not expanded
                        }
                    }
                }
                currState = null;
            }
            numOfStatesNotExpanded += queue.getSize(); // if the code terminated before queue is empty, then those states never got expanded
            Console.WriteLine("Number of states generated: " + numOfStatesCreated);
            Console.WriteLine("Number of states not Expanded: " + numOfStatesNotExpanded);
            Console.WriteLine("Max Number of states put in queue: " + queue.getMaxNumOfItems());
            end = DateTime.Now;
            TimeSpan diff    = end - start;
            double   seconds = diff.TotalSeconds;

            results[COST]  = System.Convert.ToString(bssf.costOfRoute());   // load results into array here, replacing these dummy values
            results[TIME]  = System.Convert.ToString(seconds);
            results[COUNT] = System.Convert.ToString(numOfSolutions);

            return(results);
        }