八皇后問題

/*八皇后問題
* 描述:在一個8*8的棋盤格上面放置八個皇后,使得每個皇后不能互相攻擊
* 攻擊:不能位於同一列,同一行,和對角線上
* 分析:一共有八行八列,則每一行每一列只能有一個皇后
*/

     /*
     * 判斷給定的位置是否安全
     * 參數爲已經確定的點的數組,和要進行判斷的點的行和列座標
     */
     private static boolean safeLocation(int [] queues,int row,int col){
          for(int i =0 ; i <col ; i++){
               //判斷是否會攻擊
               if( (i == col) || (queues[i] == row) || ( (row+col) ==(i+queues[i]) ) || ( (queues[i]-i) == row-col ) ){
                    return false;
               }
          }
          return true;
     }//end safeLocation


     /*
     * 八皇后問題算法實現
     * 採用回溯的策略來實現,如果遞歸的過程中遇到錯誤,則返回上一層遞歸
     * 重新選擇上一步的位置
     */
     public boolean eightQueue(int[] queues,int col){
          int row;                              //記錄行數
          boolean foundLocation;    //標記遞歸是否可以得到正確的位置
          //結束遞歸調用條件,如果列數等於8則結束
          if(col == 8){
               foundLocation = true;
          }
          else{
               row = 0;
               foundLocation = false;
               //回溯算法如果,遞歸調用的子調用的結果爲false則返回該函數繼續判斷,
               //找到合適的點再次調用遞歸。
               while(row < 8 && foundLocation != true){
                    if(safeLocation(queues, row, col)){
                         queues[col] = row;
                         foundLocation = eightQueue(queues, col+1);
                         if(!foundLocation){
                              row++;
                         }
                    }
                    else{
                         row++;
                    }
               }
          }//end else
          return foundLocation;
     }//end eightQueue


     /*
     * 測試驅動
     * 指定初始的行數
     */
     public boolean startEightQueue(int queues[],int row){
          //指定第一列的初始行數
          queues[0] = row;
         
          if(eightQueue(queues, 1)){
               return true;
          }
          else{
               return false;
          }
         
     }//end  startEightQueue

<pre name="code" class="java">//完整實現



package 算法;

import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

import 排序.bubble;

/*八皇后問題
 * 描述:在一個8*8的棋盤格上面放置八個皇后,使得每個皇后不能互相攻擊
 * 攻擊:不能位於同一列,同一行,和對角線上
 * 分析:一共有八行八列,則每一行每一列只能有一個皇后
 */

public class EightQueue {
	
	/*
	 * 判斷給定的位置是否安全
	 * 參數爲已經確定的點的數組,和要進行判斷的點的行和列座標
	 */
	private static boolean safeLocation(int [] queues,int row,int col){
		for(int i =0 ; i <col ; i++){
			//判斷是否會攻擊
			if( (i == col) || (queues[i] == row) || ( (row+col) ==(i+queues[i]) ) || ( (queues[i]-i) == row-col ) ){
				return false;
			}
		}
		return true;
	}//end safeLocation
	
	
	/*
	 * 八皇后問題算法實現
	 * 採用回溯的策略來實現,如果遞歸的過程中遇到錯誤,則返回上一層遞歸
	 * 重新選擇上一步的位置
	 */
	public boolean eightQueue(int[] queues,int col){
		int row;                              //記錄行數
		boolean foundLocation;    //標記遞歸是否可以得到正確的位置
		//結束遞歸調用條件,如果列數等於8則結束
		if(col == 8){
			foundLocation = true;
		}
		else{
			row = 0;
			foundLocation = false;
			//回溯算法如果,遞歸調用的子調用的結果爲false則返回該函數繼續判斷,
			//找到合適的點再次調用遞歸。
			while(row < 8 && foundLocation != true){
				if(safeLocation(queues, row, col)){
					queues[col] = row;
					foundLocation = eightQueue(queues, col+1);
					if(!foundLocation){
						row++;
					}
				}
				else{
					row++;
				}
			}
		}//end else
		return foundLocation;
	}//end eightQueue
	
	/*
	 * 測試驅動
	 * 指定初始的行數
	 */
	public boolean startEightQueue(int queues[],int row){
		//指定第一列的初始行數
		queues[0] = row;
		
		if(eightQueue(queues, 1)){
			return true;
		}
		else{
			return false;
		}
		
	}//end  startEightQueue
		
	
	/*
	 * 在圖形界面顯示八皇后問題的結果
	 */
	public void showInPanel(int [] queues){
		JFrame frame  = new JFrame("八皇后");
		GridLayout layout = new GridLayout(8,8,0,2);
		frame.setLayout(layout);
		ArrayList<Button> button = new ArrayList<Button>();
		for(int i = 0 ; i < 64 ;i++){
			button.add(new Button(" "));
			//frame.add(button.get(i));
		}
		for(int i =0 ; i < 8; i++){
			Button bu = new Button("8");
			bu.setBackground(Color.GREEN);
			button.set(i+queues[i]*8, bu);
		}
		for(Button b: button){
			frame.add(b);
		}
		
		frame.setSize(400, 400);
		frame.setVisible(true);	
	}
	
	
	/*
	 *在命令行中顯示結果 
	 */
	public void showOnConsole(int [] queues){
		int [] [] end = new int[8][8];
		for(int i =0 ; i < 8;i++){
			end[queues[i]][i] =1; 
		}
		for(int m =0 ; m < 8; m++){
			for(int n = 0 ; n< 8 ; n++){
				if(end[m][n] != 0){
					System.out.print("| 8 ");
					break;
				}
				else{
					System.out.print("| 0 ");
				}
			}
			System.out.println(" |");
		}
	}
		
		
		
	
	
	public static void main(String[] args) {
		int queues[] = new int [8];
		EightQueue e = new EightQueue();
		Scanner sc = new Scanner(System.in);
		System.out.println("請輸入起始的行(1~8):");
		int col = sc.nextInt();
		if(col < 1 ||col >8){
			throw new IllegalArgumentException("請輸入正確的選項");
		}
		e.startEightQueue(queues,col-1);
		System.out.println("選擇顯示的方式:1、命令行 2、圖形界面 3、1和2:");
		int choice = sc.nextInt();
		switch(choice){
			case 1:
				e.showOnConsole(queues);
				break;
			case 2: 
				e.showInPanel(queues);
				break;
			case 3:
				e.showOnConsole(queues);
				e.showInPanel(queues);
				break;
			default :
				System.err.println("請輸入正確的選擇:");
				break;
		}
	}//end main
	
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章