queens2.c 3.06 KB
/* solves two unconnected queens problems */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#include <paccs.h>

#define NMAX 200		// maximum number of queens

static int N1 = 11, N2 = 11;	// actual number of queens

void init_queens(fd_int *queens, int N)
{
#define queens (queens + BASE)
  static int BASE = 0;
  int i, j;

/*
  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);
*/

  //queens[0] = fd_new(2, 2);
  //queens[1] = fd_new(5, 5);
  //queens[2] = fd_new(3, 3);

  // N == 20
  //queens[0] = fd_new(3, 3);
  //queens[1] = fd_new(12, 12);
  //queens[2] = fd_new(9, 9);
  //queens[3] = fd_new(17, 17);
  //queens[4] = fd_new(14, 14);
  //queens[5] = fd_new(5, 5);
  //queens[6] = fd_new(15, 15);

  for (i = 0; i < N; ++i)
#if 0
    if (i == 0)
      queens[i] = fd_new(1, 1);
    else if (i == 99)
      queens[i] = fd_new(2, 2);
    else
#endif
      queens[i] = fd_new(1, N);

  //queens[N - 1] = fd_new(6, 6);

#if 01
  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);

  BASE += N;
#undef queens
}

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

  fd_init(&argc, &argv);

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

	if (i + 1 < argc)
	  N2 = atoi(argv[++i]);
      }

#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

  init_queens(queens, N1);
  init_queens(queens, N2);

  while (fd_solve() == FD_OK)
    {
      printf("solution %d:\n", ++solutions);

      printf("problem 1\n");

#if 01
      for (i = 0; i < N1; ++i)
	if (!fd_var_single(queens[i], NULL))
	  fd__fatal("solution contains non-singleton variable");
#endif

      for (i = 0; i < N1; ++i)
	{
	  fd_print(queens[i]);
	  putchar(' ');
	}
      putchar('\n');

      printf("problem 2\n");

#if 01
      for (i = N1; i < N1 + N2; ++i)
	if (!fd_var_single(queens[i], NULL))
	  fd__fatal("solution contains non-singleton variable");
#endif

      for (i = N1; i < N1 + N2; ++i)
	{
	  fd_print(queens[i]);
	  putchar(' ');
	}
      putchar('\n');

#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;
}