// "Dumb mutation" - just swap some elements private void mutateDumb(TSPSolution initial) { PermutationStandard current = new PermutationStandard(initial); current.swap(rnd.Next(current.size), rnd.Next(current.size)); current.applyToTSPSolution(initial); }
//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++; } } }
// performs local search (switches two points in the solution) and searches for better result private Boolean updateBssf(int[] route) { Boolean result = false; for (int i = 0; i < _size; i++) { for (int j = i + 1; j < _size; j++) { int[] child = new int[route.Length]; Array.Copy(route, child, _size); child[i] = route[j]; //switch two points child[j] = route[i]; // check if child is a new local/global max if (costOfRoute(child) < costOfRoute(myBssf)) { myBssf = child; if (costOfRoute(myBssf) < bssf.costOfRoute()) { bssf = bssfFromIntArray(new ArrayList(myBssf)); } result = true; } } } return(result); }
public TSPSolution solve(TSPInput input) { TSPSolution best = null; for (int r = 0; r < 5; ++r) { Console.WriteLine($@"== RUN:{r} =="); population.Clear(); for (int i = 0; i < PopulationSize; ++i) { population.Add(getRandomSolution(input)); } run(); var tmp = GetBest(); Console.WriteLine($@"Distance: {tmp.totalDistance}"); if (best == null || tmp.totalDistance < best.totalDistance) { best = tmp; } } visualizer.draw(best); return(best); }
public void solveAndShow() { solution = solver.solve(inp); solution.computeDistance(); Length_label.Text = solution.totalDistance.ToString(); vis.draw(solution); }
///////////////////////////////////////////////////////////////////////////////////////////// // These additional solver methods will be implemented as part of the group project. //////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// finds the greedy tour starting from each city and keeps the best (valid) one /// </summary> /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns> public string[] greedySolveProblem() { string[] results = new string[3]; // TODO: Add your implementation for a greedy solver here. Stopwatch timer = new Stopwatch(); timer.Start(); Route = new ArrayList(); greedySolveSub(); // At this point, we have all the cities. // We have a problem though. What if the last city does not go back to the first one??? while (((City)Route[Route.Count - 1]).costToGetTo((City)Route[0]) == Double.PositiveInfinity) { greedySolveSub(); } bssf = new TSPSolution(Route); timer.Stop(); results[COST] = costOfBssf().ToString(); // load results into array here, replacing these dummy values results[TIME] = timer.Elapsed.ToString(); results[COUNT] = "1"; return(results); }
// Reset the problem instance private void resetData() { cities = new City[size]; bssf = null; if (mode == HardMode.Modes.Easy) { for (int i = 0; i < size; i++) { cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); } } else // Medium and hard { for (int i = 0; i < size; i++) { cities[i] = new City(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble() * City.MAX_ELEVATION); } } HardMode mm = new HardMode(this.mode, this.rnd, cities); if (mode == HardMode.Modes.Hard) { int edgesToRemove = (int)(size * FRACTION_OF_PATHS_TO_REMOVE); mm.removePaths(edgesToRemove); } City.setModeManager(mm); }
// "Smart mutation" - try to swap and improve the distance private void mutateSmart(TSPSolution initial) { PermutationStandard current = new PermutationStandard(initial); var start = current.eval(); var best = start; var bestX = 0; var bestY = 0; for (int i = 0; i < current.perm.Length; ++i) { for (int j = 0; j < current.perm.Length; ++j) { current.swap(i, j); var temp = current.eval(); current.swap(j, i); if (temp < best) { best = temp; bestX = i; bestY = j; } } } if (best < start) { current.swap(bestX, bestY); current.applyToTSPSolution(initial); } }
///////////////////////////////////////////////////////////////////////////////////////////// // These additional solver methods will be implemented as part of the group project. //////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// finds the greedy tour starting from each city and keeps the best (valid) one /// </summary> /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns> // O(n^3) - goes through each city for each city, with each city as a root node - n*n*n public string[] greedySolveProblem() { // initialize the vairables int count = 0; string[] results = new string[3]; int[] perm = new int[Cities.Length]; Route = new ArrayList(); double currSol = Double.PositiveInfinity; Stopwatch timer = new Stopwatch(); timer.Start(); // for each city as a starting node, find the best greedy solution // greedy for one node - O(n^2), doing that for each city as a root: // O(n^3) for (int i = 0; i < Cities.Length; i++) { ArrayList newRoute = findGreedyPath(i); TSPSolution greedyRoute = new TSPSolution(newRoute); double temp = costOfBssf(); if (temp < currSol) { currSol = temp; Route = newRoute; bssf = greedyRoute; } } timer.Stop(); results[COST] = costOfBssf().ToString(); // load results array results[TIME] = timer.Elapsed.ToString(); results[COUNT] = count.ToString(); return(results); }
public TSPSolution solve(TSPInput input) { GreedySolver s = new GreedySolver(); best = s.solve(input).computeDistance() + 1; bestSolution = new int[input.nodesCount]; List <int> current = new List <int>(); current.Add(0); List <int> remaining = new List <int>(); for (int i = 1; i < input.nodesCount; i++) { remaining.Add(i); } trySolve(input, current, remaining, 0); TSPSolution result = new TSPSolution(input); for (int i = 0; i < input.nodesCount - 1; i++) { result.setSuccessor(bestSolution[i], bestSolution[i + 1]); } result.setSuccessor(bestSolution[input.nodesCount - 1], 0); return(result); }
public TSPSolution solve(TSPInput input) { Console.WriteLine("Hill climbing started"); current = initialize(input); currentBest = current.convertToTSPSol(); visualizer.draw(currentBest); stop = false; int steps = 0; while (!stop) { steps++; goOneStep(); if (steps % 10 == 0) { currentBest = current.convertToTSPSol(); visualizer.draw(currentBest); Console.WriteLine("Steps: " + steps + " Best distance: " + currentBest.totalDistance); } } Console.WriteLine("Search ended"); currentBest = current.convertToTSPSol(); visualizer.draw(currentBest); Console.WriteLine("Steps: " + steps + " Best distance: " + currentBest.totalDistance); return(currentBest); }
public void draw(TSPSolution sol, bool clear = true) { draw(sol.inp, clear); int j = 0, previous = 0; for (int i = 0; i < sol.inp.nodesCount; i++) { TSPPoint first = sol.inp.getPoint(j), second = sol.inp.getPoint(sol.getSuccessor(j, previous)); Pen pen = Pens.BlueViolet; for (int k = 0; k < sol.inp.nodesCount; k++) { if (Edge.isCrossing(first, second, sol.inp.getPoint(k), sol.inp.getPoint(sol.getSuccessor(k))) && Edge.isCrossing(sol.inp.getPoint(k), sol.inp.getPoint(sol.getSuccessor(k)), first, second)) { pen = Pens.Red; break; } } //TODO vybarvit cervene ty co se krizi - hotovo g.DrawLine(pen, (float)(first.x * xStretch + nodeSize / 2), (float)(first.y * yStretch + nodeSize / 2), (float)(second.x * xStretch + nodeSize / 2), (float)(second.y * yStretch + nodeSize / 2)); int pom = j; j = sol.getSuccessor(j, previous); previous = pom; } screen.Refresh(); }
/// <summary> /// Reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new List <int>(_size); bssf = null; if (_mode == HardMode.Modes.Easy) { for (int i = 0; i < _size; i++) { Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); } } else // Medium and hard { for (int i = 0; i < _size; i++) { Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble() * City.MAX_ELEVATION); } } HardMode mm = new HardMode(this._mode, this.rnd, Cities); if (_mode == HardMode.Modes.Hard) { int edgesToRemove = (int)(_size * FRACTION_OF_PATHS_TO_REMOVE); mm.removePaths(edgesToRemove); } City.setModeManager(mm); cityBrushStyle = new SolidBrush(Color.Black); cityBrushStartStyle = new SolidBrush(Color.Red); routePenStyle = new Pen(Color.Blue, 1); routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; }
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); }
//gets BSSF using random cycle private void defaultGetBSSF() { int i, swap, temp, count = 0; int[] perm = new int[Cities.Length]; Route = new List <int>(); Random rnd = new Random(); do { for (i = 0; i < perm.Length; i++) // create a random permutation template { perm[i] = i; } for (i = 0; i < perm.Length; i++) { swap = i; while (swap == i) { swap = rnd.Next(0, Cities.Length); } temp = perm[i]; perm[i] = perm[swap]; perm[swap] = temp; } Route.Clear(); for (i = 0; i < Cities.Length; i++) // Now build the route using the random permutation { Route.Add(perm[i]); } bssf = new TSPSolution(Route, Cities); count++; } while (costOfBssf() == double.PositiveInfinity); // until a valid route is found }
public string[] fancySolveProblem() { string[] results = new string[3]; Route = new ArrayList(); GeneticSolver geneticSolver = new GeneticSolver(ref Cities); geneticSolver.solve(); ArrayList newRoute = new ArrayList(); byte[] gene = geneticSolver.getBestRoute(); //Console.WriteLine(string.Join(",", gene)); for (int i = 0; i < gene.Length; i++) { newRoute.Add(Cities[gene[i]]); } TSPSolution solution = new TSPSolution(newRoute); bssf = solution; Route = newRoute; //results[COST] = geneticSolver.getCost(); results[COST] = costOfBssf().ToString(); results[TIME] = geneticSolver.getTime(); results[COUNT] = geneticSolver.getCount(); return(results); }
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); }
private TSPSolution solve(TSPInput input, bool hasEdge = false, int startNode = 0, int endNode = 0) { TSPSolution result = null; if (hasEdge) { result = new TSPSolutionPath(input, startNode, endNode); } else { result = new TSPSolution(input); } succ = new List <List <int> >(); edge predefinedEdge = default; edgesUsed = 0; List <edge> edges = new List <edge>(); for (int i = 0; i < input.nodesCount; i++) { succ.Add(new List <int>()); for (int j = 0; j < i; j++) { edge ed = new edge(i, j, input.getDistance(i, j)); if (hasEdge && (startNode == i && endNode == j) || (startNode == j && endNode == i)) { predefinedEdge = ed; } else { edges.Add(ed); } } } if (hasEdge) { addToSolution(predefinedEdge); } edges.Sort((a, b) => (int)(a.distance - b.distance)); int index = -1; while (edgesUsed < input.nodesCount) { index++; edge e = edges[index]; if (succ[e.node1].Count >= 2 || succ[e.node2].Count >= 2) { continue; } if (createsCycle(e) && edgesUsed != input.nodesCount - 1) { continue; } addToSolution(e); } addEdgesToResult(result); return(result); }
public void applyToTSPSolution(TSPSolution sol) { for (int i = 0; i < size - 1; i++) { sol.setSuccessor(perm[i], perm[i + 1]); } sol.setSuccessor(perm[size - 1], perm[0]); }
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); }
public PermutationStandard(TSPSolution sol) : this(sol.inp) { perm[0] = 0; perm[1] = sol.getSuccessor(perm[0]); for (int i = 1; i < size - 1; i++) { perm[i + 1] = sol.getSuccessor(perm[i], perm[i - 1]); } }
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); }
///////////////////////////////////////////////////////////////////////////////////////////// // These additional solver methods will be implemented as part of the group project. //////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// finds the greedy tour starting from each city and keeps the best (valid) one /// </summary> /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns> public string[] greedySolveProblem() { string[] results = new string[3]; GreedySolver greedy = new GreedySolver(Cities, bssf, results); bssf = greedy.Solve(); return(results); }
private TSPSolution bssfFromIntArray(ArrayList intArray) { Route = new ArrayList(); foreach (int i in intArray) { Route.Add(Cities[i]); } bssf = new TSPSolution(Route); return(bssf); }
private void initializeBSSF() { Route = new ArrayList(); for (int x = 0; x < Cities.Length; x++) { Route.Add(Cities[x]); } Route.Add(Cities[0]); bssf = new TSPSolution(Route); }
private bool isShorterToSwap(Edge e1, Edge e2, TSPSolution sol, bool firstChoice) { if (firstChoice) { return(sol.inp.getDistance(e1.from, e2.from) + sol.inp.getDistance(e1.to, e2.to) < e1.weight + e2.weight); } return(sol.inp.getDistance(e1.from, e2.to) + sol.inp.getDistance(e1.to, e2.from) < e1.weight + e2.weight); }
public static TSPSolution GetNew(TSPSolution parent1, TSPSolution parent2) { PermutationStandard ps1 = new PermutationStandard(parent1); PermutationStandard ps2 = new PermutationStandard(parent2); PermutationStandard tmp = new PermutationStandard(parent2); // Keep track of elements, which have not been moved yet List <bool> moved = new List <bool>(tmp.size); for (int i = 0; i < tmp.size; ++i) { moved.Add(false); } // starting point of the cycle - first unmoved element moved[0] = true; while (moved.Contains(false)) { Cycle cycle = new Cycle(); int start = moved.IndexOf(false); // find the cycle while (!cycle.IsComplete()) { int through = ps2.perm[start]; int to = 0; for (int i = 0; i < ps1.perm.Length; ++i) { if (ps1.perm[i] == through) { to = i; } } cycle.Add(start, to); start = to; } // elements from ps1 where the cycle goes foreach (var startingPoint in cycle.GetStartingPoints()) { tmp.perm[startingPoint] = ps1.perm[startingPoint]; moved[startingPoint] = true; } // swap ps1 and ps2 var swap = ps1; ps1 = ps2; ps2 = swap; } return(tmp.convertToTSPSol()); }
public TSPSolution solve(TSPInput input) { computeSpanningTree(input); TSPSolution result = new TSPSolution(input); visited.Clear(); labelTreePreOrder(0, result); result.setSuccessor(lastNodeLabeled, 0); return(result); //return null; }
public TSPSolution convertToTSPSol() { TSPSolution sol = new TSPSolution(input); for (int i = 0; i < size - 1; i++) { sol.setSuccessor(perm[i], perm[i + 1]); } sol.setSuccessor(perm[size - 1], perm[0]); return(sol); }
/// <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(); }