k-queens.c 2.65 KB
#include <stdio.h>
#include <stdlib.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;
  fd_int copy;
  int ncopies = 4;

  fd_init(&argc, &argv);

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

	  break;
	}

      i++;
    }

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

  if (ncopies < 1)
    ncopies = 1;

  copy = fd_new(0, ncopies - 1);	// XXX: only allows MAX_VALUE+1 copies

#ifdef LOCAL_SEARCH
  int seed;
#if 01
  seed = time(0);
  seed = 1206987119;
  //seed = 1207917731; // N = 6, best improvement termina
  //seed = 0;
#else
  int dev_random;

  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__trace("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]);
		putchar(' ');
	      }
	    putchar('\n');

	    break;
	  }

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

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

  fd_end();

  return !solutions;
}