1. 程式人生 > >八皇後問題 拉斯維加斯算法

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

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算法效率其實並不高,但是理論上存在比遍歷更快找到解的可能

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