private int[] FindBestTrail(int[][] dists, int numCities) { random = new Random(0); var ants = InitAnts(numCities); // initialize ants to random trails int[] bestTrail = BestTrail(ants, dists); // determine the best initial trail double bestLength = Length(bestTrail, dists); // the length of the best trail Pheromone pheromone = new Pheromone(numCities); int time = 0; while (time < maxTime) { UpdateAnts(ants, pheromone, dists); UpdatePheromones(pheromone, ants, dists); int[] currBestTrail = BestTrail(ants, dists); double currBestLength = Length(currBestTrail, dists); if (currBestLength < bestLength) { bestLength = currBestLength; bestTrail = currBestTrail; //Console.WriteLine("New best length of " + bestLength.ToString("F1") + " found at " + time); } time += 1; } return(bestTrail); }
private void UpdateAnts(Ant[] ants, Pheromone pheromone, int[][] dists) { int numCities = pheromone.Size; for (int k = 0; k <= ants.Length - 1; k++) { int start = isStartPointFixed ? startPoint : random.Next(0, numCities); int[] newTrail = isEndPointFixed ? BuildTrail(start, endPoint, pheromone, dists) : BuildTrail(start, pheromone, dists); ants[k].Trail = newTrail; } }
private double[] MoveProbs(int cityX, bool[] visited, Pheromone pheromone, int[][] dists) { // for ant, located at nodeX, with visited[], return the prob of moving to each city int numCities = pheromone.Size; double[] taueta = new double[numCities]; // inclues cityX and visited cities double sum = 0.0; // sum of all tauetas // i is the adjacent city for (int i = 0; i <= taueta.Length - 1; i++) { if (i == cityX) { taueta[i] = 0.0; // prob of moving to self is 0 } else if (visited[i]) { taueta[i] = 0.0; // prob of moving to a visited city is 0 } else { taueta[i] = Math.Pow(pheromone.Get(cityX, i), alpha) * Math.Pow((1.0 / Distance(cityX, i, dists)), beta); // could be huge when pheromone[][] is big if (taueta[i] < 0.0001) { taueta[i] = 0.0001; } else if (taueta[i] > (double.MaxValue / (numCities * 100))) { taueta[i] = double.MaxValue / (numCities * 100); } } sum += taueta[i]; } double[] probs = new double[numCities]; for (int i = 0; i <= probs.Length - 1; i++) { probs[i] = taueta[i] / sum; // big trouble if sum = 0.0 } return(probs); }
private int[] BuildTrail(int start, Pheromone pheromone, int[][] dists) { int numCities = pheromone.Size; int[] trail = new int[numCities]; bool[] visited = new bool[numCities]; trail[0] = start; visited[start] = true; for (int i = 0; i <= numCities - 2; i++) { int cityX = trail[i]; int next = NextCity(cityX, visited, pheromone, dists); trail[i + 1] = next; visited[next] = true; } return(trail); }
private void UpdatePheromones(Pheromone pheromone, Ant[] ants, int[][] dists) { for (int i = 0; i <= pheromone.Size - 1; i++) { for (int j = i + 1; j <= pheromone.Size - 1; j++) { for (int k = 0; k <= ants.Length - 1; k++) { double length = Length(ants[k].Trail, dists); // length of ant k trail double decrease = (1.0 - rho) * pheromone.Get(i, j); double increase = 0.0; if (EdgeInTrail(i, j, ants[k].Trail)) { increase = (Q / length); } pheromone.Set(i, j, decrease + increase); } } } }
private int NextCity(int cityX, bool[] visited, Pheromone pheromone, int[][] dists) { // for ant (with visited[]), at nodeX, what is next node in trail? double[] probs = MoveProbs(cityX, visited, pheromone, dists); double[] cumul = new double[probs.Length + 1]; for (int i = 0; i <= probs.Length - 1; i++) { cumul[i + 1] = cumul[i] + probs[i]; // consider setting cumul[cuml.Length-1] to 1.00 } double p = random.NextDouble(); for (int i = 0; i <= cumul.Length - 2; i++) { if (p >= cumul[i] && p < cumul[i + 1]) { return(i); } } throw new Exception("Failure to return valid city in NextCity"); }