/* Copyright 2014 Julia s.r.l. This file is part of BeeDeeDee. BeeDeeDee is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. BeeDeeDee is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with BeeDeeDee. If not, see <http://www.gnu.org/licenses/>. */ package com.juliasoft.beedeedee.examples.queens; import com.juliasoft.beedeedee.bdd.Assignment; import com.juliasoft.beedeedee.bdd.BDD; import com.juliasoft.beedeedee.factories.Factory; import com.juliasoft.julia.checkers.nullness.Inner0NonNull; import com.juliasoft.julia.checkers.nullness.Inner1NonNull; public class Queens { private static int N = 11; private static int utSize = 1000 * 1000; private static int cacheSize = 100000; private static @Inner0NonNull @Inner1NonNull BDD[][] X; /* BDD variable array */ public static void main(String[] args) { /* * override defaults */ if (args.length > 0) { N = Integer.parseInt(args[0]); } if (args.length > 1) { utSize = Integer.parseInt(args[1]); } if (args.length > 2) { cacheSize = Integer.parseInt(args[2]); } // Factory factory = Factory.mk(utSize, cacheSize); Factory factory = Factory.mkER(utSize, cacheSize); // Factory factory = new IntegrityCheckFactory(utSize, cacheSize, true); BDD queen = factory.makeOne(); int i, j; /* Build variable array */ System.out.println("Creating variables..."); X = new BDD[N][N]; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { X[i][j] = factory.makeVar(i * N + j); } } /* Place a queen in each row */ System.out.println("Adding row constraints..."); for (i = 0; i < N; i++) { BDD e = factory.makeZero(); for (j = 0; j < N; j++) { e.orWith(X[i][j].copy()); // 'or' with a copy } queen.andWith(e); } /* Build requirements for each variable(field) */ for (i = 0; i < N; i++) for (j = 0; j < N; j++) { System.out.print("Adding placement constraints for position " + i + "," + j + " \r"); BDD a = factory.makeOne(), b = factory.makeOne(), c = factory.makeOne(), d = factory.makeOne(); int k, l; /* No one in the same column */ for (l = 0; l < N; l++) { if (l != j) { BDD nand = X[i][l].nand(X[i][j]); a.andWith(nand); } } /* No one in the same row */ for (k = 0; k < N; k++) { if (k != i) { BDD nand = X[i][j].nand(X[k][j]); b.andWith(nand); } } /* No one in the same up-right diagonal */ for (k = 0; k < N; k++) { int ll = k - i + j; if (ll >= 0 && ll < N) { if (k != i) { BDD nand = X[i][j].nand(X[k][ll]); c.andWith(nand); } } } /* No one in the same down-right diagonal */ for (k = 0; k < N; k++) { int ll = i + j - k; if (ll >= 0 && ll < N) { if (k != i) { BDD nand = X[i][j].nand(X[k][ll]); d.andWith(nand); } } } c.andWith(d); b.andWith(c); a.andWith(b); queen.andWith(a); } System.out.println("\n\n" + factory.bddCount() + "\n\n"); //System.out.println(factory.toDot()); System.out.println('\n'); // System.out.println("\n" + queen + " " + factory.nodesCount()); factory.printStatistics(); long count = queen.satCount(); System.out.println("There are " + count + " solutions."); //factory.printUT(); if (count > -1234) { System.out.println("Finding a satisfying assignment...\n"); printAssignment(queen.anySat()); } /* System.out.println("Finding all assignments...\n"); for (Assignment a : queen.allSat()) { printAssignment(a); System.out.println(); } */ /* System.out.println("Replacing, worst case..."); Map<Integer, Integer> renaming = new HashMap<>(); for (j = N*N, i = j - 1; i >= 0; i--, j++) { renaming.put(i, j); } long start = System.currentTimeMillis(); queen.replace(renaming); System.out.println("Done, ms: " + (System.currentTimeMillis() - start)); System.out.println("Exist, all vars..."); BDD vars = factory.makeOne(); for (j = N*N; j < 2*N*N; j++) { vars.andWith(factory.makeVar(j)); } start = System.currentTimeMillis(); queen.exist(vars); factory.done(); Executors.shutdown(); System.out.println("Done, ms: " + (System.currentTimeMillis() - start));*/ factory.done(); } private static void printAssignment(Assignment assignment) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) System.out.print(" " + (assignment.holds(X[i][j]) ? 'Q' : '-')); System.out.println(); } } }