Ejemplo n.º 1
0
        public City[] Solve(City[] cities)
        {
            MatrixNode root = new MatrixNode(cities);
            double     lowB = root.reduce();
            MatrixNode head = root;

            while (!head.isComplete()) // while there are still unseen branches
            {
                head = head.Expand();
            }
            List <int> temp = head.FinishPath();

            City[] path = new City[cities.Count];
            int    i    = 0;

            for (int item in temp)
            {
                path[i++] = cities[item];
            }
            return(path);
        }
Ejemplo n.º 2
0
 // The creation from a previous node is O(n^2) for the matrix copy
 public MatrixNode(MatrixNode parent)
 {
     n         = parent.n;
     reduction = parent.reduction;
     matrix    = new double[n, n];
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < n; j++)
         {
             matrix[i, j] = parent.matrix[i, j];
         }
     }
     path = new List <int>();
     foreach (int item in parent.path)
     {
         path.Add(item);
     }
     unvisited = new List <int>();
     foreach (int item in parent.unvisited)
     {
         unvisited.Add(item);
     }
 }
Ejemplo n.º 3
0
        // Expands the node by building all of it's children
        // and returning the list
        // This is O(n^3) for the reduction of possibly n children
        // since the reduction costs O(n^2)
        // The sort is probably O(nlogn) although I don't know what algorithm
        // the default c# function uses.  This is dropped in the final big-O.
        public List <MatrixNode> Expand(double bound)
        {
            List <MatrixNode> children = new List <MatrixNode>();
            MatrixNode        child;
            double            temp;

            foreach (int item in unvisited)
            {
                child = new MatrixNode(this);
                temp  = child.Reduce(item);
                if (temp < bound)
                {
                    children.Add(child);
                }
                else
                {
                    pruned++;
                }
                total_count++;
            }
            children.Sort(delegate(MatrixNode x, MatrixNode y)
            {
                if (x.reduction < y.reduction)
                {
                    return(-1);
                }
                else if (x.reduction > y.reduction)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            });
            return(children);
        }
Ejemplo n.º 4
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
        /// Time complexity is O(2^n * n^2) because it has to expand 2^n possible
        /// MatrixNode's which take approximately O(n^2) time to Expand.
        /// I wrote that the expand function is worst case O(n^3) but that is
        /// only if there are n cities left unvisited, which is not going to be
        /// the case most of the time.  So on average it will turn out to be closer
        /// to O(n^2).
        /// The space complexity is O(n^2 * 2^n) for 2^n nodes and n^2 for each node.
        /// </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, max_stack = 0;
            Random    rnd   = new Random();
            Stopwatch timer = new Stopwatch();

            timer.Start();
            // My solution for branch and bound: Iain
            MatrixNode.total_count = 0;
            MatrixNode.pruned      = 0;
            MatrixNode        root = new MatrixNode(Cities);
            double            lowB = root.Reduce(), upperBound = Double.PositiveInfinity;
            List <MatrixNode> problems = new List <MatrixNode>();

            problems.Add(root);
            MatrixNode        head;
            List <MatrixNode> children;

            while (problems.Count > 0) // while there are still unseen branches
            {
                if (timer.ElapsedMilliseconds > time_limit)
                {
                    break;
                }
                if (problems.Count > max_stack)
                {
                    max_stack = problems.Count;
                }

                head = problems[0];
                problems.RemoveAt(0);
                if (head.Reduction < upperBound)
                {
                    if (head.isCompletePath())
                    {
                        List <int> temp = head.FinishPath();
                        if (head.Reduction < upperBound && temp != null && Cities[temp[temp.Count - 1]].costToGetTo(Cities[temp[0]]) != Double.PositiveInfinity)
                        {
                            upperBound = head.Reduction;
                            Route      = new ArrayList();
                            foreach (int item in temp)
                            {
                                Route.Add(Cities[item]);
                            }
                            bssf = new TSPSolution(Route);
                            count++;
                        }
                    }
                    else
                    {
                        children = head.Expand(upperBound);
                        children.AddRange(problems);
                        problems = children;
                    }
                }
                else
                {
                    MatrixNode.pruned++;
                }
            }

            // End of my solution
            timer.Stop();

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

            Console.Write("max_stack: ");
            Console.WriteLine(max_stack);
            Console.Write("total_count: ");
            Console.WriteLine(MatrixNode.total_count);
            Console.Write("pruned: ");
            Console.WriteLine(MatrixNode.pruned);

            return(results);
        }