public void solveProblemRandom() { //initialize BSSF with a greedy algorithm Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Algorithms algorithms = new Algorithms(); bssf = new TSPSolution(algorithms.random(Cities)); stopwatch.Stop(); Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = " " + stopwatch.Elapsed.TotalSeconds; // do a refresh. Program.MainForm.Invalidate(); }
/// <summary> /// Reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new ArrayList(_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 void solve() { majValue = evaluateSolution(_initialSol); calculs++; bestSol = _initialSol; fact = new float[_pb.varCount]; fact[0] = 1; for (int i = 1; i < _pb.varCount - 1; i++) { fact[i] = fact[i - 1] * i + 1; } fact[_pb.varCount - 1] = fact[_pb.varCount - 2] + 1; TreeNode tr = new TreeNode(generateFirstSolution(), null); TreeNode result = solve(tr, 1); logger.log(calculs + " calculs ont étés réalisés", Message.Level.Information); OnSolutionFound(new SolutionFoundEventArgs(bestSol)); }
//atualiza o valor dos feromônios no problema após cada iteração void UpdatePheromones() { int cityB, cityC; //atualiza o valor dos feromônios de cada aresta //para cada aresta no grafo for (int cityA = 1; cityA <= problem.CityCount; ++cityA) { for (cityB = cityA; cityB <= problem.CityCount; ++cityB) { //evaporar feromônio de acordo com a fórmula do artigo //(1-taxa de evaporação) * atual problem.SetPheromoneBetween(cityA, cityB, (1 - taxaEvaporacao) * problem.GetPheromoneBetween(cityA, cityB)); } //para cada aresta que cada formiga andou foreach (Ant ant in ants) { TSPSolution sol = new TSPSolution(ant.getSolution(), problem); int c1 = sol.TravelPlan[0]; foreach (int c2 in ant.getSolution()) { cityB = c1; cityC = cityB < c2 ? c2 : cityB; cityB = cityB < c2 ? cityB : c2; //atualizar o valor do feromônio de acordo com o artigo //(+ persistencia * 1/f(S), onde f(S) é a distância entre as duas cidades) //problem.SetPheromoneBetween(cityB, cityC, problem.GetPheromoneBetween(cityB, cityC) + (taxaEvaporacao * (1 / problem.GetDistanceBetween(cityB, cityC)))); problem.SetPheromoneBetween(cityB, cityC, problem.GetPheromoneBetween(cityB, cityC) + (taxaEvaporacao * (1 / sol.Fitness))); } } } }
//método principal do ACO public TSPSolution Run() { //verificar condição de término for (int iter = 0; iter < 5000; iter++) { //prepara as estruturas para a decisão de caminho das formigas Ant.PrepareMove(problem); //para cada formiga, movê-las até o destino foreach (Ant ant in ants) { ant.Move(problem); } //avaliar o custo de todas as soluções TSPSolution partial; foreach (Ant ant in ants) { partial = new TSPSolution(ant.getSolution(), problem); if (partial.BetterThan(bestSolutionFound)) { //guardar a melhor solução até o momento bestSolutionFound = (TSPSolution)partial.Clone(); Console.WriteLine("Melhor Solucao Encontrada: " + bestSolutionFound.Fitness); } } //atualizar as trilhas de feromônio UpdatePheromones(); } //retornar solução return(bestSolutionFound); }
private void updateMinCost(TSPSolution s) { if (s.varsIdList.Count > 2) { for (int i = 0; i < s._minCost.Length; i++) { s._minCost[i][s.varsIdList[s.varsIdList.Count - 2]] = 0; } } }
public BnBSolverTSP(Problem pb, TSPSolution initialSolution, DataParser data, Logger logger, int evalMethod) { //Attention à donner une solution avec toutes les variables fixées. _pb = pb; this.logger = logger; this.data = data; computeMinCost(); _initialSol = initialSolution; _initialSol._minCost = this._minCost; this.evalMethod = evalMethod; }
private TSPSolution generateFirstSolution() { TSPSolution sol = (TSPSolution)_initialSol.copy(); sol.reset(); sol.data = data; sol.setVariable(0, data); return(sol); }
private double evaluateSolutionSimplRelax(TSPSolution sol) { double total = getFixedCost(sol); if (sol.freeVars.Count > 1) { BoundSimplex rbTSPSolver = new BoundSimplex(data, logger, sol); total += rbTSPSolver.solve(); } return(total); }
static void RunPSO(TravellingSalesmanMap TSP) { //cria novo PSO PSO pso = new PSO(TSP, 100, 10000, TSP.OptimalTravelDistance); //roda o PSO TSPSolution s = (TSPSolution)pso.Run(); //imprime a solução Console.WriteLine("Optimal Solution: " + TSP.OptimalTravelDistance); Console.WriteLine("Solution Found: " + s.Fitness); Console.ReadKey(); }
private double evaluateSolution(TSPSolution sol) { switch (evalMethod) { case 0: return(evaluateSolutionBasic(sol)); case 1: return(evaluateSolutionSimplRelax(sol)); default: throw new NotImplementedException(); } }
//construtor do ACO //recebe os parâmetros a serem utilizados nas funções de movimento da formiga e de atualização de feromônio public ACO(TravellingSalesmanMap TSP, int numAnts) { //inicializar variáveis problem = new AntProblem(TSP); bestSolutionFound = new TSPSolution(); taxaEvaporacao = 0.9; //cria as formigas e coloca cada uma em um vértice aleatório do grafo System.Random random = new Random(); ants = new List <Ant>(); for (int i = 0; i < numAnts; i++) { //ants.Add(new Ant(random.Next(problem.CityCount) + 1)); ants.Add(new Ant((i + 1) % (TSP.CityCount + 1))); } }
private double getFixedCost(TSPSolution sol) { double total = 0; for (int i = 0; i < sol.varsIdList.Count - 1; i++) { total += data.arcWeight[sol.varsIdList[i], sol.varsIdList[i + 1]]; } if (sol.freeVarCount == 0) { total += data.arcWeight[sol.varsIdList[sol.varsIdList.Count - 1], sol.varsIdList[0]]; } return(total); }
///////////////////////////////////////////////////////////////////////////////////////////// // 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]; Greedy g = new Greedy(); ArrayList route; string time; g.solve(out route, Cities, out time); bssf = new TSPSolution(route); results[COST] = bssf.costOfRoute().ToString(); // load results into array here, replacing these dummy values results[TIME] = time; results[COUNT] = "0"; return(results); }
/// <summary> /// This is the entry point for the default solver /// which just finds a valid random tour /// </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[] defaultSolveProblem() { int i, swap, temp, count = 0; string[] results = new string[3]; int[] perm = new int[Cities.Length]; Route = new ArrayList(); Random rnd = new Random(); Stopwatch timer = new Stopwatch(); timer.Start(); 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]]); } bssf = new TSPSolution(Route); 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); }
private double evaluateSolutionBasic(TSPSolution solution) { double total = getFixedCost(solution); updateMinCost(solution); foreach (int i in solution.freeVars) { total += getMinCost(solution, i); } if (solution.varsIdList.Count >= 1 && solution.freeVars.Count >= 1) { total += getMinCost(solution, solution.varsIdList[solution.varsIdList.Count - 1]); } return(total); }
static void RunACO(TravellingSalesmanMap TSP) { //cria novo ACO ACO aco = new ACO(TSP, TSP.CityCount); //roda o ACO TSPSolution s = aco.Run(); //imprime a solução Console.WriteLine("Optimal Solution: " + TSP.OptimalTravelDistance); Console.WriteLine("Solution Found: " + s.Fitness); Console.Write("\nSteps: "); foreach (int visitedCity in s.TravelPlan) { Console.Write(TSP.GetCityAlias(visitedCity) + " => "); } Console.Write(TSP.GetCityAlias(s.TravelPlan.First())); Console.ReadKey(); }
public string[] fancySolveProblem() { string[] results = new string[3]; /*defaultSolveProblem(); * TSPSolution temp = bssf; * double best = costOfBssf(); * * for (int i = 0; i < 100000; i++) { * defaultSolveProblem(); * if (costOfBssf() < best) { * temp = bssf; * best = costOfBssf(); * } * } * * bssf = temp;*/ ////// My code ////// // Initialize variables //int bssfUpdates = 0; //string timeOut = ""; //double bssfCost = double.MaxValue; // Then do branch and bound //Genetic a = new Genetic(); //a.solve(ref Cities, time_limit, ref timeOut, ref bssfUpdates, ref bssf, ref bssfCost); Gen g = new Gen(); ArrayList route; string time; g.solve(Cities, out route, out time, 50, 100, 0.2, 5, time_limit); bssf = new TSPSolution(route); // Update text results[COST] = bssf.costOfRoute() + ""; // load results into array here, replacing these dummy values results[TIME] = time; results[COUNT] = 100 + ""; return(results); }
private double getMinCost(TSPSolution s, int varId) { double min = 0; for (int i = 0; i < s._minCost[varId].Count; i++) { if (s._minCost[varId][i] != 0) { if (min == 0) { min = s._minCost[varId][i]; } else if (min > s._minCost[varId][i]) { min = s._minCost[varId][i]; } } } return(min); }
/// <summary> /// reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new ArrayList(_size); bssf = null; for (int i = 0; i < _size; i++) Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); cityBrushStyle = new SolidBrush(Color.Black); cityBrushStartStyle = new SolidBrush(Color.Red); routePenStyle = new Pen(Color.LightGray,1); routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; }
/// <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(); }
public void greedySolve() { timer = new Stopwatch(); timer.Start(); Route = new ArrayList(Cities.Length); System.Collections.Generic.HashSet<int> unvisitedIndexes = new System.Collections.Generic.HashSet<int>(); // using a city's index in Cities, we can interate through indexes that have yet to be added for (int index = 0; index < Cities.Length; index++) { unvisitedIndexes.Add(index); } print("\n\nTESTING\n"); City city; for (int i = 0; i < Cities.Length; i++) // keep trying start nodes until a solution is found { if (Route.Count == Cities.Length) { break; // DONE! } else { Route.Clear(); for (int index = 0; index < Cities.Length; index++) { unvisitedIndexes.Add(index); } city = Cities[i]; } for (int n = 0; n < Cities.Length; n++) // add nodes n times { double shortestDistance = Double.PositiveInfinity; int closestIndex = -1; foreach (int check in unvisitedIndexes) //find the closest city to add to route { double distance = city.costToGetTo(Cities[check]); if (distance < shortestDistance) { shortestDistance = distance; closestIndex = check; } } if (closestIndex != -1) { city = Cities[closestIndex]; Route.Add(city); unvisitedIndexes.Remove(closestIndex); } else { break; // try again } } } // 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(); TimeSpan ts = timer.Elapsed; Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString(); // do a refresh. Program.MainForm.Invalidate(); }
public void antSolve() { timer = new Stopwatch(); timer.Start(); //BASF = Best Ant So Far Ant BASF, bestAnt, worstAnt; Edge[,] matrix = generateCostMatrix(); do { BASF = new Ant(ref matrix); } while (!(BASF.IsComplete)); //I found that these were good values. double MIN_IMPROVEMENT = .70; int MAX_REDUNDANT_ITERATIONS = 25; int redundant_iterations = 0; while (redundant_iterations < MAX_REDUNDANT_ITERATIONS) { do { bestAnt = new Ant(ref matrix); } while (!bestAnt.IsComplete); worstAnt = bestAnt; //send out ants! //With only two ants, two sets of edges will be either increased or decayed. Edges occuring in both solutions will be slightly decremented. for (int j = 1; j < 2; j++) { Ant ant = new Ant(ref matrix); if (ant.IsComplete) { if (ant.TotalCost < bestAnt.TotalCost) bestAnt = ant; else if (ant.TotalCost > worstAnt.TotalCost) worstAnt = ant; } } bestAnt.updatePheromones(false); worstAnt.updatePheromones(true); //improvement represents the ratio of this ant's journey to the current best. double improvement = bestAnt.TotalCost / BASF.TotalCost; if (improvement < 1) BASF = bestAnt; if (improvement > MIN_IMPROVEMENT) redundant_iterations++; } // call this the best solution so far. bssf is the route that will be drawn by the Draw method. Route = new ArrayList(Cities.Length); for (int i = 0; i < BASF.Route.Count; i++) Route.Add(Cities[BASF.Route[i]]); bssf = new TSPSolution(Route); // update the cost of the tour. TimeSpan ts = timer.Elapsed; // do a refresh. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString(); Program.MainForm.Invalidate(); }
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); }
public SolutionFoundEventArgs(TSPSolution res) { result = res; }
/// <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() { State state = new State(Cities); bssf = new TSPSolution(State.BSSF.Route); Console.WriteLine(bssf.costOfRoute()); Console.WriteLine(State.BSSF.Bound); Debug.Assert(bssf.costOfRoute() == State.BSSF.Bound); Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = State.Watch.Elapsed.ToString(); Program.MainForm.Invalidate(); // Trivial solution, what appeared here originally // Uncomment to see how it works /*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();*/ }
// 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; }
// generates an initial bssf by using local search algorithm 4 times and picking the best result private TSPSolution generateInitialBSSF() { // initialize starting solutions myBssf = myInitializeBSSF(); bssf = bssfFromIntArray(new ArrayList(myBssf)); int count = 0; while (count < 4) { count++; myBssf = myInitializeBSSF(); while (updateBssf(myBssf)) // if local Bssf was updated, re-run updateUI(); //Console.Out.WriteLine("Cost: {0}", costOfRoute(myBssf)); } updateUI(); return bssf; }
private TSPSolution bssfFromIntArray(ArrayList intArray) { Route = new ArrayList(); foreach (int i in intArray) Route.Add(Cities[i]); bssf = new TSPSolution(Route); return bssf; }
/// <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(); }
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); }
/// <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(); }
public TSPSolution findBestCandidate(TSPSolution currentSolution, TabuList tabuList) { TSPSolution bestCandidate = null; TSPSolution candidate = new TSPSolution(new ArrayList(currentSolution.Route)); for (int swapA = 0; swapA < Cities.Length - 1; swapA++) { // only consider swapping forward so we don't double the space for (int swapB = swapA + 1; swapB < Cities.Length; swapB++) { //candidate.Route.Clear(); // perform swap City tmp = (City)candidate.Route[swapA]; candidate.Route[swapA] = candidate.Route[swapB]; candidate.Route[swapB] = tmp; // normalize to make TabuList.Contains() easier if (swapA == 0) { ArrayList normalRoute = new ArrayList(); for (int i = swapB; i < Cities.Length; i++) normalRoute.Add(candidate.Route[i]); for (int i = 0; i < swapB; i++) normalRoute.Add(candidate.Route[i]); candidate.Route = normalRoute; } // recalc cost candidate.cost = candidate.costOfRoute(); // get best candidate if (!tabuList.contains(candidate)) { if (bestCandidate == null || candidate.cost < bestCandidate.cost){ bestCandidate = new TSPSolution(new ArrayList(candidate.Route)); } } // revert swap for next candidate if (swapA == 0) { // it's simpler to recopy candidate.Route = new ArrayList(currentSolution.Route); } else { candidate.Route[swapB] = candidate.Route[swapA]; candidate.Route[swapA] = tmp; } } } if (bestCandidate == null) { tabuList.setCapacity(tabuList.capacity * 2); return tabuList.getLast(); // or whatever this function ends up being called } return bestCandidate; }
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(); }
/// <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() { //initialize BSSF with a greedy algorithm Algorithms algorithms = new Algorithms(); bssf = new TSPSolution(algorithms.greedy(Cities)); Node.bssf = bssf.costOfRoute(); int maxQsize = 0; int totalStates = 0; int timeSeconds = Convert.ToInt32(Program.MainForm.textBoxTime.Text); //set up priority queue and stopwatch PriorityQueue PQ = new PriorityQueue(); PQ.insert(new Node(Cities)); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while(PQ.getSize() > 0 && stopwatch.Elapsed.TotalSeconds < timeSeconds) { //pop node off of queue and check lower bound against bssf Node node = PQ.deleteMin(); if(node.lowerBound > Node.bssf) { Node.prunes++; break; } Node include = null; Node exclude = null; double maxDif = Double.NegativeInfinity; //search for include/exclude edge that gives max difference in lower bound double[,] matrix = node.rCmatrix; for (int i = 0; i < node.matrixLength; i++) { if (node.exited[i] == -1) { for (int j = 0; j < node.matrixLength; j++) { if (matrix[i, j] == 0) { Node tempInclude = new Node(node, true, i, j); Node tempExclude = new Node(node, false, i, j); double potentialMaxDif = tempExclude.lowerBound - tempInclude.lowerBound; if (potentialMaxDif > maxDif) { maxDif = potentialMaxDif; include = tempInclude; exclude = tempExclude; } } } } } //check if found a bssf if(include.totalEdges == include.matrixLength && include.lowerBound < Node.bssf) { Node.bssfUpdates++; Node.bssf = include.lowerBound; Node.bssfNode = include; } else if(include.lowerBound < Node.bssf)//add include node to queue { PQ.insert(include); int currentQSize = PQ.getSize(); if(currentQSize > maxQsize) { maxQsize = currentQSize; } } else//prune include node { Node.prunes++; } if(exclude.lowerBound < Node.bssf)//add exclude node to queue { PQ.insert(exclude); int currentQSize = PQ.getSize(); if (currentQSize > maxQsize) { maxQsize = currentQSize; } } else//prune exclude node { Node.prunes++; } totalStates += 2;//2 states are created per while-loop iteration } stopwatch.Stop(); //if stopwatch is < 30, then we have found an optimal solution bool isOptimal = false; if(stopwatch.Elapsed.TotalSeconds < timeSeconds) { isOptimal = true; } //prune number of items left in the queue Node.prunes += PQ.getSize(); //if a bssf has been found better than the greedy solution if(Node.bssfNode != null) { Node solution = Node.bssfNode; ArrayList route = solution.getRoute(Cities); // call this the best solution so far. bssf is the route that will be drawn by the Draw method. bssf = new TSPSolution(route); } //display stats if (isOptimal) { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + "*"; } else { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); } Program.MainForm.tbElapsedTime.Text = " " + stopwatch.Elapsed.TotalSeconds; // do a refresh. Program.MainForm.Invalidate(); //print more stats Console.WriteLine(); Console.WriteLine("Max # of stored states: " + maxQsize); Console.WriteLine("# of BSSF updates: " + Node.bssfUpdates); Console.WriteLine("Total # of states created: " + totalStates); Console.WriteLine("Total # of states pruned: " + Node.prunes); Node.resetStaticVariables(); }
public List<TSPSolution> makeChildren() { List<TSPSolution> result = new List<TSPSolution>(); if (Route.Count == _size) { TSPSolution newSolution = new TSPSolution(new ArrayList(Route.ToArray())); newSolution.Route.Add(Cities[0]); result.Add(newSolution); return result; } for (int i = 0; i < _size; i++) { if (Route.Contains(Cities[i])) continue; TSPSolution newSolution = new TSPSolution(new ArrayList(Route.ToArray())); newSolution.Route.Add(Cities[i]); result.Add(newSolution); } return result; }
/// <summary> /// This is the entry point for the default solver /// which just finds a valid random tour /// </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[] defaultSolveProblem() { int i, swap, temp, count=0; string[] results = new string[3]; int[] perm = new int[Cities.Length]; Route = new ArrayList(); Random rnd = new Random(); Stopwatch timer = new Stopwatch(); timer.Start(); 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]]); } bssf = new TSPSolution(Route); 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; }
private TreeNode solve(TreeNode currentNode, int step) { if (currentNode.sol.isFinalSolution()) { if (majValue > currentNode.sol.eval) { majValue = currentNode.sol.eval; bestSol = (TSPSolution)currentNode.sol; logger.log("Meilleur solution trouvée de coût:" + ((int)Math.Round(currentNode.sol.eval)).ToString(), Message.Level.Warning); updateEtape(true, step); displaySolution(bestSol); } else { currentNode.isLocked = true; updateEtape(true, step); } return(currentNode); } else { List <TreeNode> nextSol = new List <TreeNode>(); for (int i = 0; i < _pb.varCount; i++) { if (!currentNode.sol.isFixed(i)) { TSPSolution nSol = (TSPSolution)currentNode.sol.copy(); nSol.setVariable(i, data); nSol.eval = evaluateSolution(nSol); calculs++; //> ou < selon minimisation ou maximisation if (nSol.eval <= majValue) { nextSol.Add(new TreeNode(nSol, null)); } else { //logger.log("Elimination", Message.Level.Error); updateEtape(false, step + 1); } } } if (nextSol.Count != 0) { nextSol.Sort((x, y) => x.sol.eval.CompareTo(y.sol.eval)); for (int i = 0; i < nextSol.Count; i++) { if (nextSol[i].sol.eval <= majValue) { //logger.log("Resolution de l'etape " + (step + 1).ToString() + ", variable n°" + i.ToString() + "/" + nextSol.Count.ToString(), Message.Level.Information); //logger.log("Borne courante:" + ((int)Math.Round(nextSol[i].sol.eval)).ToString() + " / Cout courant:" + ((int)Math.Round(majValue)).ToString(), Message.Level.Information); nextSol[i] = solve(nextSol[i], step + 1); } else { //logger.log("Elimination à l'etape " + (step + 1).ToString() + ", variable n°" + i.ToString() + "/" + nextSol.Count.ToString(), Message.Level.Error); nextSol[i].isLocked = true; updateEtape(false, step + 1); } } currentNode.childs = nextSol; } else { currentNode.isLocked = true; } updateEtape(true, step); int locked = 0; foreach (TreeNode node in nextSol) { if (node.isLocked) { node.Dispose(); locked++; } } if (locked == nextSol.Count) { currentNode.isLocked = true; nextSol = null; } return(currentNode); } }
public void finalizeRoute(ref List<int> subTour, ref int updates) { double tourCost = 0; ArrayList route = new ArrayList(); for (int i = 0; i < subTour.Count; i++) { if (i == subTour.Count -1) { tourCost += Cities[subTour[i]].costToGetTo(Cities[subTour[0]]); route.Add(Cities[subTour[i]]); } else { tourCost += Cities[subTour[i]].costToGetTo(Cities[subTour[i + 1]]); route.Add(Cities[subTour[i]]); } } if (subTour.Count == Cities.Length && tourCost < bssf.costOfRoute() ) { bssf = new TSPSolution(route); updates++; } else return; }
public void branchAndBoundSolve() { initialState = new State(new Double[Cities.Length, Cities.Length]); timer = new Stopwatch(); timer.Start(); for (int i = 0; i < Cities.Length; i++) //O(n^2), initialize initialStates map { for (int x = 0; x < Cities.Length; x++) { initialState.setPoint(i, x, Cities[i].costToGetTo(Cities[x])); if (initialState.getPoint(i, x) == 0) initialState.setPoint(i, x, double.PositiveInfinity); } } initialState.initializeEdges(); //initializeEdges initializes the state's dictionary //with key 0 to n (# of cities), value -> -1 reduceMatrix(initialState); //reduce the matrix to find lower bound queue = new IntervalHeap<State>(); //this is a global queue BSSF = greedy(); //find initial best solution so far, O(n^4) Console.WriteLine("BSSF: " + BSSF); findGreatestDiff(initialState); //exclude minus include, O(n^3) TimeSpan ts = timer.Elapsed; bool terminatedEarly = false; //boolean to keep track if we stopped after 30 seconds int maxStates = 0; //keeps track of the maximum amount of states in the queue at one point int totalSeconds = 0; while (queue.Count != 0) //O(2^n * n^3), because each time you expand a node, it expands it 2 times, exponentially { //where n is the number of cities if (queue.Count > maxStates) //if maxStates needs to be updated, update it maxStates = queue.Count; ts = timer.Elapsed; State min = queue.DeleteMin(); if (totalSeconds < ts.Seconds) { totalSeconds = ts.Seconds; Console.WriteLine("seconds: " + totalSeconds); } if (min.getLB() < BSSF) //if the min popped off the queue has a lowerbound less than findGreatestDiff(min);//the BSSF, expand it, otherwise, prune it. -> O(n^3) else {//all of the lowerbounds are worse than the BSSF, break! break; } } if (!terminatedEarly)//if it solved the problem in less than 30 seconds { int city = 0; for (int i = 0; i < bestState.getEdges().Count; i++) //O(n) { if (i == 0) //outputting a map into the Route list { Route.Add(Cities[i]); city = bestState.getEdge(i); } else { Route.Add(Cities[city]); city = bestState.getEdge(city); } } bssf = new TSPSolution(Route); // update the cost of the tour. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString(); // do a refresh. Program.MainForm.Invalidate(); } }
public void initialBSSF(int X) { Route = new ArrayList(); Random rnd = new Random(); for (int i = 0; i < X; i++) { while (Route.Count < Cities.Length) { int x = rnd.Next(0, Cities.Length); checkForDuplicates(ref Route, Cities[x]); } if (i == 0 || new TSPSolution(Route).costOfRoute() < bssf.costOfRoute()) { bssf = new TSPSolution(Route); } Route.Clear(); } }
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(); }
public void pickGreedySolution() { // first node will be the starting & ending point int x = 0; Route = new ArrayList(); Stopwatch timer = new Stopwatch(); timer.Start(); Route.Add(Cities[x]); // this is the greedy solution. we start at 0 and don't return to 0 until we're all done. int[] visitedCities = new int[Cities.Length]; for (int i = 0; i < visitedCities.Length; i++) visitedCities[i] = 0; do { // go through every city not visited and make note of the shortest one Double shortestDistance = Double.PositiveInfinity; int closestCity = -1; for (int i = 1; i < Cities.Length; i++) { // if the city is already visited or isn't connected (distance == Double.PositiveInfinity), skip it if (visitedCities[i] == 1) continue; // if it's smaller than the best distance so far, make note of it. Double distance = Cities[x].costToGetTo(Cities[i]); if (distance < shortestDistance) { shortestDistance = distance; closestCity = i; } } // if by this point the closest city is still -1, it's visited every city and needs to return to the beginning. if (closestCity == -1) x = 0; else { x = closestCity; visitedCities[x] = 1; Route.Add(Cities[closestCity]); } } while (x != 0); timer.Stop(); // call this the Best Solution So Far. bssf is the route that will be drawn by the Draw method. bssf = new TSPSolution(Route); if (UpdateForm) { // update the cost of the tour. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); // update count of tours found. (Greedy stops when it finds the first one) if (bssf.costOfRoute() > 0) Program.MainForm.toolStripTextBox1.Text = "" + 1; else Program.MainForm.toolStripTextBox1.Text = "" + 0; //update time taken to find the tour. Program.MainForm.tbElapsedTime.Text = "" + (timer.Elapsed.TotalMilliseconds / 1000); // do a refresh. Program.MainForm.Invalidate(); } }
/// <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 void pickRandomSolution() { // first node will be the starting & ending point int x = 0; Route = new ArrayList(); Route.Add(Cities[x]); // this is the random solution. we start at 0, pick random cities out of the hat, and don't return to 0 until we're all done. List<int> hat = new List<int>(); for (int i = 1; i < Cities.Length; i++) hat.Add(i); x = -1; Random r = new Random(); while (x != 0) { // pick a random city that hasn't been visited if (hat.Count == 0) x = 0; else { x = hat[r.Next(0, hat.Count)]; hat.Remove(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); if (UpdateForm) { // update the cost of the tour. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); // do a refresh. Program.MainForm.Invalidate(); } }
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(); }
public void PointClusterSolution() { Stopwatch sw = new Stopwatch(); sw.Start(); CostMatrix costMatrix; List<CityNodeData> cityData; List<CityCluster> cityClusters; Dictionary<int, CityCluster> cityToClusterItsIn; List<int> interNodeEdges; Dictionary<int, int> sizeClusterToNumOfThatSize; DoClusters(out costMatrix, out cityData, out cityClusters, out cityToClusterItsIn, out sizeClusterToNumOfThatSize); double solutionLength = SolveExternalClusters(costMatrix, cityData, cityClusters, cityToClusterItsIn, out interNodeEdges); TSPSolution sol = Solve(costMatrix, cityData, cityClusters, cityToClusterItsIn, interNodeEdges); bssf = sol; sw.Stop(); foreach (int size in sizeClusterToNumOfThatSize.Keys) { Console.WriteLine("There are {0} clusters of size {1}", sizeClusterToNumOfThatSize[size], size); } Console.WriteLine("Solution length is {0}", solutionLength); if (UpdateForm) { Program.MainForm.tbCostOfTour.Text = bssf.costOfRoute() + ""; Program.MainForm.tbElapsedTime.Text = sw.Elapsed.TotalSeconds + ""; Program.MainForm.Invalidate(); } }
/// <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(); }
public void solveProblem() { /** Initialize */ Stopwatch timer = new Stopwatch(); double lowerBound = 0; List<Tuple<double[][], double, partialRoute>> priorityQueue = new List<Tuple<double[][], double, partialRoute>>(); double[][] costMatrix = new double[Cities.Length][]; for (int i = 0; i < Cities.Length; i++) { costMatrix[i] = new double[Cities.Length]; for (int k = 0; k < Cities.Length; k++) { if (i == k) { costMatrix[i][k] = Double.PositiveInfinity; } else { double cost = Cities[i].costToGetTo(Cities[k]); costMatrix[i][k] = cost; } } } /** Reduce Cost Matrix */ timer.Start(); reduceCostMatrix(ref costMatrix, ref lowerBound); addPriority(ref priorityQueue, new Tuple<double[][], double, partialRoute>(costMatrix, lowerBound, new partialRoute(Cities))); /** Initial BSSF */ Route = new ArrayList(); Random rnd = new Random(); for (int i = 0; i < 100; i++) { while (Route.Count < Cities.Length) { int x = rnd.Next(0, Cities.Length); addCity(ref Route, Cities[x]); } //temp = new TSPSolution(Route); if (i == 0 || new TSPSolution(Route).costOfRoute() < bssf.costOfRoute()) { bssf = new TSPSolution(Route); } Route.Clear(); } /** Solve Problem */ int updates = 0; int pruned = 0; int states = 0; int stored = 0; Tuple<double, ArrayList> answer = new Tuple<double, ArrayList>(bssf.costOfRoute(), Route); List<Tuple<double[][], double, partialRoute, double[][], double, partialRoute, double>> tempQueue = new List<Tuple<double[][], double, partialRoute, double[][], double, partialRoute, double>>(); while (true) // until bool is true or timer is >= 30 { if (priorityQueue.Count == 0) { timer.Stop(); if (UpdateForm) { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + "*"; Program.MainForm.toolStripTextBox1.Text = " " + updates; Program.MainForm.tbElapsedTime.Text = " " + timer.Elapsed.TotalSeconds; Program.MainForm.Invalidate(); } return; } if (priorityQueue.Count > stored) { stored = priorityQueue.Count; } partialRoute relativePath = copyArrayList(priorityQueue[0].Item3); double cost = priorityQueue[0].Item2; double[][] matrix = copyArray(priorityQueue[0].Item1); priorityQueue.RemoveAt(0); if (bssf.costOfRoute() < cost) { timer.Stop(); pruned += priorityQueue.Count + 1; if (UpdateForm) { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + "*"; Program.MainForm.Invalidate(); Program.MainForm.toolStripTextBox1.Text = " " + updates; Program.MainForm.tbElapsedTime.Text = " " + timer.Elapsed.TotalSeconds; } return; } if (relativePath.size == Cities.Length) { if (answer.Item1 > cost) { updates++; answer = new Tuple<double, ArrayList>(cost, relativePath.toArrayList()); bssf = new TSPSolution(answer.Item2); if (answer.Item1 <= priorityQueue[0].Item2) { timer.Stop(); pruned += priorityQueue.Count; if (UpdateForm) { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + "*"; Program.MainForm.Invalidate(); Program.MainForm.toolStripTextBox1.Text = " " + updates; Program.MainForm.tbElapsedTime.Text = " " + timer.Elapsed.TotalSeconds; } return; } } } if (timer.Elapsed.TotalSeconds >= ProblemAndSolver.TimeOut) { timer.Stop(); if (UpdateForm) { Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.Invalidate(); Program.MainForm.toolStripTextBox1.Text = " " + updates; Program.MainForm.tbElapsedTime.Text = " " + 30; } return; } for (int i = 0; i < Cities.Length; i++) { for (int j = 0; j < Cities.Length; j++) { if (matrix[i][j] == 0) { double[][] matrixOne = copyArray(matrix); double costOne = cost; partialRoute routeInc = copyArrayList(relativePath); include(ref matrixOne, ref costOne, ref routeInc, i, j); double[][] matrixTwo = copyArray(matrix); double costTwo = cost; partialRoute routeExc = copyArrayList(relativePath); exclude(ref matrixTwo, ref costTwo, i, j); double diff = costTwo - costOne - cost; addTemp(ref tempQueue, new Tuple<double[][], double, partialRoute, double[][], double, partialRoute, double>(matrixOne, costOne, routeInc, matrixTwo, costTwo, routeExc, diff)); } } } if (tempQueue.Count != 0) { if (tempQueue[0].Item2 < bssf.costOfRoute()) { states++; Tuple<double[][], double, partialRoute> Include = new Tuple<double[][], double, partialRoute>(tempQueue[0].Item1, tempQueue[0].Item2, tempQueue[0].Item3); addPriority(ref priorityQueue, Include); } else { pruned++; } if (tempQueue[0].Item5 < bssf.costOfRoute()) { states++; Tuple<double[][], double, partialRoute> Exculde = new Tuple<double[][], double, partialRoute>(tempQueue[0].Item4, tempQueue[0].Item5, tempQueue[0].Item6); addPriority(ref priorityQueue, Exculde); } else { pruned++; } tempQueue.Clear(); } } }
/// <summary> /// Reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new ArrayList(_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 void displaySolution(TSPSolution s) { OnPartialSolutionFound(new SolutionFoundEventArgs(s)); }
/// <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]; double bssf = Double.PositiveInfinity; // TODO: Add your implementation for a branch and bound solver here. //List<int> citiesLeft = new List<int>(); //double[][] matrix = new double[Cities.Length][]; //for (int i = 0; i < Cities.Length; i++) //{ // citiesLeft.Add(i); // matrix[i] = new double[Cities.Length]; // for (int j = 0; j < Cities.Length; j++) // { // if (i != j) // matrix[i][j] = Cities[i].costToGetTo(Cities[j]); // else // matrix[i][j] = Double.PositiveInfinity; // } //} //citiesLeft.RemoveAt(0); double[][] matrix = new double[4][]; matrix[0] = new double[4] { Double.PositiveInfinity, 7, 3, 12 }; matrix[1] = new double[4] { 3, Double.PositiveInfinity, 6, 14 }; matrix[2] = new double[4] { 5, 8, Double.PositiveInfinity, 6 }; matrix[3] = new double[4] { 9, 3, 5, Double.PositiveInfinity }; BBState state = new BBState(matrix, new List<int>() { 0 }, new List<int>() { 1,2,3 },0); //BBState state = new BBState(matrix, new List<int>() { 0 }, citiesLeft,0); PriorityQueue.getInstance().insert(state); BBState current; while (!PriorityQueue.getInstance().isEmpty()) { current = PriorityQueue.getInstance().deletemin(); if(state.extend()) { if(current.getCost() < bssf) { bssf = current.getCost(); PriorityQueue.getInstance().trim(bssf); } } } results[COST] = "not implemented"; // load results into array here, replacing these dummy values results[TIME] = "-1"; results[COUNT] = "-1"; return results; }
//Our TSP internal void solveProblemTabu() { int bssfUpdates = 0; Algorithms algorithms = new Algorithms(); bssf = new TSPSolution(algorithms.greedy(Cities)); TSPSolution currentSolution = new TSPSolution(bssf.Route); int size = Convert.ToInt32(Program.MainForm.textBoxTabuSize.Text); TabuList tabuList = new TabuList(size);//set capacity of tabuList int timeSeconds = Convert.ToInt32(Program.MainForm.textBoxTime.Text); double totalTime = 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while(stopwatch.Elapsed.TotalSeconds < timeSeconds)//run for 600 seconds, 10 minutes { currentSolution = findBestCandidate(currentSolution, tabuList); if(currentSolution.cost < bssf.cost) { bssf = new TSPSolution(currentSolution.Route); totalTime = stopwatch.Elapsed.TotalSeconds; bssfUpdates++; } tabuList.addSolution(currentSolution); } stopwatch.Stop(); Program.MainForm.tbCostOfTour.Text = " " + bssf.cost; Program.MainForm.tbElapsedTime.Text = " " + totalTime; //Program.MainForm.tbElapsedTime.Text = " " + stopwatch.Elapsed.TotalSeconds; Program.MainForm.toolStripTextBox1.Text = " " + bssfUpdates; //print bssf update number // do a refresh. Program.MainForm.Invalidate(); }