36static int randint(
int n_max) {
40 div_t y = div(-RAND_MAX-1, -n_max-1);
43 while (x > RAND_MAX + y.rem);
47#include <gsl/gsl_rng.h>
50static int randint(
int n_max) {
51 return gsl_rng_uniform_int(rng, n_max+1);
61static int *randperm(
int *p,
int n) {
66 for (i = 1; i < n; i++) {
75static void swap(
int *data,
int i,
int j) {
95struct problem *newProblem(
const char *filename) {
99 infile = fopen(filename,
"r");
101 fscanf(infile,
"%d", &n);
107 fprintf(stderr,
"Invalid n-Queens instance %s\n", filename);
109 fprintf(stderr,
"Cannot open file %s\n", filename);
113struct problem *newProblem(
int n) {
119 fprintf(stderr,
"Invalid board size: %d\n", n);
137 s->data = (
int*) malloc(p->n * sizeof (
int));
138 s->olddata = (
int*) malloc(p->n * sizeof (
int));
139 s->mod = (
int*) malloc(p->n * sizeof (
int));
140 s->modi = (
int*) malloc(p->n * sizeof (
int));
162 ps->data = (
int*) malloc(p->n * sizeof (
int));
163 ps->datai = (
int*) malloc(p->n * sizeof (
int));
164 ps->cycle = (
int*) malloc(p->n * sizeof (
int));
165 ps->pos = (
int*) malloc(p->n * sizeof (
int));
174void freeProblem(
struct problem *p) {
182void freeSolution(
struct solution *s) {
194void freeMove(
struct move *v) {
204void freePathState(
struct pathState *ps) {
213void printProblem(
struct problem *p) {
214 printf(
"%d-Queens problem\n",p->n);
217void printSolution(
struct solution *s) {
219 printf(
"%d-Queens solution\n p:", s->n);
220 for(i = 0; i < s->n; i++)
221 printf(
" %d", s->data[i]);
224 for(i = 0; i < s->n; i++)
225 printf(
" %d", s->mod[i]);
227 for(i = 0; i < s->n; i++)
228 printf(
" %d", s->modi[i]);
233void printMove(
struct move *v) {
234 printf(
"%d-Queens move: %d, %d\n", v->prob->n, v->data[0], v->data[1]);
237void printPathState(
struct pathState *ps) {
239 printf(
"%d-Queens path state\n", ps->n);
240 printf(
" Path length: %d\n Permutation:", ps->n - ps->n_cycles);
241 for (i = 0; i < ps->n; i++)
242 printf(
" %d",ps->data[i]);
243 printf(
"\n Inverse permutation:");
244 for (i = 0; i < ps->n; i++)
245 printf(
" %d", ps->datai[i]);
246 printf(
"\n Cycles:");
247 for (i = 0; i < ps->n; i++)
248 printf(
" %d", ps->cycle[i]);
249 printf(
"\n Number of different positions: %d\n Positions: ", ps->n_diff);
250 for (i = 0; i < ps->n_diff; i++)
251 printf(
"%d ",ps->pos[i]);
264 randperm(s->data, s->n);
266 for (i = 0; i < s->n; i++)
267 s->mod[i] = s->modi[i] = i;
280double getObjectiveValue(
struct solution *s) {
281 int i, j, n = s->n, att, *mod, nmod = s->nmod;
284 for (i = 0; i < n-1; i++)
285 for (j = i+1; j < n; j++)
286 att += (j - i == abs(s->data[i] - s->data[j]));
288 memcpy(s->olddata, s->data, n * sizeof (
int));
290 }
else if (nmod >= 1) {
293 for (i = 0; i < nmod-1; i++)
294 for (j = i+1; j < nmod; j++)
295 att += (abs(mod[j] - mod[i]) == abs(s->data[mod[i]] - s->data[mod[j]])) -
296 (abs(mod[j] - mod[i]) == abs(s->olddata[mod[i]] - s->olddata[mod[j]]));
297 for (i = 0; i < nmod; i++)
298 for (j = nmod; j < n; j++)
299 att += (abs(mod[j] - mod[i]) == abs(s->data[mod[i]] - s->data[mod[j]])) -
300 (abs(mod[j] - mod[i]) == abs(s->olddata[mod[i]] - s->olddata[mod[j]]));
302 memcpy(s->olddata, s->data, n * sizeof (
int));
307 for (i = 0; i < n-1; i++)
308 for (j = i+1; j < n; j++)
309 if (j - i == abs(s->data[i] - s->data[j]))
311 printf(
"incremental = %d, full = %d, diff = %d\n", s->objvalue, att, s->objvalue-att);
315 return (
double)s->objvalue;
320 dest->prob = src->prob;
322 memcpy(dest->data, src->data, src->n * sizeof (
int));
323 memcpy(dest->olddata, src->olddata, src->n * sizeof (
int));
324 memcpy(dest->mod, src->mod, src->n * sizeof (
int));
325 memcpy(dest->modi, src->modi, src->n * sizeof (
int));
326 dest->nmod = src->nmod;
327 dest->objvalue = src->objvalue;
342 if (s->modi[i] >= s->nmod) {
343 swap(s->mod, s->modi[i], s->nmod);
344 swap(s->modi, i, s->mod[s->modi[i]]);
347 if (s->modi[j] >= s->nmod) {
348 swap(s->mod, s->modi[j], s->nmod);
349 swap(s->modi, j, s->mod[s->modi[j]]);
367 v->data[0] = randint(n-1);
368 v->data[1] = (v->data[0] + 1 + randint(n-2)) % n;
379 int i, j, r, n = ps->n;
380 int *pos = ps->pos, *data = ps->data, *datai = ps->datai;
382 if (ps->n_cycles >= n) {
383 v->data[0] = v->data[1] = 0;
392 r = randint(--ps->n_diff);
393 i = v->data[0] = pos[r];
396 pos[r] = pos[ps->n_diff];
402 swap(ps->datai, i, data[i]);
403 swap(ps->data, i, j);
419 for (i = 0; i < n; i++)
420 ps->pos[s2->data[i]] = i;
421 for (i = 0; i < n; i++)
422 ps->data[i] = ps->pos[s1->data[i]];
424 for (i = 0; i < n; i++)
425 ps->datai[ps->data[i]] = i;
429 for (i = 0; i < n; i++)
431 for (i = 0; i < n; i++) {
432 if (ps->cycle[i] == 0) {
436 ps->cycle[j] = ps->n_cycles;
443 for (i = 0, j = 0; i < n; i++)
444 if (ps->data[i] != i)
465int getPathLength(
const struct pathState *ps) {
466 return ps->n - ps->n_cycles;