X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=main.c;h=08bf5cb6ff524caf3fc84a62fc5e113bdc5d86f9;hb=9688636f9bc864be40bed86422617adde2805fe8;hp=b7aae53e43007901eb4a547a2d52a188eb61efc2;hpb=eee0048ef0047180eefb8407e4e441e59fd902b9;p=matchsticks-search.git diff --git a/main.c b/main.c index b7aae53..08bf5cb 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 */ /* @@ -58,7 +64,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 +83,18 @@ * 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 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 * to have low hamming weight, and having found a reasonable solution @@ -128,9 +142,13 @@ 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; + n_max_frags = ceil(n / near_best) - 1; + m_max_frags = ceil(m / near_best) - 1; } /*----- multicore support -----*/ @@ -618,6 +636,10 @@ static void iterate_recurse(int i, AdjWord min) { AdjWord jbit; if (i >= n) { + for (j=0; j= 0) { switch (opt) { case 'j': ncpus = atoi(optarg); break; + case 'b': set_best(atof(optarg)); break; case '+': assert(!"bad option"); default: abort(); } @@ -707,6 +738,7 @@ int main(int argc, char **argv) { assert(argc==3); n = atoi(argv[1]); m = atoi(argv[2]); + assert(n > m); prep();