Ejemplo n.º 1
0
            public TSPState Dequeue()
            {
                if (IsEmpty())
                {
                    throw new Exception("Please check that priorityQueue is not empty before dequeing");
                }
                else
                {
                    // Get first item from the sorted dictionary
                    var kv = storage.First();
                    // Get the Queue from the val
                    Queue q = kv.Value;
                    // Then grab the first item from it
                    TSPState deq = (TSPState)q.Dequeue();

                    // Remove if now empty
                    if (q.Count == 0)
                    {
                        storage.Remove(kv.Key);
                    }

                    // Decrement the total size
                    total_size--;

                    // Return the state that's been dequeued
                    return(deq);
                }
            }
Ejemplo n.º 2
0
 public void Enqueue(TSPState item, double prio)
 {
     // Check if key prio exists
     if (!storage.ContainsKey(prio))
     {
         // Add a new queue for key prio
         storage.Add(prio, new Queue());
     }
     // Enqueue state at prio in queue
     storage[prio].Enqueue(item);
     // Inc the total size of the agenda
     total_size++;
 }
Ejemplo n.º 3
0
            public bool Contains(TSPState state)
            {
                // Get the state's priority for lookup
                double prio = state.Bound;

                // If it doesn't exist, absolutely false
                if (!storage.ContainsKey(prio))
                {
                    return(false);
                }
                else
                {
                    // Otherwise run contains on the inner Queue
                    return(storage[prio].Contains(state));
                }
            }
Ejemplo n.º 4
0
        private List <TSPState> generateChildren(TSPState state)
        {
            // Create new state list
            List <TSPState> children = new List <TSPState>();

            // Iterate through the current child's children
            foreach (int child in state.ChildList)
            {
                // Copy values from parent state so we can modify
                List <int> childList = new List <int>(state.ChildList);
                List <int> pathSoFar = new List <int>(state.PathSoFar);
                double     cost      = Cities[state.City].costToGetTo(Cities[child]);
                double[,] matrix = (double[, ])state.Matrix.Clone();

                // Remove child from child list
                childList.Remove(child);
                // Add the parent state city to the path so far
                pathSoFar.Add(state.City);

                // Reduce the matrix
                for (int j = 0; j <= matrix.GetUpperBound(0); j++)
                {
                    matrix[j, state.City] = double.MaxValue;
                }

                // Create a new state
                TSPState newState = new TSPState(state.Bound + state.Matrix[state.City, child], childList, matrix, pathSoFar, state.Cost + cost, child, state.TreeDepth + 1);
                // Update the bound
                newState.Bound += boundingFunction(newState);

                // Check for a soltuion
                if (newState.IsSolution)
                {
                    // Mark state as a solution
                    newState.Cost += Cities[newState.City].costToGetTo(Cities[0]);
                    newState.PathSoFar.Add(newState.City);
                }

                // Add child to childrens state
                children.Add(newState);
            }

            // Returnt the list for later usage
            return(children);
        }
Ejemplo n.º 5
0
        private double boundingFunction(TSPState state)
        {
            // Start with 0 vals and the state's matrix
            double bound   = 0;
            double numRows = 0;

            double[,] matrix = state.Matrix;

            // Reduce the matrix rows
            // Create a child city list
            List <int> childList = new List <int>(state.ChildList);

            // Add the current city to the list, creating all cities
            childList.Add(state.City);

            // Iterate through state's 1D col or row
            for (int i = 0; i < childList.Count; i++)
            {
                // Look for the min cost
                double minCost = double.MaxValue;
                // Interage through the other state's 1D col or row
                for (int j = 0; j < state.ChildList.Count; j++)
                {
                    // Check if cost is less than min...
                    if (matrix[childList[i], state.ChildList[j]] < minCost)
                    {
                        // Update the min cost
                        minCost = matrix[childList[i], state.ChildList[j]];
                    }
                }

                // Then once you find min cost and it's not infinity...
                if (minCost < double.MaxValue)
                {
                    // Reduce the matrix
                    for (int j = 0; j < state.ChildList.Count; j++)
                    {
                        matrix[childList[i], state.ChildList[j]] -= minCost;
                    }
                    // Add the cost to the bound
                    bound += minCost;
                }
                else
                {
                    // Mark as infinity
                    numRows++;
                }
            }

            // Reduce the matrix columns
            for (int i = 0; i < state.ChildList.Count; i++)
            {
                // Look for the min cost
                double minCost = double.MaxValue;
                // Iterate through each column
                for (int j = 0; j < childList.Count; j++)
                {
                    // Update min cost if the cell's value is less
                    if (matrix[childList[j], state.ChildList[i]] < minCost)
                    {
                        minCost = matrix[childList[j], state.ChildList[i]];
                    }
                }
                // Now that we have min cost, see if it is less than infinity
                if (minCost < double.MaxValue)
                {
                    // If so, reduce the matrix column
                    for (int j = 0; j < childList.Count; j++)
                    {
                        matrix[childList[j], state.ChildList[i]] -= minCost;
                    }
                }
                else
                {
                    // Mark as infinity
                    numRows++;
                }
            }

            // If entire matrix is infinity
            if (numRows >= matrix.GetUpperBound(0))
            {
                // Save solution
                state.IsSolution = true;
                state.Cost      += Cities[1].costToGetTo(Cities[state.City]);
            }
            // Return 0 if it is a solution
            if (state.IsSolution)
            {
                return(0);
            }

            // Otherwise return the bound as normal
            return(bound);
        }
