1. 程式人生 > >演算法設計與分析: 6-12 世界名畫陳列館問題

演算法設計與分析: 6-12 世界名畫陳列館問題

6-12 世界名畫陳列館問題

問題描述

世界名畫陳列館由m×n 個排列成矩形陣列的陳列室組成。為了防止名畫被盜,需要在陳列室中設定警衛機器人哨位。每個警衛機器人除了監視它所在的陳列室外,還可以監視與 它所在的陳列室相鄰的上、下、左、右 4 個陳列室。試設計一個安排警衛機器人哨位的演算法, 使得名畫陳列館中每一個陳列室都在警衛機器人的監視之下,且所用的警衛機器人數最少。

設計一個優先佇列式分支限界法,計算警衛機器人的最佳哨位安排,使得名畫陳列館中 每一個陳列室都在警衛機器人的監視之下,且所用的警衛機器人數最少。

資料輸入:
第一行有 2 個正整數 m 和 n (1≤m,n≤20)。

Java

package Chapter6FenZhiXianJieFa;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class ShiJieMingHuaChenLieGuan {

    private static class HeapNode implements Comparable{
        int i,j,k,t;
        int[][] x,y;

        public int compareTo
(Object o){ HeapNode heapNode = (HeapNode) o; int result = Integer.compare(k, heapNode.k); return result; } private void heapNode(int n, int m){ x = new int[n+2][m+2]; y = new int[n+2][m+2]; for(int a=0; a<=n+1
; a++) for(int b=0; b<=m+1; b++){ x[a][b]=0; y[a][b]=0; } for(int a=0; a<=m+1; a++) {y[0][a]=1; y[n+1][a]=1;} for(int a=0; a<=n+1; a++) {y[a][0]=1; y[a][m+1]=1;} i=1; j=1; k=t=0; } } private static class Robot{ int[][] bestx; int n,m,best; boolean p; private void compute(){ bestx = new int[n+2][m+2]; if(n==1 && m==1){System.out.println(1); System.out.println(1); return;} pqbb(); output(); } private void pqbb(){ Queue<HeapNode> H = new PriorityQueue<>(); HeapNode E = new HeapNode(); E.heapNode(n,m); while (true){ int i=E.i, j=E.j, k=E.k, t=E.t; if(t == n*m) {best=k; copy(bestx,E.x); return;} else { if(i < n) change(H,E,i+1,j); if(j<m && (E.y[i][j+1]==0 || E.y[i][j+2]==0)) change(H,E,i,j+1); if(E.y[i+1][j]==0 && E.y[i][j+1]==0) change(H,E,i,j); } if(H.isEmpty()) break; E = H.poll(); } } private void change(Queue<HeapNode> H, HeapNode E, int i, int j){ HeapNode N = new HeapNode(); N.heapNode(n,m); N.i=E.i; N.j=E.j; N.k=E.k+1; N.t=E.t; for(int a=0; a<=n+1; a++) for(int b=0; b<=m+1; b++){ N.x[a][b] = E.x[a][b]; N.y[a][b] = E.y[a][b]; } N.x[i][j] = 1; for(int s=1; s<=5; s++){ int p = i+d[s][1]; int q = j+d[s][2]; N.y[p][q]++; if(N.y[p][q] == 1) N.t++; } while (!(N.y[N.i][N.j]==0 || N.i>n)){ N.j++; if(N.j > m) {N.i++; N.j=1;} } H.add(N); } private void copy(int[][] x, int[][] y){ for(int i=0; i<=n; i++) for(int j=0; j<=m; j++) x[i][j] = y[i][j]; } private void output(){ 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(); } } private void init(){ Scanner input = new Scanner(System.in); n = input.nextInt(); m = input.nextInt(); p = false; if(n < m) {int tmp=n; n=m; m=tmp; p=true;} } } private static int[][] d = {{0,0,0},{0,0,0},{0,0,-1},{0,-1,0},{0,0,1},{0,1,0}}; public static void main(String[] args){ while (true){ Robot X = new Robot(); X.init(); X.compute(); } } }

Input & Output

4 4
4
0 0 1 0 
1 0 0 0 
0 0 0 1 
0 1 0 0 


5 5
7
0 0 1 0 0 
1 0 0 0 1 
0 0 1 0 0 
0 0 1 0 0 
1 0 0 0 1 

Reference

王曉東《計算機演算法設計與分析》(第3版)P229