八皇後問題 拉斯維加斯算法
阿新 • • 發佈:2018-08-31
class 效率 random 執行 不出 找不到 次循環 amp ati
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算法效率其實並不高,但是理論上存在比遍歷更快找到解的可能
八皇後問題 拉斯維加斯算法