Ejemplo n.º 6
0
        private void branchAndBoundEngine()
        {
            // Start the stop watch
            DateTime startTime = DateTime.Now;

            endTime = startTime.AddMilliseconds(_time);

            // Run until the PQ is empty, we find an optimal solution, or time runs out
            while (!PQ.IsEmpty() && DateTime.Now < endTime && BSSF > currBound)
            {
                // Get a state from the PQ
                TSPState state = PQ.Dequeue();
                // Check to see if the state is worth evaluating
                if (state.Bound < BSSF)
                {
                    // Generate the states children and iterate
                    List <TSPState> children = generateChildren(state);
                    foreach (TSPState child in children)
                    {
                        // If the bound is worth investigating...
                        if (child.Bound < bssf.costOfRoute())
                        {
                            // Check for a solution and save
                            if (child.IsSolution && child.Cost < BSSF)
                            {
                                // Save solution
                                BSSF     = child.Cost;
                                BSSFList = child.PathSoFar;
                            }
                            // Otherwise assign the state's bound and Enqueue
                            else
                            {
                                double bound = child.Bound;
                                // Our bound of min cost path to destination + state bound
                                foreach (int childIndex in child.ChildList)
                                {
                                    bound += rowMins[childIndex];
                                }
                                PQ.Enqueue(child, bound);
                            }
                        }
                    }
                }
                GC.Collect();
            }

            //
            // END BRANCH AND BOUND
            //

            // Clear the route
            Route.Clear();
            // Save the BSSF route
            for (int i = 0; i < BSSFList.Count; i++)
            {
                Route.Add(Cities[BSSFList[i]]);
            }

            // Create our soltuion and assign
            bssf = new TSPSolution(Route);
        }
Ejemplo n.º 7
0
        private void solveProblem()
        {
            // Start off with some var power!
            Route = new ArrayList();
            double minCost;
            int    minIndex  = 0;
            int    currIndex = 0;

            // Set our BSSF to 0, so we can create a new better one
            BSSFList = new List <int>();
            BSSFList.Add(0);

            // Begin with our first city
            Route.Add(Cities[currIndex]);

            // Use the nearest neighbor greedy algorithm
            // to find a random (naive) solution
            while (Route.Count < Cities.Length)
            {
                minCost = double.MaxValue;
                for (int j = 0; j < Cities.Length; j++)
                {
                    if (j != currIndex)
                    {
                        if (!Route.Contains(Cities[j]))
                        {
                            double currCost = Cities[currIndex].costToGetTo(Cities[j]);
                            if (currCost < minCost)
                            {
                                minCost  = currCost;
                                minIndex = j;
                            }
                        }
                    }
                }
                // Update the BSSDlist and Route (creating BSSF)
                currIndex = minIndex;
                Route.Add(Cities[currIndex]);
                BSSFList.Add(currIndex);
            }
            // Save solution
            bssf = new TSPSolution(Route);
            BSSF = bssf.costOfRoute();

            //Build matrix for initial state
            double[,] initialMatrix = buildInitialMatrix();

            //Get the minimum cost for the remaining cities; kinda like bound
            rowMins = getRowMins();

            //Generate list of children for initial state
            List <int> initStateChildren = new List <int>();

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

            //Build initial state
            TSPState initialState = new TSPState(0, initStateChildren, initialMatrix, new List <int>(), 0, 0, 0);

            initialState.Bound += boundingFunction(initialState);

            //Set the bound
            currBound = initialState.Bound;

            //Start our PQ and load with init state
            PQ = new PriorityQueue();
            PQ.Enqueue(initialState, initialState.Bound);

            //Run Branch and Bound
            branchAndBoundEngine();
        }