/* * golomb.c * * Created on: 26/03/2016 * Author: pedro * * http://www.csplib.org/Problems/prob006/ * https://github.com/MiniZinc/minizinc-benchmarks/tree/master/golomb * https://www.cril.univ-artois.fr/~lecoutre/benchmarks.html# * * Golomb Ruler problem: * The Golomb Ruler problem is the task of putting n marks on a ruler of length m such that the * distance between any two pairs of marks is distinct. */ #include "golomb.h" #include #include #include #include "../config.h" #include "../constraints/fake_all_different.h" #include "../constraints/ge.h" #include "../constraints/lt.h" #include "../constraints/minimize.h" #include "../constraints/var_eq_minus.h" #include "../split.h" #include "../variables.h" /* * Solve the Golomb ruler problem with N marks */ void run_golomb(int* csp_dims) { int n = csp_dims[0]; unsigned int* mark; unsigned int* differences; unsigned long result; int i, j, d; // ruler variables mark = malloc((unsigned int)n * sizeof(unsigned int)); // vector with the ID of the variables constrained with all_diff differences = malloc((unsigned int)n * ((unsigned int)n - 1) / 2 * sizeof(unsigned int)); // Create the Golomb ruler main variables and lt constraint mark[1] = v_new_range(1, (unsigned int)n * (unsigned int)n, true); for (i = 2; i < n; i++) { mark[i] = v_new_range(0, (unsigned int)n * (unsigned int)n, true); } // for optimization c_minimize(mark[n - 1]); for (i = 1; i < n - 1; i++) { c_lt(mark[i], mark[i + 1]); } // Create the triangle of differences variables and its c_var_eq_minus constraints j = 0; for (d = 1; d < n; d++) { differences[j++] = mark[d]; for (i = d + 1; i < n; i++) { differences[j] = v_new_range(0, (unsigned int)n * (unsigned int)n, false); c_var_eq_minus(differences[j++], mark[i], mark[i - d]); } } mark[0] = v_new_val(0); c_fake_all_different(differences, (unsigned int)n * ((unsigned int)n - 1) / 2); // Symmetry breaking c_lt(differences[0], differences[n * (n - 1) / 2 - 1]); if (OPTIMIZING) { printf("Optimizing one solution for Golomb Ruler with %u marks.\n", n); } else if (FINDING_ONE_SOLUTION) { printf("\nFinding one solution for Golomb Ruler with %u marks.\n", n); } else { printf("\nCounting all the solutions for Golomb Ruler with %u marks.\n", n); } // Solve the CSP result = solve_CSP(); if (OPTIMIZING && result == 1) { printf("Best solution:\n"); vs_print_single_val(mark, (unsigned int)n, 0); printf("\n"); v_print_cost(0); } else if (FINDING_ONE_SOLUTION && result == 1) { printf("Solution:\n"); vs_print_single_val(mark, (unsigned int)n, 0); printf("\n"); } else { printf("%lu solution(s) found\n", result); } free(differences); free(mark); }