Java——世界名畫陳列館(最少機器人問題)
阿新 • • 發佈:2019-02-19
問題描述:
世界名畫陳列館問題。世界名畫陳列館由m×n個排列成矩形陣列的陳列室組成。為了防止名畫被盜,需要在陳列室中設定警衛機器人哨位。每個警衛機器人除了監視它所在的陳列室外,還可以監視與它所在的陳列室相鄰的上、下、左、右4
個陳列室。試設計一個安排警衛機器人哨位的演算法,使得名畫陳列館中每一個陳列室都在警衛機器人的監視之下,且所用的警衛機器人數最少。
程式碼
import java.util.Scanner; /** * 世界名畫陳列館問題 * 最少機器人 * @author lzq * */ public class Test { static int[][] x=new int[10][10]; //這些陣列大小可以根據自己需要改 static int[][] y=new int[10][10]; static int[][] bestx=new int[10][10]; //x用來設定當前警衛,y用來表示監控情況,bestx返回最終結果 static int n, m, best , k=0; public static void main(String[] args) { for(;;) { System.out.println("------------------------------------"); System.out.println("請設定陳列館區域:"); System.out.print("m:"); Scanner sc1 = new Scanner(System.in); m = Integer.parseInt(sc1.next()); System.out.print("n:"); sc1 = new Scanner(System.in); n = Integer.parseInt(sc1.next()); compute(); //計算 System.out.println("最少需要"+best+"個警衛!"); for(int i = 1;i <= n; i++) { for(int j = 1;j <= m;j++) { System.out.print(bestx[i][j]+" "); } System.out.println(); } } } /** * 在整個外面加上一圈,便於處理邊界情況 */ public static void compute() { best = m*n/3+2; for(int i = 0;i <= m+1;i++) { y[0][i] = 1; y[n+1][i] = 1; } for(int i = 0;i <= m+1;i++) { y[i][0] = 1; y[i][m+1] = 1; } search(1,0); } /** * 在(i, j)處設定一個警衛,並改變其周圍受監控情況 * @param i * @param j */ public static void change(int i,int j) { x[i][j] = 1; k++; y[i][j+1]++; y[i+1][j]++; y[i][j]++; y[i][j-1]++; y[i-1][j]++; } /** * 撤銷在(i, j)處設定的警衛,並改變其周圍受監控情況 * @param i * @param j */ public static void restore(int i,int j) { x[i][j] = 0; k--; y[i][j+1]--; y[i+1][j]--; y[i][j]--; y[i][j-1]--; y[i-1][j]--; } /** * 回溯搜尋 * 從上到下,從左至右搜尋沒被監控的位置 * @param i * @param j */ public static void search(int i,int j) { do { j++; if(j > m) { i++; j= 1; } }while(!((y[i][j] == 0) || (i > n))); //重新整理警衛值 if(i > n) { if(k < best) { best = k; for(int p = 1;p <= n;p++) for(int q = 1;q <= m;q++) bestx[p][q] = x[p][q]; return; } } if(i < n) { //結點p change(i+1,j); search(i,j); //遞迴搜尋下一個點 restore(i+1, j); //恢復 } if((y[i][j+1] == 0)) { //結點q change(i,j); search(i,j); restore(i, j); } if(((y[i][j+1] == 0) && (y[i][j+2] == 0))) { //結點q change(i,j+1); search(i,j); restore(i, j+1); } } }
執行結果:
------------------------------------
請設定陳列館區域:
m:4
n:4
最少需要4個警衛!
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
------------------------------------
請設定陳列館區域:
m:8
n:6
最少需要11個警衛!
0 0 1 0 0 1 0 0
1 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0
0 1 0 0 0 1 1 0
0 0 0 0 0 0 0 0
0 1 0 0 1 0 0 1
------------------------------------
請設定陳列館區域:
m: