X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=main.c;h=57a979654f705bd01912fe773cd01668a92ddb07;hb=7f7db5029057d9d6cfd74de0f464e1913cb80cff;hp=69f56d1a30e8bba421e9e7a7231019a45f08b09d;hpb=41013cb05383473c8ffdcf9afc89dde04760a847;p=matchsticks-search.git diff --git a/main.c b/main.c index 69f56d1..57a9796 100644 --- a/main.c +++ b/main.c @@ -58,7 +58,8 @@ * * We search all possible adjacency matrices, and for each one we run * GLPK's simplex solver. We represent the adjacency matrix as an - * array of bitmaps. + * array of bitmaps: one word per input stick, with one bit per output + * stick. * * However, there are a couple of wrinkles: * @@ -76,11 +77,15 @@ * nondecreasing in array order. * * Once we have a solution, we also avoid considering any candidate - * which involves dividing one of the output sticks into so many + * which involves dividing one of the input sticks into so many * fragment that the smallest fragment would necessarily be no bigger * than our best solution. That is, we reject candidates where any of * the hamming weights of the adjacency bitmap words are too large. * + * We further winnow the set of possible adjacency matrices, by + * ensuring the same bit is not set in too many entries of adjmatrix + * (ie, as above, only considering output sticks). + * * And, we want to do the search in order of increasing maximum * hamming weight. This is because in practice optimal solutions tend * to have low hamming weight, and having found a reasonable solution @@ -101,7 +106,7 @@ static double best; static glp_prob *best_prob; static AdjWord *best_adjmatrix; -static int n_over_best, m_over_best; +static int n_max_frags, m_max_frags; static int *weight; static unsigned printcounter; @@ -119,8 +124,18 @@ static void progress_eol(void) { static void set_best(double new_best) { best = new_best; - n_over_best = floor(n / best); - m_over_best = floor(m / best); + /* + * When computing n_max_frags, we want to set a value that will skip + * anything that won't provide strictly better solutions. So we + * want + * frags < n / best + * _ _ + * <=> frags < | n / best | + * _ _ + * <=> frags <= | n / best | - 1 + */ + n_max_frags = ceil(n / best) - 1; + m_max_frags = ceil(m / best) - 1; } /*----- multicore support -----*/ @@ -356,8 +371,8 @@ static void prep(void) { glp_term_out(GLP_OFF); setlinebuf(stderr); weight = calloc(sizeof(*weight), m); assert(weight); - n_over_best = INT_MAX; - m_over_best = INT_MAX; + n_max_frags = INT_MAX; + m_max_frags = INT_MAX; } #if 0 @@ -379,7 +394,7 @@ static int count_set_adj_bits(AdjWord w) { static int totalfrags; static bool maxhamweight_ok(void) { - return maxhamweight <= m_over_best; + return maxhamweight <= m_max_frags; } static bool preconsider_ok(int nwords, bool doprint) { @@ -391,7 +406,7 @@ static bool preconsider_ok(int nwords, bool doprint) { for (i=0, totalfrags=0; i m_over_best) { + if (frags > m_max_frags) { PRINTF(" too fine"); goto out; } @@ -502,7 +517,7 @@ static void optimise(bool doprint) { glp_set_obj_coef(prob, X_minimum, 1); for (i=0; i= n_over_best) + if (weight[j] >= n_max_frags) goto takeout; iterate_recurse(i+1, adjmatrix[i]);