//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))); } } } }
//calcula os valores para a chance de cada aresta ser escolhida para fazer parte da solução final public static void PrepareMove(AntProblem problem) { //vetor que guarda as notas individuais de cada aresta double[,] notaTrilhas = new double[problem.CityCount, problem.CityCount]; //vetor que guarda a soma das notas das arestas visíveis de cada cidade double[] somaNotas = new double[problem.CityCount]; /* calcula a nota de cada aresta separadamente */ //para cada aresta no grafo for (int cityA = 1; cityA <= problem.CityCount; cityA++) { for (int cityB = cityA + 1; cityB <= problem.CityCount; cityB++) { // Otimizar Atribuição pelo Corte pela Metade /*if (cityA == cityB) { * notaTrilhas[cityA - 1, cityB - 1] = 0; * continue; * }*/ //calcula o valor p de acordo com a trilha de feromonios e a distancia notaTrilhas[cityA - 1, cityB - 1] = System.Math.Pow(problem.GetPheromoneBetween(cityA, cityB), problem.pheromoneWeight) * System.Math.Pow(1 / problem.GetDistanceBetween(cityA, cityB), problem.distanceWeight); //e atualiza a soma das notas daquela cidade somaNotas[cityA - 1] += notaTrilhas[cityA - 1, cityB - 1]; } } ProbabilityMatrix = new double[problem.CityCount, problem.CityCount]; /* calcula o vetor de densidade de probabilidade para cada cidade */ //para cada cidade cityA no grafo for (int cityA = 1; cityA <= problem.CityCount; cityA++) { double acumulado = 0; //calcula a chance de visitar a cidade cityB for (int cityB = cityA + 1; cityB <= problem.CityCount; cityB++) { // Otimizar Atribuição pelo Corte pela Metade //como sendo a nota da aresta [cityA, cityB] dividido pela soma de todas as arestas visíveis de cityA (todas) acumulado += notaTrilhas[cityA - 1, cityB - 1] / somaNotas[cityA - 1]; ProbabilityMatrix[cityA - 1, cityB - 1] = acumulado; ProbabilityMatrix[cityB - 1, cityA - 1] = acumulado; } } }
//calcula os valores para a chance de cada aresta ser escolhida para fazer parte da solução final public static void PrepareMove(AntProblem problem) { //vetor que guarda as notas individuais de cada aresta double[,] notaTrilhas = new double[problem.CityCount, problem.CityCount]; //vetor que guarda a soma das notas das arestas visíveis de cada cidade double[] somaNotas = new double[problem.CityCount]; /* calcula a nota de cada aresta separadamente */ //para cada aresta no grafo for (int cityA = 1; cityA <= problem.CityCount; cityA++) { for (int cityB = cityA + 1; cityB <= problem.CityCount; cityB++) { // Otimizar Atribuição pelo Corte pela Metade /*if (cityA == cityB) { notaTrilhas[cityA - 1, cityB - 1] = 0; continue; }*/ //calcula o valor p de acordo com a trilha de feromonios e a distancia notaTrilhas[cityA - 1, cityB - 1] = System.Math.Pow(problem.GetPheromoneBetween(cityA, cityB), problem.pheromoneWeight) * System.Math.Pow(1 / problem.GetDistanceBetween(cityA, cityB), problem.distanceWeight); //e atualiza a soma das notas daquela cidade somaNotas[cityA - 1] += notaTrilhas[cityA - 1, cityB - 1]; } } ProbabilityMatrix = new double[problem.CityCount, problem.CityCount]; /* calcula o vetor de densidade de probabilidade para cada cidade */ //para cada cidade cityA no grafo for (int cityA = 1; cityA <= problem.CityCount; cityA++) { double acumulado = 0; //calcula a chance de visitar a cidade cityB for (int cityB = cityA + 1; cityB <= problem.CityCount; cityB++) { // Otimizar Atribuição pelo Corte pela Metade //como sendo a nota da aresta [cityA, cityB] dividido pela soma de todas as arestas visíveis de cityA (todas) acumulado += notaTrilhas[cityA - 1, cityB - 1] / somaNotas[cityA - 1]; ProbabilityMatrix[cityA - 1, cityB - 1] = acumulado; ProbabilityMatrix[cityB - 1, cityA - 1] = acumulado; } } }