八皇后問題 拉斯維加斯算法


Java

import java.util.Random;

public class LVQueen {

    // 問題規模
    static int SIZE = 8;
    // 隨機數發生器
    static Random rnd = new Random(SIZE);
    // 解向量
    static int[] queen = new int[SIZE];

    private static boolean check(int row) {
        for (int i = 0; i < queen.length && i != row; i++) {
            if (queen[i] == queen[row] || i - queen[i] == row - queen[row] || i + queen[i] == row + queen[row]) {
                return false;
            }
        }
        return true;
    }

    private static boolean queensLV() {
        int row = 0;
        int count = 1;
        while ((row < SIZE) && (count > 0)) {
            count = 0;
            int j = 0;
            for (int column = 0; column < SIZE; column++) {
                queen[row] = column;
                if (check(row)) {
                    if (rnd.nextInt(++count) == 0) {
                          j = column;
                        // break;//有break如果第一此找到合適的列place(k)滿足,那么此時random(1)==0恆成立,遇到下面的break,就把皇后放置在這個位置。如果這種放置皇后的方案不可行,下次循環還會執行同樣的,故一直循環調不出來找不到方案。即剩下的所有皇后放置不了的可能性增大。
                        // 沒有break,會一直試探for循環結束。x[k]會在隨機的選擇當前可以放置的位置中for循環最后一個滿足的列。那么后面如果n-1個皇后放置不了的可能性減小。
                    }
                }
            }
            if (count > 0) {
                queen[row++] = j;
            }
        }
        return (count > 0);
    }

    public static void nQueen() {
        while (!queensLV());
        System.out.println("-----解法--------");
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (queen[i] == j) {
                    System.out.print(" Q ");
                } else {
                    System.out.print(" . ");
                }
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        nQueen();
    }
}

總結一下它的思想,

就是從第一行開始,尋找可以放置的位置,顯然第一行七種擺法都是可以的,隨機抽取一種,擺上去

到第二行的時候,可以擺放的位置少了幾種,從這幾種里面又隨機取一種擺上去

如此循環,但顯然大概率擺放到后面的時候,會發現無解,所以才會有

while (!queensLV());

這么一行,知道碰運氣找到了解才結束。

它和之前的暴利遞歸算法不同之處在於

1.拉斯維加斯算法旨在尋找一個解而非全部解

2.由於不是有序遍歷,所以LV算法效率其實並不高,但是理論上存在比遍歷更快找到解的可能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM