Gather data

This commit is contained in:
mike
2026-01-10 02:36:41 +01:00
parent 7cd40c90be
commit 84d7bea32e
2 changed files with 135 additions and 135 deletions

View File

@@ -341,7 +341,7 @@ public class Main {
TOTAL_ATTEMPTS.incrementAndGet(); TOTAL_ATTEMPTS.incrementAndGet();
var swe = new SwedishGenerator(rng); var swe = new SwedishGenerator(rng);
var mask = swe.generateMask(opts.pop, opts.gens); var mask = swe.generateMask(opts.pop, opts.gens);
var filled = new CSP(rng).fillMask(mask, dict.index(), opts.fillTimeout); var filled = swe.fillMask(mask, dict.index(), opts.fillTimeout);
TOTAL_NODES.addAndGet(filled.stats().nodes); TOTAL_NODES.addAndGet(filled.stats().nodes);
TOTAL_BACKTRACKS.addAndGet(filled.stats().backtracks); TOTAL_BACKTRACKS.addAndGet(filled.stats().backtracks);

View File

@@ -379,7 +379,7 @@ public record SwedishGenerator(Rng rng) {
Arrays.fill(covH, 0, SIZE, 0); Arrays.fill(covH, 0, SIZE, 0);
Arrays.fill(covV, 0, SIZE, 0); Arrays.fill(covV, 0, SIZE, 0);
boolean[] hasSlots = { false }; boolean hasSlots = false;
long lo_cl = grid.bo[0], hi_cl = grid.bo[1]; long lo_cl = grid.bo[0], hi_cl = grid.bo[1];
while (lo_cl != 0) { while (lo_cl != 0) {
int clueIdx = Long.numberOfTrailingZeros(lo_cl); int clueIdx = Long.numberOfTrailingZeros(lo_cl);
@@ -400,12 +400,10 @@ public record SwedishGenerator(Rng rng) {
cc += nbrs16.dc(); cc += nbrs16.dc();
} }
if (n == 0) continue; if (n == 0) continue;
hasSlots[0] = true; hasSlots = true;
if (n < MIN_LEN) { if (n < MIN_LEN) {
penalty[0] += 8000; penalty[0] += 8000;
} /*else if (lenCounts[n] <= 0) { }
penalty[0] += 12000;
}*/
var horiz = Slot.horiz(d) ? covH : covV; var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1; for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
} }
@@ -428,17 +426,15 @@ public record SwedishGenerator(Rng rng) {
cc += nbrs16.dc(); cc += nbrs16.dc();
} }
if (n == 0) continue; if (n == 0) continue;
hasSlots[0] = true; hasSlots = true;
if (n < MIN_LEN) { if (n < MIN_LEN) {
penalty[0] += 8000; penalty[0] += 8000;
} /*else if (lenCounts[n] <= 0) { }
penalty[0] += 12000;
}*/
var horiz = Slot.horiz(d) ? covH : covV; var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1; for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
} }
if (!hasSlots[0]) return 1_000_000_000L; if (!hasSlots) return 1_000_000_000L;
int idx, h, v; int idx, h, v;
for (idx = 0; idx < SIZE; idx++) { for (idx = 0; idx < SIZE; idx++) {
@@ -480,8 +476,19 @@ public record SwedishGenerator(Rng rng) {
if (size >= 2) penalty[0] += (size - 1L) * 120L; if (size >= 2) penalty[0] += (size - 1L) * 120L;
}); });
int walls;
// dead-end-ish letter cell (3+ walls) // dead-end-ish letter cell (3+ walls)
int walls, wc, wr;
/*for (var rci : IT) {
if (grid.isDigitAt(rci.i())) continue;
walls = 0;
for (var d : nbrs4) {
wr = rci.r() + d.r();
wc = rci.c() + d.c();
if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(wr, wc)) walls++;
}
if (walls >= 3) penalty[0] += 400;
}*/
for (var rci : IT) { for (var rci : IT) {
if (grid.isDigitAt(rci.i())) continue; if (grid.isDigitAt(rci.i())) continue;
walls = (4 - rci.nbrCount()) + Long.bitCount(rci.n1() & grid.bo[0]) + Long.bitCount(rci.n2() & grid.bo[1]); walls = (4 - rci.nbrCount()) + Long.bitCount(rci.n1() & grid.bo[0]) + Long.bitCount(rci.n2() & grid.bo[1]);
@@ -691,33 +698,31 @@ public record SwedishGenerator(Rng rng) {
return new CandidateInfo(in, curLen); return new CandidateInfo(in, curLen);
} }
record CSP(Rng rng) {
public FillResult fillMask(Grid mask, DictEntry[] dictIndex, public FillResult fillMask(Grid mask, DictEntry[] dictIndex,
int timeLimitMs) { int timeLimitMs) {
boolean multiThreaded = Thread.currentThread().getName().contains("pool"); val multiThreaded = Thread.currentThread().getName().contains("pool");
var grid = mask.deepCopyGrid(); val grid = mask.deepCopyGrid();
var slots = extractSlots(grid); val used = new Bit1029();
val assigned = new HashMap<Integer, Lemma>();
var used = new Bit1029(); val ctx = CTX.get();
var assigned = new HashMap<Integer, Lemma>(); val count = ctx.cellCount;
var ctx = CTX.get();
var count = ctx.cellCount;
Arrays.fill(count, 0, SIZE, 0); Arrays.fill(count, 0, SIZE, 0);
val slots = extractSlots(grid);
for (var s : slots) for (int i = 0, len = s.len(); i < len; i++) count[s.pos(i)]++; for (var s : slots) for (int i = 0, len = s.len(); i < len; i++) count[s.pos(i)]++;
var t0 = System.currentTimeMillis(); val t0 = System.currentTimeMillis();
final var lastLog = new AtomicLong(t0); val stats = new FillStats();
val TOTAL = slots.size();
var stats = new FillStats(); class Solver {
final var TOTAL = slots.size();
Runnable renderProgress = () -> { long lastLog = t0;
void renderProgress() {
if (!Main.VERBOSE || multiThreaded) return; if (!Main.VERBOSE || multiThreaded) return;
var now = System.currentTimeMillis(); var now = System.currentTimeMillis();
if ((now - lastLog.get()) < LOG_EVERY_MS) return; if ((now - lastLog) < LOG_EVERY_MS) return;
lastLog.set(now); lastLog = (now);
var done = assigned.size(); var done = assigned.size();
var pct = (TOTAL == 0) ? 100 : (int) Math.floor((done / (double) TOTAL) * 100); var pct = (TOTAL == 0) ? 100 : (int) Math.floor((done / (double) TOTAL) * 100);
@@ -732,9 +737,8 @@ public record SwedishGenerator(Rng rng) {
); );
System.out.print("\r" + Strings.padRight(msg, 120)); System.out.print("\r" + Strings.padRight(msg, 120));
System.out.flush(); System.out.flush();
}; }
Pick chooseMRV() {
Supplier<Pick> chooseMRV = () -> {
Slot best = null; Slot best = null;
CandidateInfo bestInfo = null; CandidateInfo bestInfo = null;
int bestSlot = -1; int bestSlot = -1;
@@ -766,17 +770,14 @@ public record SwedishGenerator(Rng rng) {
} else { } else {
return new Pick(best, bestInfo, false); return new Pick(best, bestInfo, false);
} }
}; }
class Solver {
boolean backtrack(int depth) { boolean backtrack(int depth) {
if (Thread.currentThread().isInterrupted()) return false; if (Thread.currentThread().isInterrupted()) return false;
stats.nodes++; stats.nodes++;
if (timeLimitMs > 0 && (System.currentTimeMillis() - t0) > timeLimitMs) return false; if (timeLimitMs > 0 && (System.currentTimeMillis() - t0) > timeLimitMs) return false;
var pick = chooseMRV.get(); var pick = chooseMRV();
if (pick.done) return true; if (pick.done) return true;
if (pick.slot == null) { if (pick.slot == null) {
stats.backtracks++; stats.backtracks++;
@@ -784,7 +785,7 @@ public record SwedishGenerator(Rng rng) {
} }
val info = pick.info; val info = pick.info;
stats.lastMRV = info.count; stats.lastMRV = info.count;
renderProgress.run(); renderProgress();
var s = pick.slot; var s = pick.slot;
var k = s.key(); var k = s.key();
@@ -867,8 +868,9 @@ public record SwedishGenerator(Rng rng) {
} }
// initial render (same feel) // initial render (same feel)
renderProgress.run(); var solver = new Solver();
var ok = new Solver().backtrack(0); solver.renderProgress();
var ok = solver.backtrack(0);
// final progress line // final progress line
if (!multiThreaded) { if (!multiThreaded) {
System.out.print("\r" + Strings.padRight("", 120) + "\r"); System.out.print("\r" + Strings.padRight("", 120) + "\r");
@@ -891,5 +893,3 @@ public record SwedishGenerator(Rng rng) {
return res; return res;
} }
} }
}