Skip to content

Commit

Permalink
Made all SolverUtils functions static
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Jan 5, 2024
1 parent 10d801d commit aabc692
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 75 deletions.
25 changes: 12 additions & 13 deletions src/main/java/de/nqueensfaf/impl/CPUSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import de.nqueensfaf.Solver;
import de.nqueensfaf.persistence.SolverState;

import static de.nqueensfaf.impl.SolverUtils.*;

public class CPUSolver extends Solver {

// for very small n it is overkill to use this method
Expand All @@ -41,11 +43,9 @@ public class CPUSolver extends Solver {
private boolean loaded;

private CPUSolverConfig config;
private SolverUtils utils;

public CPUSolver() {
config = new CPUSolverConfig();
utils = new SolverUtils();
ijklList = new HashSet<Integer>();
constellations = new ArrayList<Constellation>();
threads = new ArrayList<CPUSolverThread>();
Expand All @@ -62,7 +62,6 @@ protected void run() {
return;
}

utils.setN(n);
if (!loaded) {
genConstellations();
}
Expand All @@ -83,7 +82,7 @@ protected void run() {
// start the threads and wait until they are all finished
ExecutorService executor = Executors.newFixedThreadPool(config.threadcount);
for (i = 0; i < config.threadcount; i++) {
CPUSolverThread cpuSolverThread = new CPUSolverThread(utils, n, threadConstellations.get(i));
CPUSolverThread cpuSolverThread = new CPUSolverThread(n, threadConstellations.get(i));
threads.add(cpuSolverThread);
executor.submit(cpuSolverThread);
}
Expand Down Expand Up @@ -196,10 +195,10 @@ private void genConstellations() {
if (j == i || l == j)
continue;

if (!utils.checkRotations(ijklList, i, j, k, l)) { // if no rotation-symmetric starting
if (!checkRotations(n, ijklList, i, j, k, l)) { // if no rotation-symmetric starting
// constellation already
// found
ijklList.add(utils.toijkl(i, j, k, l));
ijklList.add(toIjkl(i, j, k, l));
}
}
}
Expand All @@ -209,24 +208,24 @@ private void genConstellations() {
// (0,0)
for (int j = 1; j < n - 2; j++) { // j is idx of Queen in last row
for (int l = j + 1; l < n - 1; l++) { // l is idx of Queen in last col
ijklList.add(utils.toijkl(0, j, 0, l));
ijklList.add(toIjkl(0, j, 0, l));
}
}

HashSet<Integer> ijklListJasmin = new HashSet<Integer>();
// rotate and mirror all start constellations, such that the queen in the last
// row is as close to the right border as possible
for (int startConstellation : ijklList) {
ijklListJasmin.add(utils.jasmin(startConstellation));
ijklListJasmin.add(jasmin(n, startConstellation));
}
ijklList = ijklListJasmin;

int i, j, k, l, ld, rd, col, currentSize = 0;
for (int sc : ijklList) {
i = utils.geti(sc);
j = utils.getj(sc);
k = utils.getk(sc);
l = utils.getl(sc);
i = geti(sc);
j = getj(sc);
k = getk(sc);
l = getl(sc);
// fill up the board with preQueens queens and generate corresponding variables
// ld, rd, col, start_queens_ijkl for each constellation
// occupy the board corresponding to the queens on the borders of the board
Expand All @@ -247,7 +246,7 @@ private void genConstellations() {
// jkl and sym and start are the same for all subconstellations
for (int a = 0; a < counter; a++) {
constellations.get(currentSize - a - 1)
.setStartIjkl(constellations.get(currentSize - a - 1).getStartIjkl() | utils.toijkl(i, j, k, l));
.setStartIjkl(constellations.get(currentSize - a - 1).getStartIjkl() | toIjkl(i, j, k, l));
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions src/main/java/de/nqueensfaf/impl/CPUSolverThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.ArrayList;

import static de.nqueensfaf.impl.SolverUtils.*;

class CPUSolverThread extends Thread {

private final int n, n3, n4, L, L3, L4; // boardsize
Expand All @@ -16,18 +18,15 @@ class CPUSolverThread extends Thread {

// list of uncalculated starting positions, their indices
private ArrayList<Constellation> constellations;

private SolverUtils utils;

CPUSolverThread(SolverUtils utils, int n, ArrayList<Constellation> constellations) {
CPUSolverThread(int n, ArrayList<Constellation> constellations) {
this.n = n;
n3 = n - 3;
n4 = n - 4;
L = 1 << (n - 1);
L3 = 1 << n3;
L4 = 1 << n4;
this.constellations = constellations;
this.utils = utils;
}

// Recursive functions for Placing the Queens
Expand Down Expand Up @@ -775,9 +774,9 @@ public void run() {
startIjkl = constellation.getStartIjkl();
start = startIjkl >> 20;
ijkl = startIjkl & ((1 << 20) - 1);
j = utils.getj(ijkl);
k = utils.getk(ijkl);
l = utils.getl(ijkl);
j = getj(ijkl);
k = getk(ijkl);
l = getl(ijkl);

// IMPORTANT NOTE: we shift ld and rd one to the right, because the right
// column does not matter (always occupied by queen l)
Expand Down Expand Up @@ -1059,7 +1058,7 @@ else if (j == n - 2) {
}

// for saving and loading progress remove the finished starting constellation
constellation.setSolutions(tempcounter * utils.symmetry(ijkl));
constellation.setSolutions(tempcounter * symmetry(n, ijkl));
tempcounter = 0;
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/de/nqueensfaf/impl/GPUSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import static de.nqueensfaf.impl.SolverUtils.*;
import static de.nqueensfaf.impl.InfoUtil.*;
import static org.lwjgl.opencl.CL12.*;
import static org.lwjgl.system.MemoryStack.*;
Expand All @@ -55,11 +56,9 @@ public class GPUSolver extends Solver {
private boolean loaded;

private GPUSolverConfig config;
private SolverUtils utils;

public GPUSolver() {
config = new GPUSolverConfig();
utils = new SolverUtils();
devices = new ArrayList<Device>();
availableDevices = new ArrayList<Device>();
constellations = new ArrayList<Constellation>();
Expand Down Expand Up @@ -87,7 +86,6 @@ protected void run() {
throw new IllegalStateException("no devices selected");

try (MemoryStack stack = stackPush()) {
utils.setN(n);
if (!loaded)
genConstellations(); // generate constellations
var remainingConstellations = constellations.stream().filter(c -> c.getSolutions() < 0)
Expand Down Expand Up @@ -203,7 +201,7 @@ void sortConstellations(List<Constellation> constellations) {
public int compare(Constellation o1, Constellation o2) {
int o1ijkl = o1.getStartIjkl() & ((1 << 20) - 1);
int o2ijkl = o2.getStartIjkl() & ((1 << 20) - 1);
return Integer.compare(utils.getjkl(o1ijkl), utils.getjkl(o2ijkl));
return Integer.compare(getJkl(o1ijkl), getJkl(o2ijkl));
}
});
}
Expand Down Expand Up @@ -441,7 +439,7 @@ private void readResults(Device device) {
if (device.workloadConstellations.get(i).getStartIjkl() >> 20 == 69) // start=69 is for trash constellations
continue;
long solutionsForConstellation = device.resPtr.getLong(i * 8)
* utils.symmetry(device.workloadConstellations.get(i).getStartIjkl() & 0b11111111111111111111);
* symmetry(n, device.workloadConstellations.get(i).getStartIjkl() & 0b11111111111111111111);
if (solutionsForConstellation >= 0)
// synchronize with the list of constellations on the RAM
device.workloadConstellations.get(i).setSolutions(solutionsForConstellation);
Expand Down
93 changes: 44 additions & 49 deletions src/main/java/de/nqueensfaf/impl/SolverUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,38 @@
import java.util.HashSet;

class SolverUtils {

private int n;

SolverUtils() {
// functions for ijkl manipulation
static int toIjkl(int i, int j, int k, int l) {
return (i << 15) + (j << 10) + (k << 5) + l;
}

static int geti(int ijkl) {
return ijkl >> 15;
}

static int getj(int ijkl) {
return (ijkl >> 10) & 31;
}

static int getk(int ijkl) {
return (ijkl >> 5) & 31;
}

static int getl(int ijkl) {
return ijkl & 31;
}

void setN(int n) {
this.n = n;
static int getJkl(int ijkl) {
return ijkl & 0b111111111111111;
}

static boolean oneQueenInCorner(int n, int ijkl) {
return getj(ijkl) == n-1 && getl(ijkl) == n-1;
}

// true, if starting constellation rotated by any angle has already been found
boolean checkRotations(HashSet<Integer> ijklList, int i, int j, int k, int l) {
static boolean checkRotations(int n, HashSet<Integer> ijklList, int i, int j, int k, int l) {
// rot90
if (ijklList.contains(((n - 1 - k) << 15) + ((n - 1 - l) << 10) + (j << 5) + i))
return true;
Expand All @@ -30,34 +50,9 @@ boolean checkRotations(HashSet<Integer> ijklList, int i, int j, int k, int l) {
return false;
}

// i, j, k, l to ijkl and functions to get specific entry
int toijkl(int i, int j, int k, int l) {
return (i << 15) + (j << 10) + (k << 5) + l;
}

int geti(int ijkl) {
return ijkl >> 15;
}

int getj(int ijkl) {
return (ijkl >> 10) & 31;
}

int getk(int ijkl) {
return (ijkl >> 5) & 31;
}

int getl(int ijkl) {
return ijkl & 31;
}

int getjkl(int ijkl) {
return ijkl & 0b111111111111111;
}

// rotate and mirror board, so that the queen closest to a corner is on the
// right side of the last row
int jasmin(int ijkl) {
static int jasmin(int n, int ijkl) {
int min = Math.min(getj(ijkl), n - 1 - getj(ijkl)), arg = 0;

if (Math.min(geti(ijkl), n - 1 - geti(ijkl)) < min) {
Expand All @@ -74,43 +69,43 @@ int jasmin(int ijkl) {
}

for (int i = 0; i < arg; i++) {
ijkl = rot90(ijkl);
ijkl = rot90(n, ijkl);
}

if (getj(ijkl) < n - 1 - getj(ijkl))
ijkl = mirvert(ijkl);
ijkl = mirvert(n, ijkl);

return ijkl;
}

// mirror left-right
int mirvert(int ijkl) {
return toijkl(n - 1 - geti(ijkl), n - 1 - getj(ijkl), getl(ijkl), getk(ijkl));
private static int mirvert(int n, int ijkl) {
return toIjkl(n - 1 - geti(ijkl), n - 1 - getj(ijkl), getl(ijkl), getk(ijkl));
}

// rotate 90 degrees clockwise
int rot90(int ijkl) {
private static int rot90(int n, int ijkl) {
return ((n - 1 - getk(ijkl)) << 15) + ((n - 1 - getl(ijkl)) << 10) + (getj(ijkl) << 5) + geti(ijkl);
}

// helper functions for doing the math
// for symmetry stuff and working with ijkl
// true, if starting constellation is symmetric for rot90
boolean symmetry90(int ijkl) {
if (((geti(ijkl) << 15) + (getj(ijkl) << 10) + (getk(ijkl) << 5) + getl(ijkl)) == (((n - 1 - getk(ijkl)) << 15)
+ ((n - 1 - getl(ijkl)) << 10) + (getj(ijkl) << 5) + geti(ijkl)))
return true;
return false;
}

// how often does a found solution count for this start constellation
int symmetry(int ijkl) {
static int symmetry(int n, int ijkl) {
if (geti(ijkl) == n - 1 - getj(ijkl) && getk(ijkl) == n - 1 - getl(ijkl)) // starting constellation symmetric by rot180?
if (symmetry90(ijkl)) // even by rot90?
if (symmetry90(n, ijkl)) // even by rot90?
return 2;
else
return 4;
else
return 8; // none of the above?
}

// helper functions for doing the math
// for symmetry stuff and working with ijkl
// true, if starting constellation is symmetric for rot90
private static boolean symmetry90(int n, int ijkl) {
if (((geti(ijkl) << 15) + (getj(ijkl) << 10) + (getk(ijkl) << 5) + getl(ijkl)) == (((n - 1 - getk(ijkl)) << 15)
+ ((n - 1 - getl(ijkl)) << 10) + (getj(ijkl) << 5) + geti(ijkl)))
return true;
return false;
}
}

0 comments on commit aabc692

Please sign in to comment.