今天看啦一下拉斯×××算法,然后结合回溯,一起运用到n皇后问题上,发现比较起来,时间效率确实很ok。
package test; import java.util.Random; public class NQueen { public static void main(String[] args) { int size = 24; array = new int[size]; //单纯使用lv算法 long startTime = System.currentTimeMillis(); // 获取开始时间 while (!lv(size)) { } for (int a : array) { System.out.print(a + " "); } long endTime = System.currentTimeMillis(); // 获取结束时间 System.out.println("程序运行时间: " + (endTime - startTime) + "ms"); //单纯使用回溯法 startTime = System.currentTimeMillis(); drawBack(0); for (int a : array) { System.out.print(a + " "); } endTime = System.currentTimeMillis(); System.out.println("程序运行时间: " + (endTime - startTime) + "ms"); // lv和回溯一起使用 startTime = System.currentTimeMillis(); b = false; while (!lv(size / 2)) { } drawBack(size / 2); for (int a : array) { System.out.print(a + " "); } endTime = System.currentTimeMillis(); System.out.println("程序运行时间: " + (endTime - startTime) + "ms"); } private static int[] array; // 拉斯×××(Las Vegas)算法 public static boolean lv(int n) { Random random = new Random(); for (int a = 0; a < n; a++) { int count = 0; for (int b = 0; b < array.length; b++) { if (place(array, a, b)) { int k = random.nextInt(count + 1); if (k == count) { array[a] = b; } count++; } } if (count == 0) { return false; } } return true; } // b的值是使得一旦回溯得到最优解即中断搜索 private static boolean b = false; // 回溯算法 public static void drawBack(int level) { if (level == array.length) { b = true; return; } else { for (int n = 0; n < array.length && !b; n++) { if (place(array, level, n)) { array[level] = n; drawBack(level + 1); } } } } public static boolean place(int[] array, int level, int value) { for (int n = 0; n < level; n++) { if (array[n] == value || Math.abs(n - level) == Math.abs(value - array[n])) { return false; } } return true; } }
外加一条个人见解 : lv算法貌似必须知道最优解的情况下才能准确求出解。