// random routes and cut points void rand_string_relocation(int[][] routes, int mode, int K) { // select two routes int r1, r2, c1, c2, x1, x2; int[] newr1; int[] newr2; int c = 0; // select cut lengths x1 = MatUtils.irandom(K - 1) + 1; // number of stops from r1 to r2 do { r1 = MatUtils.irandom(routes.length - 1); // source c++; } while (c < 2 * routes.length && routes[r1].length <= x1); do { r2 = MatUtils.irandom(routes.length - 1); // destination c++; } while (c < 2 * routes.length && r1 == r2); if (c != 2 * routes.length) { // select cut points c1 = MatUtils.irandom(routes[r1].length - x1 - 1) + 1; c2 = MatUtils.irandom(routes[r2].length - 1) + 1; boolean feasible = (excess_demand(routes) == 0.0); string_relocation(routes, r1, r2, x1, c1, c2, mode, feasible, true); } }
int[] inversion_improve(int[] sol) { int i, j, l; int s = sol.length; int[] newsol = new int[s]; int pos = MatUtils.irandom(s - 1); int k = MatUtils.irandom(s - 2); int n = (int) (k / 2); for (i = 0; i < s; i++) newsol[i] = sol[i]; for (i = 0, j = pos, l = (pos + k - 1) % s; i < n; i++, j = (j + 1) % s) { newsol[j] = sol[l]; newsol[l] = sol[j]; if (l > 0) l--; else l = s - 1; } improve_routes_2opt(newsol); if (total_cost(newsol) < total_cost(sol)) return newsol; else return sol; }
// String exchange move - random routes and cut points void rand_string_exchange(int[][] routes, int mode, int K) { // select two routes int r1, r2, c1, c2, x1, x2; int c = 0; // avoid infinite loops // select cut lengths // x1 = MatUtils.irandom(K-1)+1; //number of stops from r1 to r2 // x2 = MatUtils.irandom(K-1)+1; //number of stops from r2 to r1 x1 = MatUtils.irandom(K); // number of stops from r1 to r2 x2 = MatUtils.irandom(K); // number of stops from r2 to r1 do { r1 = MatUtils.irandom(routes.length - 1); c++; } while (c < 2 * routes.length && routes[r1].length <= x1); do { r2 = MatUtils.irandom(routes.length - 1); c++; } while (c < 2 * routes.length && (r1 == r2 || routes[r2].length <= x2)); if (c != 2 * routes.length) { // select cut points c1 = MatUtils.irandom(routes[r1].length - x1 - 1) + 1; c2 = MatUtils.irandom(routes[r2].length - x2 - 1) + 1; boolean feasible = (excess_demand(routes) == 0.0); string_exchange(routes, r1, r2, x1, x2, c1, c2, mode, feasible, true); } }
int[] order_inversion_improve(int[] sol) { int i, j, l; int[] newsol = new int[nc]; int pos = MatUtils.irandom(nc - 1); int k = MatUtils.irandom(nc - 2); int n = (int) (k / 2); for (i = 0; i < nc; i++) newsol[i] = sol[i]; for (i = 0, j = pos, l = (pos + k - 1) % nc; i < n; i++, j = (j + 1) % nc) { newsol[j] = sol[l]; newsol[l] = sol[j]; if (l > 0) l--; else l = nc - 1; } int[][] r = routes_from_order(sol); int[][] r1 = routes_from_order(newsol); // improve_routes_2opt(newsol); if (total_cost(r1) < total_cost(r)) return newsol; else return sol; }
// string cross with random routes and cut points // mode = ALWAYS_PERFORM ou PERFORM_ON_IMPROVE void rand_string_cross(int[][] routes, int mode) { // select two routes int r1, r2, c1, c2; int c = 0; // used to avoid possibility of infinite loopS do { r1 = MatUtils.irandom(routes.length - 1); c++; } while (c < 2 * routes.length && routes[r1].length < 3); c = 0; do { r2 = MatUtils.irandom(routes.length - 1); c++; } while (c < 2 * routes.length && (routes[r2].length < 3 || r1 == r2)); if (c != 2 * routes.length) { // select cut points c1 = MatUtils.irandom(routes[r1].length - 3) + 2; c2 = MatUtils.irandom(routes[r2].length - 3) + 2; boolean feasible = (excess_demand(routes) == 0.0); string_cross(routes, r1, r2, c1, c2, mode, feasible, true); } }