#include <unistd.h>
#include <stdbool.h>
#include <inttypes.h>
+#include <math.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <glpk.h>
+#ifndef VERSION
+#define VERSION "(unknown-version)"
+#endif
+
/*
* Algorithm.
*
static glp_prob *best_prob;
static AdjWord *best_adjmatrix;
+static int n_over_best;
+static int *weight;
+
static unsigned printcounter;
static void iterate(void);
static void set_best(double new_best) {
best = new_best;
+ n_over_best = floor(n / best);
}
/*----- multicore support -----*/
pid_t pid;
} Worker;
static Worker *mc_us;
+static bool mc_am_generator;
static void multicore_check_for_new_best(void);
-#define MAX_NIOVS 3
+#define MAX_NIOVS 4
static AdjWord mc_iter_min;
static int mc_niovs;
static size_t mc_iovlen;
IOV(maxhamweight, 1);
IOV(mc_iter_min, 1);
IOV(*adjmatrix, multicore_iteration_boundary);
+ IOV(*weight, m);
}
static void mc_rwvsetup_full(void) {
iterate_recurse(mc_org_it_bound, mc_iter_min);
multicore_iteration_boundary = mc_org_it_bound;
}
- LPRINTF("worker %2d reporting",mc_us->w);
if (best_adjmatrix) {
+ LPRINTF("worker %2d reporting",mc_us->w);
adjmatrix = best_adjmatrix;
mc_rwvsetup_full();
ssize_t r = writev(fileno(mc_us->results), mc_iov, mc_niovs);
genpid = fork(); assert(genpid >= 0);
if (!genpid) {
+ mc_am_generator = 1;
LPRINTF("generator running");
iterate();
exit(0);
LPRINTF("reading report from %2d",w);
ssize_t sr = preadv(fileno(mc_workers[w].results), mc_iov, mc_niovs, 0);
if (!sr) continue;
+ LPRINTF("got report from %2d",w);
maxhamweight = 0;
optimise(1);
}
}
static void multicore_check_for_new_best(void) {
- if (!ncpus) return;
+ if (!(mc_us || mc_am_generator))
+ return;
for (;;) {
double msg;
}
static void multicore_found_new_best(void) {
- if (!ncpus) return;
+ if (!mc_us)
+ return;
if (mc_us /* might be master */) fprintf(stderr," w%-2d ",mc_us->w);
ssize_t wrote = write(mc_bus, &best, sizeof(best));
adjmatrix = xalloc_adjmatrix();
glp_term_out(GLP_OFF);
setlinebuf(stderr);
+ weight = calloc(sizeof(*weight), m); assert(weight);
+ n_over_best = INT_MAX;
}
static AdjWord one_adj_bit(int bitnum) {
if (i == 0 && (adjmatrix[i] & (1+adjmatrix[i])))
goto again;
+ for (int j = 0; j < m; j++)
+ if (adjmatrix[i] & one_adj_bit(j))
+ weight[j]++;
+ for (int j = 0; j < m; j++)
+ if (weight[j] >= n_over_best)
+ goto takeout;
+
iterate_recurse(i+1, adjmatrix[i]);
+ takeout:
+ for (int j = 0; j < m; j++)
+ if (adjmatrix[i] & one_adj_bit(j))
+ weight[j]--;
+
again:
if (adjmatrix[i] == adjall)
return;
continue;
a[x][y] = min + glp_get_col_prim(best_prob, i);
}
- printf("%d into %d: min fragment %g\n", n, m, min);
+ printf("%d into %d: min fragment %g [%s]\n", n, m, min, VERSION);
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (a[i][j])