#include #include //#include //#include //#include #include #include "fdc_int.h" // try to save on variables static fd_int fd_const[MAX_VALUE + 1]; #define FD_CONST(n) (fd_const[n] ? fd_const[n] : (fd_const[n] = fd_new(n, n))) //#define FD_CONST(n) fd_new(n, n) /* Costas arrays (communicated by Daniel Diaz) */ #define diffs(a, b) diffs[(a) * (N - 1) + (b)] int main(int argc, char *argv[]) { int solutions = 0, one_solution = 1; int use_label = 0; int i, j; int verbose = 0; fd_int *array, *diffs; int N = 10; int coeffs[] = { 1, 1, -1 }; fd_int diffeq[3]; int k; fd_init(&argc, &argv); for (i = 1; i < argc; ++i) if (!strcmp(argv[i], "--all")) one_solution = 0; else if (!strcmp(argv[i], "--label")) use_label = 1; else if (!strncmp(argv[i], "-v", 2)) { char *s = argv[i] + 1; while (*s++ == 'v') verbose++; } else if (isdigit(*argv[i])) { N = atoi(argv[i]); i++; break; } else _fd_error("%s: unknown option `%s'\n", argv[0], argv[i]); array = calloc(N, sizeof(*array)); for (j = 0; i < argc; ++j, ++i) { int a, b; a = b = atoi(argv[i]); if (strchr(argv[i], '-')) b = atoi(strchr(argv[i], '-') + 1); array[j] = (a == b) ? FD_CONST(a - 1) : fd_new(a - 1, b - 1); } for (; j < N; ++j) array[j] = fd_new(0, N - 1); fd_all_different(array, N); if (use_label) fd_label(array, N); // differences: // 0 <= array[] < N // -> -(N-1) <= array[i] - array[j] <= N-1 // -> 0 <= array[i] - array[j] + N-1 <= 2*(N-1) diffs = calloc((N - 2) * (N - 1), sizeof(*diffs)); for (i = 0; i < N - 2; ++i) for (j = 0; j < N - 1 - i; ++j) diffs(i, j) = fd_new(0, 2 * (N - 1)); diffeq[0] = FD_CONST(N - 1); for (k = 1; k < N - 1; ++k) { for (i = k; i < N; ++i) { diffeq[1] = array[i]; diffeq[2] = array[i - k]; fd_poly_eq(coeffs, diffeq, 3, diffs(k - 1, i - k)); if (verbose >= 2) printf("x[%d] - x[%d] -> (%d,%d)\n", i, i-k, k-1, i-k); } fd_all_different(&diffs(k - 1, 0), N - k); } while (fd_solve() == FD_OK) { printf("solution %d:\n", ++solutions); for (i = 0; i < N; ++i) { printf("%d", fd_var_value(array[i]) + 1); if (i != N - 1) putchar(' '); } putchar('\n'); if (verbose >= 1) for (k = 1; k < N - 1; ++k) { printf("%*s", k, ""); for (i = k; i < N; ++i) printf("%d ", fd_var_value(diffs(k - 1, i - k)) - (N - 1)); putchar('\n'); } #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; }