queens.c 2.68 KB
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#include "fdc_int.h"

#ifndef NMAX
#  define NMAX MAX_VARIABLES	// maximum number of queens
#endif

static int N = 11;		// actual number of queens

int main(int argc, char *argv[])
{
  fd_int queens[NMAX];
  int solutions = 0, one_solution = 1;
  int i, j;
  int seed;
  int dev_random;

  fd_init(&argc, &argv);

  for (i = 1; i < argc; ++i)
    if (!strcmp(argv[i], "--all"))
      one_solution = 0;
    else
      {
	N = atoi(argv[i]);

	break;
      }

  if (N > NMAX)
    _fd_fatal("queens: more than NMAX queens requested");

#ifdef LOCAL_SEARCH
#if 01
  seed = time(0);
  seed = 1206987119;
  //seed = 1207917731; // N = 6, best improvement termina
  //seed = 0;
#else
    if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1)
    _fd_fatal("/dev/urandom: %s\n", strerror(errno));

  read(dev_random, &seed, sizeof(seed));
#endif

  srandom(seed);
  _fd_debug("seed = %u\n", seed);
#endif

/*
  FORWARD_CHECKING REBENTA(VA) (N == 6)

  queens[0] = fd_new(2, 5);
  _fd_val_del_val(5, queens[0]->domain);
  queens[N - 1] = fd_new(6, 6);
*/

  for (j = ++i, i = 0; j < argc; ++j, ++i)
    {
      int lb, ub;
      char *p;

      lb = ub = atoi(argv[j]) - 1;
      if (p = strchr(argv[j], '-'))
	ub = atoi(p + 1) - 1;

      queens[i] = fd_new(lb, ub);
    }

  for (; i < N; ++i)
    queens[i] = fd_new(0, N - 1);

#if 0
  fd_fake_all_different(queens, N);
#elif 01
  fd_all_different(queens, N);
#else
  for (i = 0; i < N; ++i)
    fd_exactly_one(queens, N, i + 1);
#endif

  for (i = 0; i < N; ++i)
    for (j = i + 1; j < N; ++j)
      fd_minus_ne(queens[i], queens[j], i - j);

  for (i = 0; i < N; ++i)
    for (j = i + 1; j < N; ++j)
      fd_minus_ne(queens[i], queens[j], j - i);

  while (fd_solve() == FD_OK)
    {
      int value;

      printf("solution %d:\n", ++solutions);

      for (i = 0; i < N; ++i)
	if (fd_var_single(queens[i], &value))
	  printf("%d%c", value + 1, (i < N - 1) ? ' ' : '\n');
	else
	  {
	    int j;

	    _fd_error("\nsolution contains non-singleton variable\n");


	    for (j = 0; j < N; ++j)
	      {
		fd_print(queens[j]);
#if defined(FORWARD_CHECKING) && 0
		printf("\t(%d)", queens[i]->epoch);
		putchar('\n');
	      }
#else
		putchar(' ');
	      }
	    putchar('\n');
#endif

	    break;
	  }

#if !(defined(LOCAL_SEARCH) || defined(DISTRIBUTED_SOLVER))
      if (one_solution)
#endif
	break;
    }

  fd_end();

  {
    // avoid failure messages from mpirun
    extern int _fd_counting_solutions;	// XXX: private variable

    if (_fd_counting_solutions)
      return 0;
  }

  if (solutions)
    printf("%d solutions found\n", solutions);
  else
    printf("inconsistent CSP\n");

  return !solutions;
}