introduce bitloops

This commit is contained in:
mike
2026-01-19 20:45:28 +01:00
parent 5d186ae0ba
commit 5678af332e
20 changed files with 111 additions and 1005 deletions

View File

@@ -1,28 +1,25 @@
package puzzle;
import module java.base;
import lombok.AllArgsConstructor;
import lombok.val;
import precomp.Neighbors9x8;
import precomp.Neighbors9x8.rci;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
import static java.lang.Long.*;
import static puzzle.SwedishGenerator.*;
public final class Masker {
public static final rci[] IT = Neighbors9x8.IT;
private final Rng rng;
private final int[] stack;
private final Clues cache;
private final int[] activeCIdx = new int[SwedishGenerator.SIZE];
private final long[] activeSLo = new long[SwedishGenerator.SIZE];
private final long[] activeSHi = new long[SwedishGenerator.SIZE];
private final long[] adjLo = new long[SwedishGenerator.SIZE];
private final long[] adjHi = new long[SwedishGenerator.SIZE];
public static final rci[] IT = Neighbors9x8.IT;
private final Rng rng;
private final int[] stack;
private final Clues cache;
private final int[] activeCIdx = new int[SwedishGenerator.SIZE];
private final long[] activeSLo = new long[SwedishGenerator.SIZE];
private final long[] activeSHi = new long[SwedishGenerator.SIZE];
private final long[] adjLo = new long[SwedishGenerator.SIZE];
private final long[] adjHi = new long[SwedishGenerator.SIZE];
public Masker(Rng rng, int[] stack, Clues cache) {
this.rng = rng;
@@ -41,7 +38,7 @@ public final class Masker {
for (int dc2 = -2; dc2 <= 2; dc2++) {
val ti = IT[i];
MUTATE_RI[i][k++] = offset(clamp(ti.r() + dr1 + dr2, 0, R - 1),
clamp(ti.c() + dc1 + dc2, 0, C - 1));
clamp(ti.c() + dc1 + dc2, 0, C - 1));
}
}
}
@@ -477,50 +474,55 @@ public final class Masker {
}
}
if (Main.VERBOSE) System.out.println("generateMask init pop: " + popSize + " clueSize: " + clueSize);
var pop = new ArrayList<GridAndFit>();
for (var i = 0; i < popSize; i++) {
GridAndFit[] pop = new GridAndFit[popSize];
for (int i = 0; i < popSize; i++) {
if (Thread.currentThread().isInterrupted()) return null;
pop.add(new GridAndFit(hillclimb(randomMask(clueSize), clueSize, 180)));
pop[i] = new GridAndFit(hillclimb(randomMask(clueSize), clueSize, 180));
}
for (var gen = 0; gen < gens; gen++) {
for (int gen = 0; gen < gens; gen++) {
if (Thread.currentThread().isInterrupted()) break;
var children = new ArrayList<GridAndFit>();
for (var k = 0; k < offspring; k++) {
GridAndFit[] children = new GridAndFit[offspring];
int childCount = 0;
for (int k = 0; k < offspring; k++) {
if (Thread.currentThread().isInterrupted()) break;
var p1 = rng.rand(pop);
var p2 = rng.rand(pop);
var child = crossover(p1.grid, p2.grid);
children.add(new GridAndFit(hillclimb(child, clueSize, 70)));
GridAndFit p1 = rng.rand(pop);
GridAndFit p2 = rng.rand(pop);
Clues child = crossover(p1.grid, p2.grid);
children[k] = new GridAndFit(hillclimb(child, clueSize, 70));
childCount++;
}
pop.addAll(children);
pop.sort(Comparator.comparingLong(GridAndFit::fit));
GridAndFit[] combined = new GridAndFit[pop.length + childCount];
System.arraycopy(pop, 0, combined, 0, pop.length);
System.arraycopy(children, 0, combined, pop.length, childCount);
Arrays.sort(combined, Comparator.comparingLong(GridAndFit::fit));
var next = new ArrayList<GridAndFit>();
for (var cand : pop) {
if (next.size() >= offspring) break;
var ok = true;
for (var kept : next)
if (cand.grid.similarity(kept.grid) > 0.92) {
GridAndFit[] next = new GridAndFit[offspring];
int nextCount = 0;
for (GridAndFit cand : combined) {
if (nextCount >= offspring) break;
boolean ok = true;
for (int i = 0; i < nextCount; i++)
if (cand.grid.similarity(next[i].grid) > 0.92) {
ok = false;
break;
}
if (ok) next.add(cand);
if (ok) next[nextCount++] = cand;
}
pop = next;
pop = nextCount == offspring ? next : Arrays.copyOf(next, nextCount);
if (Main.VERBOSE && (gen & 15) == 15) System.out.println(" gen " + gen + "/" + gens + " bestFitness=" + pop.get(0).fit());
if (Main.VERBOSE && (gen & 15) == 15) System.out.println(" gen " + gen + "/" + gens + " bestFitness=" + pop[0].fit());
}
if (pop.isEmpty()) return null;
GridAndFit best = pop.get(0);
for (int i = 1; i < pop.size(); i++) {
var x = pop.get(i);
if (pop.length == 0) return null;
GridAndFit best = pop[0];
for (int i = 1; i < pop.length; i++) {
GridAndFit x = pop[i];
if (x.fit() < best.fit()) best = x;
}
return best.grid;
}//@formatter:off
}
//@formatter:off
@FunctionalInterface public interface SlotVisitor { void visit(int key, long lo, long hi); }
//@formatter:on
@AllArgsConstructor