private void greedySolveSub() { // So because adding and removing from hash set are O(1), this feels faster. HashSet <int> citiesLeft = new HashSet <int>(); for (int i = 0; i < Cities.Length; i++) { citiesLeft.Add(i); } City currentCity = Cities[0]; while (citiesLeft.Count > 0) { double lowest = Double.PositiveInfinity; int lowestc = 0; foreach (int c in citiesLeft) { if (currentCity.costToGetTo(Cities[c]) < lowest) { lowest = currentCity.costToGetTo(Cities[c]); lowestc = c; } } Route.Add(Cities[lowestc]); citiesLeft.Remove(lowestc); } }
///////////////////////////////////////////////////////////////////////////////////////////// // 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); }
//where r is the city being added public int findMinArc(ArrayList route, int cityToAdd) { double min = Double.PositiveInfinity; int insertAt = -1; /* * j = [d a b c] * i = [a b c d] */ int j = route.Count - 1; //previous for (int i = 0; i < route.Count; i++) { //i and j are already in the subtour //r is being inserted City cityI = Cities[(int)(route[i])]; City cityJ = Cities[(int)(route[j])]; City cityR = Cities[cityToAdd]; double ir = cityI.costToGetTo(cityR); double rj = cityR.costToGetTo(cityJ); double ij = cityI.costToGetTo(cityJ); if (ir != Double.PositiveInfinity && rj != Double.PositiveInfinity) { double temp = ir + rj - ij; if (temp < min) { min = temp; insertAt = i; } } j = i; } return(insertAt); }
///////////////////////////////////////////////////////////////////////////////////////////// // These additional solver methods will be implemented as part of the group project. //////////////////////////////////////////////////////////////////////////////////////////// //************************************************************************Greedy Algorithm***************************************************************************************************** /// <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> /// Austin's /*public string[] greedySolveProblem() * { * string[] results = new string[3]; * * //Initialize the timer * DateTime start = DateTime.Now; * DateTime end = start.AddSeconds(time_limit / 1000); * Random random = new Random(); * Route = new ArrayList(); * * results[COST] = "not implemented"; // load results into array here, replacing the default values * while (DateTime.Now < end && Route.Count < Cities.Length) * { * // Create variables to track progress * Route.Add(Cities[random.Next(0, Cities.Length)]); * int currCityIndex = 0; * * // While we haven't added |V| edges to our route * while (Route.Count < Cities.Length) * { * double minValue = double.MaxValue; * int minIndex = 0; * * // Loop over all the cities and find the one with min cost to get to * for (int i = 0; i < Cities.Length; i++) * { * // We don't want to be checking ourselves or ones that are already in the route because it won't be a tour * if (currCityIndex != i && !Route.Contains(Cities[i])) * { * double tempValue = Cities[currCityIndex].costToGetTo(Cities[i]); * if (tempValue < minValue) * { * if (Route.Count == Cities.Length - 1 && Cities[i].costToGetTo(Cities[0]) == double.MaxValue) * { * continue; * } * minValue = tempValue; * minIndex = i; * } * } * } * * // Add the min edge to the Route by adding the destination city * currCityIndex = minIndex; * Route.Add(Cities[currCityIndex]); * } * * City lastCity = (City)(Route[Route.Count - 1]); * City firstCity = (City)(Route[0]); * if (lastCity.costToGetTo(firstCity) == double.MaxValue) * { * Route.Clear(); * } * * } * * int numOfSolutions = 0; * // Display the results * bssf = new TSPSolution(Route); * 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; * }*/ // Dallas' public string[] greedySolveProblem() // O(n^2) { string[] results = new string[3]; Stopwatch timer = new Stopwatch(); timer.Start(); List <City> bestRoute = new List <City>(); double bestCost = double.MaxValue; for (int i = 0; i < Cities.Length; i++) { List <City> tempRoute = new List <City>(); tempRoute.Add(Cities[i]); while (tempRoute.Count < Cities.Length) // n { City city = tempRoute[tempRoute.Count - 1]; double min = double.MaxValue; City closest = null; foreach (City neighbor in Cities) // n { double dist = city.costToGetTo(neighbor); if (dist < min && tempRoute.IndexOf(neighbor) < 0) { min = dist; closest = neighbor; } } tempRoute.Add(closest); } bssf = new TSPSolution(new ArrayList(tempRoute)); double tempCost = costOfBssf(); if (tempCost < bestCost) { bestCost = tempCost; bestRoute = tempRoute; } } timer.Stop(); bssf = new TSPSolution(new ArrayList(bestRoute)); results[COST] = costOfBssf().ToString(); // load results into array here, replacing these dummy values results[TIME] = timer.Elapsed.ToString(); results[COUNT] = "1"; return(results); }
// Populate the state matrix with distances between cities public static void initializeState(State state, Problem cityData) { for (int i = 0; i < cityData.size; i++) { City city = cityData.cities[i]; for (int j = 0; j < cityData.size; j++) { if (i == j) { state.matrix[i, j] = SPACE_PLACEHOLDER; } else { state.matrix[i, j] = city.costToGetTo(cityData.cities[j]); } } } reduce(state); }
// used to initialize each city public TSPath(City[] cities) { isFinished = false; parent = null; minDistance = 0; level = 1; numCities = cities.Length; distances = new double[numCities, numCities]; cityPathOrder = new int[numCities]; for (int i = 0; i < numCities; i++) { City refCity = cities[i]; for (int j = 0; j < numCities; j++) { double distance = refCity.costToGetTo(cities[j]); distances[i, j] = distance; } distances[i, i] = double.PositiveInfinity; cityPathOrder[i] = 0; } cityPathOrder[0] = 1; commonInitialization(); }
//**********************************************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); }
///////////////////////////////////////////////////////////////////////////////////////////// // 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. results[COST] = "not implemented"; // load results into array here, replacing these dummy values results[TIME] = "-1"; results[COUNT] = "-1"; int count = 0; TSPSolution solution = null; Stopwatch timer = new Stopwatch(); timer.Start(); //Outer loop for looking through each city for (int i = 0; i < Cities.Length; i++) { Route = new ArrayList(); //This array will contain cities not visited already City[] current_cities = GetCities(); //removes the city that is currently being looked at var temp = new List <City>(current_cities); temp.RemoveAt(i); City[] unchecked_cities = temp.ToArray(); City cur_city = Cities[i]; Route.Add(cur_city); //holds the shortest distance and the index of that city double shortest_distance = -1; int index = 0; do { //Loops through the cities not visited yet to find smallest for (int k = 0; k < unchecked_cities.Length; k++) { if (shortest_distance == -1 && !double.IsPositiveInfinity(cur_city.costToGetTo(unchecked_cities[k]))) { shortest_distance = cur_city.costToGetTo(unchecked_cities[k]); } else if (shortest_distance > cur_city.costToGetTo(unchecked_cities[k])) { shortest_distance = cur_city.costToGetTo(unchecked_cities[k]); index = k; } } //This means no paths were found if (shortest_distance == -1) { //I will do nothing and just go on to the next city in the list break; } /* * Then, once all the cities have been checked, I remove the shortest and check again until there's only one city left */ //Set the current city I'm checking distances from and add it to the route cur_city = unchecked_cities[index]; Route.Add(cur_city); //Remove the current city from the list of cities to check temp = new List <City>(unchecked_cities); temp.RemoveAt(index); unchecked_cities = temp.ToArray(); //reset the shortest distance and index variables shortest_distance = -1; index = 0; //Add the last city at the end if (unchecked_cities.Length == 1) { //If I can't get to the last city if (!double.IsPositiveInfinity(cur_city.costToGetTo(unchecked_cities[0]))) { //add the last city to the route Route.Add(unchecked_cities[0]); count++; solution = new TSPSolution(Route); } } } while (unchecked_cities.Length > 1); //Console.Out.WriteLine("Cost of found route: " + solution.costOfRoute()); //Console.Out.WriteLine("Cost of BSSF: " + costOfBssf()); //Here I check the found route against the current best route if (solution != null) { if (costOfBssf() == -1) { bssf = solution; } else if (costOfBssf() > solution.costOfRoute()) { bssf = solution; } } } timer.Stop(); results[COST] = costOfBssf().ToString(); results[TIME] = timer.Elapsed.ToString(); results[COUNT] = count.ToString(); return(results); }
///////////////////////////////////////////////////////////////////////////////////////////// // 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); }
///////////////////////////////////////////////////////////////////////////////////////////// // 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() { // TODO: Add your implementation for a greedy solver here. int i, count = 0; string[] results = new string[3]; Route = new ArrayList(); Stopwatch timer = new Stopwatch(); timer.Start(); Route.Clear(); for (i = 0; i < Cities.Length; i++) // Now build the route using the random permutation { Route.Add(Cities[i]); } bssf = new TSPSolution(Route); for (i = 0; i < Cities.Length; i++) { City[] queue = GetCities(); //queue of cities not visited Route.Clear(); City Prev = queue[i]; queue[i] = null; Route.Add(Prev); for (int j = 0; j < queue.Length; j++) // until we have reached all cities { double minNeighborCost = double.PositiveInfinity; int minNeighborIndex = -1; for (int k = 0; k < queue.Length; k++) //find the minimum neighbor { if (queue[k] == null) { continue; } if (Prev.costToGetTo(queue[k]) < minNeighborCost) { minNeighborCost = Prev.costToGetTo(queue[k]); minNeighborIndex = k; } } if (minNeighborIndex == -1) { break; } Prev = queue[minNeighborIndex]; queue[minNeighborIndex] = null; Route.Add(Prev); } TSPSolution tsp = new TSPSolution(Route); count++; if (tsp.costOfRoute() < bssf.costOfRoute()) { bssf = tsp; } } timer.Stop(); results[COST] = costOfBssf().ToString(); // load results array results[TIME] = timer.Elapsed.ToString(); results[COUNT] = count.ToString(); return(results); }
/// <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(); ArrayList CitiesLeft = new ArrayList(); for (x = 0; x < Cities.Length; x++) { CitiesLeft.Add(Cities[Cities.Length - x - 1]); } City curCity = (City)CitiesLeft[0]; Route.Add(curCity); CitiesLeft.RemoveAt(0); while (CitiesLeft.Count > 0) { double minDist = 999999; int minInd = 0; for (int i = 0; i < CitiesLeft.Count; i++) { City temp = (City)CitiesLeft[i]; if (curCity.costToGetTo(temp) < minDist) { minDist = curCity.costToGetTo(temp); minInd = i; } } Program.MainForm.tbCostOfTour.Text += "Ind " + minInd; curCity = (City)CitiesLeft[minInd]; Route.Add(curCity); CitiesLeft.RemoveAt(minInd); } // 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(); Program.MainForm.tbElapsedTime.Text = "initial bssf"; // do a refresh. Program.MainForm.Invalidate(); //My solving begins here //generate first adjacency matrix double[,] firstAdj = new double[Cities.Length, Cities.Length]; for (int i = 0; i < Cities.Length; i++) { for (int j = 0; j < Cities.Length; j++) { if (i == j) { firstAdj[i, j] = 999999; } else { firstAdj[i, j] = Cities[i].costToGetTo(Cities[j]); } } } State firstState = new State(firstAdj); Agenda myAgenda = new Agenda(Cities.Length); myAgenda.Add(firstState); //Start timer and go DateTime start = DateTime.Now; DateTime timeUp = DateTime.Now.AddSeconds(60); while ((myAgenda.hasNextState()) && (DateTime.Now <= timeUp)) { State s = myAgenda.nextState; if ((s.routeSF.Count == Cities.Length) && s.costSF < bssf.costOfRoute()) { TSPSolution posS = new TSPSolution(s.routeSF); if (posS.costOfRoute() < bssf.costOfRoute()) { bssf = posS; //Prune the agenda myAgenda.Prune(bssf.costOfRoute()); // update the cost of the tour. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = " " + (DateTime.Now - start); // do a refresh. Program.MainForm.Invalidate(); } } else { ArrayList newStates = s.Expand(Cities); foreach (State state in newStates) { if (state.lowerBound < bssf.costOfRoute()) { myAgenda.Add(state); } } } } if (DateTime.Now < timeUp) { Program.MainForm.tbElapsedTime.Text += " true"; } Program.MainForm.tbCostOfTour.Text += " MC " + myAgenda.MaxCount + " NP " + myAgenda.NumPruned; }
public primState(City s, City e) { startCity = s; endCity = e; cost = s.costToGetTo(e); }
public bool GenerateRoute(ref ArrayList route, ref int startCity) { List <int> remainingCities = new List <int>(); City currentCity = Cities[startCity]; route.Add(currentCity); //Make a queue to help keep track of remaining cities //Remember to not add city 0 int cityCount = Cities.Length; for (int i = 0; i < cityCount; i++) { if (i != startCity) { remainingCities.Add(i); } } //Initialixe helper variables City neighborCity = null; int neighborCityIndex = 0; double neighborCost = Double.PositiveInfinity; double cost = 0; while (remainingCities.Count != 0) { //For each remaining city int size = remainingCities.Count; for (int i = 0; i < size; i++) { int remainingCity = remainingCities[i]; cost = currentCity.costToGetTo(Cities[remainingCity]); if (cost < neighborCost) { neighborCity = Cities[remainingCity]; neighborCost = cost; neighborCityIndex = remainingCity; } } //If the cost from the one city to the next comes out to be infinite then this route failed, and we have to start over. if (cost == Double.PositiveInfinity) { return(false); } //As it ends, we will have the closest neighbor to the current city route.Add(neighborCity); remainingCities.Remove(neighborCityIndex); currentCity = neighborCity; neighborCost = Double.PositiveInfinity; } //Verify that the last city in the route can make it back to the first City lastCity = (City)route[route.Count - 1]; City beginCity = Cities[startCity]; if (lastCity.costToGetTo(beginCity) == Double.PositiveInfinity) { return(false); } //If we make it through, we found a route return(true); }
private void initBSSF() { int x; ArrayList init = new ArrayList(); List <int> fix = new List <int>(); // this is the trivial solution. for (x = 0; x < Cities.Length; x++) { init.Add(Cities[Cities.Length - x - 1]); if (x != 0 && Cities[Cities.Length - x].costToGetTo(Cities[Cities.Length - x - 1]) == double.PositiveInfinity) { fix.Add(x); // fix city at location x. } } Random m = new Random(); for (int i = 0; i < fix.Count; i++) { City fixPrev = init[(fix[i] - 1) % Cities.Length] as City; City fixMid = init[fix[i]] as City; City fixNext = init[(fix[i] + 1) % Cities.Length] as City; City swapPrev; City swapMid; City swapNext; int swapIndex; do { swapIndex = m.Next(1, Cities.Length - 1); swapPrev = init[(swapIndex - 1) % Cities.Length] as City; swapMid = init[swapIndex % Cities.Length] as City; swapNext = init[(swapIndex + 1) % Cities.Length] as City; } while (fixPrev.costToGetTo(swapMid) == double.PositiveInfinity || swapMid.costToGetTo(fixNext) == double.PositiveInfinity || swapPrev.costToGetTo(fixMid) == double.PositiveInfinity || fixMid.costToGetTo(swapNext) == double.PositiveInfinity); // found an agreeable swap, fix. init[fix[i]] = swapMid; init[swapIndex] = fixNext; } // call this the best solution so far. bssf is the route that will be drawn by the Draw method. bssf = new TSPSolution(init); // try 2 other random solutions for (int j = 0; j < 2; j++) { // randomize for (int i = 1; i < Cities.Length; i++) { City fixPrev = init[(i - 1) % Cities.Length] as City; City fixMid = init[i] as City; City fixNext = init[(i + 1) % Cities.Length] as City; City swapPrev; City swapMid; City swapNext; int swapIndex; do { swapIndex = m.Next(1, Cities.Length - 1); swapPrev = init[swapIndex - 1 % Cities.Length] as City; swapMid = init[swapIndex % Cities.Length] as City; swapNext = init[swapIndex + 1 % Cities.Length] as City; } while (fixPrev.costToGetTo(swapMid) == double.PositiveInfinity || swapMid.costToGetTo(fixNext) == double.PositiveInfinity || swapPrev.costToGetTo(fixMid) == double.PositiveInfinity || fixMid.costToGetTo(swapNext) == double.PositiveInfinity); // found an agreeable swap, fix. init[i] = swapMid; init[swapIndex] = fixNext; } TSPSolution tmp = new TSPSolution(init); if (tmp.costOfRoute() < bssf.costOfRoute()) { bssf = tmp; } } }
private City findFarthest(City in_city, ArrayList in_cities) { double temp_dist, max_dist = double.NegativeInfinity; int max_to = -1; for (int i = 0; i < in_cities.Count; i++) { temp_dist = in_city.costToGetTo((City)in_cities[i]); if (temp_dist > max_dist) { max_dist = temp_dist; max_to = i; } } //Debug.WriteLine(max_to + "\t" + max_dist); return (City)in_cities[max_to]; }
private void insertEdge(City furthestPoint, ArrayList in_cities) { int prevCity = -1, postCity = -1; double min_dist = double.PositiveInfinity; double distToEdge; for (int j = 0; j < Route.Count; j++) { if (j < Route.Count - 1) { distToEdge = FindDistanceToSegment(furthestPoint, (City)Route[j], (City)Route[j + 1]); //Debug.WriteLine(j + "\tto\t" + (j + 1) + "\t:" + distToEdge); if (distToEdge < min_dist && furthestPoint.costToGetTo((City)Route[j + 1]) != double.PositiveInfinity && ((City)Route[j]).costToGetTo(furthestPoint) != double.PositiveInfinity) { min_dist = distToEdge; prevCity = j; postCity = j + 1; } } else { distToEdge = FindDistanceToSegment(furthestPoint, (City)Route[j], (City)Route[0]); //Debug.WriteLine(j + "\tto\t0\t:" + distToEdge); if (distToEdge < min_dist && furthestPoint.costToGetTo((City)Route[0]) != double.PositiveInfinity && ((City)Route[j]).costToGetTo(furthestPoint) != double.PositiveInfinity) { min_dist = distToEdge; prevCity = j; postCity = 0; } } } if (prevCity == -1) { Debug.WriteLine("UH OH! no valid edge has been found, no entry point for new city"); } else { Route.Insert(prevCity + 1, furthestPoint); } //in_cities.Remove(furthestPoint); }