X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=main.c;h=3ee58c59760729eba27ae8b88123caa59d9062b0;hb=2b68e0812cdf71031274fe1883a8857479a390a0;hp=57a979654f705bd01912fe773cd01668a92ddb07;hpb=b6c1176e49824e8e043ece399fb94d6bb93617a7;p=matchsticks-search.git diff --git a/main.c b/main.c index 57a9796..3ee58c5 100644 --- a/main.c +++ b/main.c @@ -5,7 +5,13 @@ * * Invoke as ./main n m * - * The algorithm is faster if the arguments are ordered so that n > m. + * The arguments must be ordered so that n > m: + * n is the number of (more, shorter) input matches of length m + * m is the number of (fewer, longer) output matches of length n + * + * Options: + * -j run in parallel on cores + * -b search only for better than */ /* @@ -84,7 +90,10 @@ * * 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). + * (ie, as above, only considering output sticks); and by ensuring + * that it is not set in too few: each output stick must consist + * of at least two fragments since the output sticks are longer than + * the input ones. * * And, we want to do the search in order of increasing maximum * hamming weight. This is because in practice optimal solutions tend @@ -106,7 +115,7 @@ static double best; static glp_prob *best_prob; static AdjWord *best_adjmatrix; -static int n_max_frags, m_max_frags; +static int n_max_frags=INT_MAX, m_max_frags=INT_MAX; static int *weight; static unsigned printcounter; @@ -133,9 +142,15 @@ static void set_best(double new_best) { * <=> frags < | n / best | * _ _ * <=> frags <= | n / best | - 1 + * + * But best values from glpk are slightly approximate, so we + * subtract a fudge factor from our target. */ - n_max_frags = ceil(n / best) - 1; - m_max_frags = ceil(m / best) - 1; + double near_best = best * 0.98 - 0.02; + if (near_best > 0) { + n_max_frags = ceil(n / near_best) - 1; + m_max_frags = ceil(m / near_best) - 1; + } } /*----- multicore support -----*/ @@ -250,6 +265,8 @@ static void multicore_outer_iteration(int i, AdjWord min) { } static void mc_iterate_worker(void) { + static time_t lastprint; + for (;;) { mc_rwvsetup_outer(); ssize_t r = readv(mc_work[0], mc_iov, mc_niovs); @@ -259,8 +276,12 @@ static void mc_iterate_worker(void) { bool ok = maxhamweight_ok(); if (!ok) continue; - ok = preconsider_ok(multicore_iteration_boundary, 1); - progress_eol(); + time_t now = time(0); + bool doprint = now != lastprint; + lastprint = now; + + ok = preconsider_ok(multicore_iteration_boundary, doprint); + if (doprint) progress_eol(); if (!ok) continue; /* stop iterate_recurse from trying to run multicore_outer_iteration */ @@ -371,8 +392,6 @@ static void prep(void) { glp_term_out(GLP_OFF); setlinebuf(stderr); weight = calloc(sizeof(*weight), m); assert(weight); - n_max_frags = INT_MAX; - m_max_frags = INT_MAX; } #if 0 @@ -623,6 +642,10 @@ static void iterate_recurse(int i, AdjWord min) { AdjWord jbit; if (i >= n) { + for (j=0; j= n_max_frags) + if (weight[j] > n_max_frags) goto takeout; iterate_recurse(i+1, adjmatrix[i]); @@ -670,6 +693,14 @@ static void iterate(void) { static void report(void) { fprintf(stderr, "\n"); + if (best_adjmatrix) { + int i; + fprintf(stderr," "); + for (i=0; i= 0) { + double best_to_set = -1.0; /* means 'don't' */ + while ((opt = getopt(argc,argv,"j:b:")) >= 0) { switch (opt) { case 'j': ncpus = atoi(optarg); break; + case 'b': best_to_set = atof(optarg); break; case '+': assert(!"bad option"); default: abort(); } @@ -712,6 +747,8 @@ int main(int argc, char **argv) { assert(argc==3); n = atoi(argv[1]); m = atoi(argv[2]); + assert(n > m); + if (best_to_set > 0) set_best(best_to_set); prep();