今天看啦一下拉斯×××算法,然后结合回溯,一起运用到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算法貌似必须知道最优解的情况下才能准确求出解。