private TSPSolution getShortestTour() { double lowestCost = Double.PositiveInfinity; Ant lowestAnt = null; foreach (Ant ant in ants) { if (ant.getFinalTourLength(Cities) < lowestCost) { lowestCost = ant.getFinalTourLength(Cities); lowestAnt = ant; } } if (lowestAnt == null) { return(null); } return(new TSPSolution(indexToCities(Cities, lowestAnt.pathSoFar))); }
private Edge NextEdge(Ant ant) { double c = 0; double r = random.NextDouble(); Vertex vertex = ant.visitedVertices.Peek(); foreach (Edge e in vertex.neighbors) { if (!ant.visitedVertices.Contains(e.vertex2)) { c += Probability(ant, e); if (c >= r) { return(e); } } } return(null); }
private void AntPath(Ant ant) { counter = 0; AntPathRecurring(ant, ant.startVertex); }
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(); }
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(); }
public void doCircut(Ant ant) { ant.visitCity(rand.Next(0, Cities.Length)); for (int i = 0; i < Cities.Length - 1; i++) { if (rand.NextDouble() < RANDOM_CHANCE) { int t = rand.Next(Cities.Length - ant.getCurrentCity()); // random town int j = -1; for (int k = 0; k < Cities.Length; k++) { if (!ant.citiesVisited[k]) { j++; } if (j == t) { ant.visitCity(k); break; } } } double[] probs = new double[Cities.Length]; double denom = 0.0; for (int j = 0; j < Cities.Length; j++) { if (ant.citiesVisited[j]) { probs[j] = 0.0; } else { probs[j] = getProbability(ant.getCurrentCity(), j); } denom += probs[j]; } if (denom == 0) { ant = new Ant(Cities.Length); doCircut(ant); if (ant.pathSoFar.Count < Cities.Length) { finishPath(ant); return; } return; } for (int j = 0; j < Cities.Length; j++) { probs[j] /= denom; } double r = rand.NextDouble(); double total = 0.0; for (int j = 0; j < Cities.Length; j++) { total += probs[j]; if (total >= r) { ant.visitCity(j); break; } } } if (ant.pathSoFar.Count < Cities.Length) { finishPath(ant); return; } }
/* * Clears out the ant's path. * The ant's new path is then started at a random city. */ private void ResetAnt(Ant ant) { ant.Path.Clear(); ant.Visited.Clear(); ant.Add(random.Next(0, Cities.Length)); }
public string[] fancySolveProblem() { string[] results = new string[3]; int count = 0; Stopwatch timer = new Stopwatch(); Ant[] ants = new Ant[Cities.Length]; //Initialize with empty ants for (int i = 0; i < Cities.Length; i++) { ants[i] = new Ant(); ants[i].Add(i); } distances = CalculateInitialMatrix(); pheromones = new double[Cities.Length, Cities.Length]; for (int i = 0; i < Cities.Length; i++) { for (int j = 0; j < Cities.Length; j++) { pheromones[i, j] = 1; } } int iterations = 0; timer.Start(); /* * While we are not out of time and still seeing changes, * The ants all select the best edge out of current city. * This is done using the distance and pheromone of the edge. * When a completed tour is found, it is compared to the BSSF. * If the tour is better the BSSF is updated. * The existing, older pheromones fade by a constant factor, * and additional pheromone is placed on the new tour. * After this an ant with a completed tour is reset. */ while (timer.Elapsed.TotalMilliseconds < time_limit && iterations < ITERATION_THRESHOLD) { for (int i = 0; i < Cities.Length; i++) { for (int j = 0; j < Cities.Length; j++) { if (ants[j].Count == Cities.Length) { if (Cities[ants[j].Path[ants[j].Count - 1]].costToGetTo(Cities[ants[j].Path[0]]) != double.PositiveInfinity) { TSPSolution potentialSolution = GenerateRoute(ants[j].Path); double costOfRoute = potentialSolution.costOfRoute(); if (bssf == null || costOfRoute < costOfBssf()) { iterations = 0; bssf = potentialSolution; count++; } FadePheromone(); DropPheromone(ants[j], costOfRoute); } ResetAnt(ants[j]); } TakeNextEdge(ants[j]); } } iterations++; } timer.Stop(); results[COST] = costOfBssf().ToString(); results[TIME] = timer.Elapsed.ToString(); results[COUNT] = count.ToString(); Console.WriteLine("Ant Colony Size: " + Cities.Length + " Random: " + Seed + " Path: " + costOfBssf().ToString() + " Time: " + timer.Elapsed.ToString()); return(results); }
public void groupTSP() { // start our timer System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); // constants used in heuristics const int ITERATIONS = 50; const double Q0 = 0.9; const double BETA = 50.0; const double ALPHA = 0.1; // get cost from nearest neighbor, used in our heuristic greedy(); double nnCost = costOfBssf(); // our fastest ant through all the iterations Ant bestAnt = null; double bestCost = Double.PositiveInfinity; // initialize pheramone level matrix double[,] pheromoneLevels = new double[Cities.Length, Cities.Length]; for (int i = 0; i < Cities.Length; i++) { for (int j = 0; j < Cities.Length; j++) { pheromoneLevels[i, j] = 1.0 / Cities.Length; } } // start iterations for (int h = 0; h < ITERATIONS; h++) { // our fastest ant in the iteration Ant bestAntIter = null; double bestCostIter = Double.PositiveInfinity; // initialize ants List <Ant> ants = new List <Ant>(); for (int i = 0; i < Cities.Length; i++) { ants.Add(new Ant(Cities.Length, i)); } // iterate through each time step for (int i = 0; i < Cities.Length - 1; i++) { // determine each ants next move List <Ant> remainingAnts = new List <Ant>(ants); foreach (Ant ant in remainingAnts) { int nextCity = -1; double nextDistance = Double.PositiveInfinity; Random random = new Random(); double q = random.NextDouble(); if (q < Q0) { // select next city based on distance / pheramone only double bestScore = Double.NegativeInfinity; foreach (int city in ant.unvisited) { double distance = Cities[ant.curCity].costToGetTo(Cities[city]); double score = pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA); if (score > bestScore) { nextCity = city; bestScore = score; nextDistance = distance; } } } else { // select city randomly with different weights given to each city based on distance / pheramone double runningTotal = 0.0; double randomValue = random.NextDouble(); // get sum of scores double summedScores = 0.0; foreach (int city in ant.unvisited) { double distance = Cities[ant.curCity].costToGetTo(Cities[city]); summedScores += pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA); } // determine probability for each city foreach (int city in ant.unvisited) { double distance = Cities[ant.curCity].costToGetTo(Cities[city]); runningTotal += (pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA)) / summedScores; if (runningTotal > randomValue) { nextCity = city; nextDistance = distance; break; } } } if (nextCity != -1) { // apply local trail updating pheromoneLevels[ant.curCity, nextCity] += (1 - ALPHA) * pheromoneLevels[ant.curCity, nextCity] + ALPHA * (1 / (Cities.Length * nnCost)); // add the picked city to the tour ant.tour[ant.curCity] = nextCity; ant.unvisited.Remove(nextCity); ant.curCost += nextDistance; ant.prevCity = ant.curCity; ant.curCity = nextCity; } else { //deal with stuck ant ants.Remove(ant); } } } // finalize tours and find best ant foreach (Ant ant in ants) { // finalize tour ant.tour[ant.curCity] = ant.startCity; ant.curCost += Cities[ant.curCity].costToGetTo(Cities[ant.startCity]); // check against current best cost if (ant.curCost < bestCostIter) { bestAntIter = ant; bestCostIter = ant.curCost; } } if (bestAntIter != null) { // apply global trail updating int current = bestAntIter.startCity; do { pheromoneLevels[current, bestAntIter.tour[current]] += (1 - ALPHA) * pheromoneLevels[current, bestAntIter.tour[current]] + ALPHA * (1 / bestCostIter); current = bestAntIter.tour[current]; } while (current != bestAntIter.startCity); // see if it is the best ant through all iterations so far if (bestCostIter < bestCost) { bestAnt = bestAntIter; bestCost = bestCostIter; } } } if (bestAnt != null) { ArrayList route = new ArrayList(); int curCity = bestAnt.startCity; do { route.Add(Cities[curCity]); curCity = bestAnt.tour[curCity]; } while (curCity != bestAnt.startCity); bssf = new TSPSolution(route); } timer.Stop(); Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = Convert.ToString(timer.Elapsed); // do a refresh. Program.MainForm.Invalidate(); }