void kdtree_semigreedy_tour(kdtree *tree, data *d, int start, int *tour, int *len) { int dim = d->numnodes; int i, current, next; int lenght = 0; /* RCL. */ int j, k; double total_bias, prob_acc, prob_pick, prob; struct rcl params; params.candidates = MALLOC(dim, struct heapelm); tour[0] = start; current = start; for (i = 1; i < dim; i++) { kdtree_delete(tree, current); /* Define RCL size. */ params.rcl_used = 0; params.rcl_size = RANDOM(3) + 1; kdtree_m_nearest_neighbours(tree, d, current, ¶ms); /*printf("RCL size: %d, used: %d\n", params.rcl_size, params.rcl_used); heap_dump(params.candidates, params.rcl_used);*/ /* Pick an element from RCL. */ total_bias = 0; for (j = 1; j <= params.rcl_used; j++) { total_bias += BIAS(j); } prob_acc = 0; prob_pick = RANDOM_UNIT(); for (j = params.rcl_used, k = 1; j >= 0; j--, k++) { prob = BIAS(k) / total_bias; if (prob + prob_acc > prob_pick) { break; } prob_acc += prob; } /*printf("Picked %d: %d, %d\n", j, params.candidates[j - 1].num, params.candidates[j - 1].cost);*/ next = params.candidates[j - 1].num; /* Update tour. */ tour[i] = next; lenght += params.candidates[j - 1].cost; current = next; } lenght += d->dist(d, current, start); *len = lenght; kdtree_undelete_all(tree, d->numnodes); free(params.candidates); }
static int probabilistic_choice (double *probs, int size, double div) {/*{{{*/ double p, last; int i; p = (double) RANDOM_UNIT() / INT_MAX; last = 0; for (i = 0; i < size; i++) { if (p <= last + (probs[i]/div)) { return i; } last += (probs[i]/div); } return i; }/*}}}*/
static int choose_vertex(double *probb, int size) {/*{{{*/ double p, last, div; int i; div = probb[size]; p = (double) RANDOM_UNIT() / INT_MAX; last = 0; for (i = 0; i < size; i++) { if (p <= last + (probb[i]/div)) { return i; } last += (probb[i]/div); } abort(); }/*}}}*/
/* lct: location * flt: facility */ int next_facility(QAP_t *p, set_t *s, int lct){ /* int fcl; int x = rand() % s->size; fcl = s->data[x]; s->data[x] = s->data[s->size - 1]; s->size--; return fcl; */ double delta, x, prob[N], last; int flt, i; delta = 0; for (i = 0; i < p->size; i++) { delta += pheromone[lct][i]; } for (i = 0; i < s->size; i++) { flt = s->data[i]; prob[i] = pheromone[lct][flt] / delta; } x = (double) RANDOM_UNIT() / INT_MAX; last = 0; for (i = 0; i < s->size; i++) { if (x <= last + prob[i]) { flt = s->data[i]; break; } last += prob[i]; } s->data[i] = s->data[s->size - 1]; s->size--; return flt; }
static void semi_greedy(data *d, int start, int *tour, int *tour_length) { int i, j, k; int dim = d->numnodes; int current, len, dist; int *visited = MALLOC(dim, int); /* RCL. */ struct heapelm *candidates = MALLOC(dim, struct heapelm); int rclsize, rclused; double total_bias, rprob, racc, rpick; memset(visited, 0, dim * sizeof(int)); len = 0; current = start; for (i = 0; i < dim - 1; i++) { visited[current] = 1; tour[i] = current; /* Define RCL size. */ rclused = 0; if (RANDOM_UNIT() < 0.05) rclsize = dim - i - 2; else rclsize = RANDOM(((dim - i - 2) / 4) + 1); rclsize++; DEBUG("RCL size: %d\n", rclsize); /* Define RCL. */ for (j = 0; j < dim; j++) { if (!visited[j]) { dist = d->dist(d, current, j); if (rclused < rclsize) { candidates[rclused].num = j; candidates[rclused].cost = dist; rclused++; if (rclused == rclsize) { heap_build_max(candidates, rclsize); } } else if (dist < candidates[0].cost) { heap_replace_root(candidates, rclsize, j, dist); } } } DEBUG("RCL used: %d\n", rclused); heap_dump(candidates, rclused); /* Pick RCL element based on logarithmic bias. */ #define BIAS_LOG(r) (1/log((r)+1)) #define BIAS_LINEAR(r) (1./(r)) #define BIAS_EXP(r) (1/exp(r)) #define BIAS_RANDOM(r) 1 #define BIAS(r) BIAS_LOG(r) total_bias = 0; for (j = 1; j <= rclused; j++) { total_bias += BIAS(j); } racc = 0; rpick = RANDOM_UNIT(); #if DEBUGGING for (j = rclused; j >= 1; j--) { DEBUG("%f ", BIAS(j) / total_bias); } DEBUG("\nR: %f\n", rpick); #endif for (j = rclused, k = 1; j >= 0; j--, k++) { rprob = BIAS(k) / total_bias; if (rprob + racc > rpick) { break; } racc += rprob; } DEBUG("Picked: j = %d, %d %d\n\n", j, candidates[j-1].num, candidates[j-1].cost); current = candidates[j - 1].num; len += candidates[j - 1].cost; } tour[i] = current; len += d->dist(d, current, start); *tour_length = len; free(visited); free(candidates); #undef BIAS #undef BIAS_LOG }