static void gogo_ant(ref ant_t ant, matrix_t adj_mat, matrix_t weight, matrix_t d_pheromon, int q) { int N = weight.n; int i = 1; int next = 0; array_t prob = create_array(N); while (i < N) { double sum_weight = 0; for (int j = 0; j < N; j++) { sum_weight += weight.matr[ant.curr_city, j] * ant.Jk.arr[j]; } for (int j = 0; j < N; j++) { prob.arr[j] = weight.matr[ant.curr_city, j] / sum_weight * ant.Jk.arr[j]; } next = choose_next(prob); ant.curr_city = next; ant.Jk.arr[next] = 0; ant.route.arr[i++] = next; } ant.Lk = (int)(length_of_route(adj_mat, ant.route)); add_pheromon(d_pheromon, ant.route, ant.Lk, q); }
static array_t create_array(int size) { array_t array = new array_t(); array.arr = new double[size]; array.size = size; return(array); }
static void add_pheromon(matrix_t d_pheromon, array_t route, int Lk, int q) { float d_fer = (float)q / (float)Lk; for (int i = 0; i < route.size - 1; i++) { d_pheromon.matr[(int)route.arr[i], (int)route.arr[i + 1]] += d_fer; } }
static void copy_array(array_t dst, array_t src) { if (dst.size == src.size) { for (int i = 0; i < dst.size; i++) { dst.arr[i] = src.arr[i]; } } }
static double length_of_route(matrix_t adj_mat, array_t route) { double length = 0; for (int i = 0; i < route.size - 1; i++) { length += adj_mat.matr[(int)route.arr[i], (int)route.arr[i + 1]]; } return(length); }
static int choose_next(array_t prob) { int i = 0; double r = rand.NextDouble(); if (r == 0) { while (prob.arr[i++] <= 0) { ; } return(--i); } while (r > 0) { r -= prob.arr[i++]; } return(--i); }
static solution_t solve(matrix_t adj_mat, double a, double b, double p, int q, int t_max) { int N = adj_mat.n; ant_t[] ants = create_ant_array(N); matrix_t pheromon = create_matrix(N, N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { pheromon.matr[i, j] = 0.5; } } matrix_t visib = create_matrix(N, N); for (int i = 0; i < N; i++) { for (int j = i; j < N; j++) { if (i != j) { visib.matr[i, j] = 1 / adj_mat.matr[i, j]; visib.matr[j, i] = visib.matr[i, j]; } else { visib.matr[i, j] = 1000; } } } matrix_t weight = create_matrix(N, N); recalc_weight(ref weight, pheromon, visib, a, b); int best_l = int.MaxValue; array_t route = create_array(N); for (int t = 0; t < t_max; t++) { for (int k = 0; k < N; k++) { init_ant(ref ants[k]); gogo_ant(ref ants[k], adj_mat, weight, pheromon, q); } int best = -1; for (int i = 0; i < N; i++) { if (ants[i].Lk < best_l) { best = i; best_l = ants[i].Lk; } } if (best != -1) { copy_array(route, ants[best].route); } recalc_pheromon(ref pheromon, p); recalc_weight(ref weight, pheromon, visib, a, b); } solution_t solv = new solution_t(); solv.l = best_l; solv.route = route; return(solv); }