算法设计与分析: 6-2 最小长度电路板排列问题(优先队列)

6-2 最小长度电路板排列问题(优先队列)


问题描述

最小长度电路板排列问题是大规模电子系统设计中提出的实际问题。该问题的提法是,将 n 块电路板以最佳排列方案插入带有 n 个插槽的机箱中。n 块电路板的不同的排列方式对 应于不同的电路板插入方案。
B={12...n} B = { 1 , 2 , . . . , n } 是n块电路板的集合。集合 L={N1N2...Nm} L = { N 1 , N 2 , . . . , N m } 是n块电路板的 m 个连接块。其中每个连接块 Ni N i 是 B 的一个子集,且 Ni N i 中的电路板用同一根导线连接在一起。
例如,设 n=8,m=5。给定 n 块电路板及其 m 个连接块如下: B={12345678} B = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } ; L={N1N2N3N4N5} L = { N 1 , N 2 , N 3 , N 4 , N 5 } ;
N1={456} N 1 = { 4 , 5 , 6 } ; N2={23} N 2 = { 2 , 3 } ; N3={13} N 3 = { 1 , 3 } ; N4={36} N 4 = { 3 , 6 } ; N5={78} N 5 = { 7 , 8 } 。 这 8 块电路板的一个可能的排列如图所示。

最小长度电路板排列问题(优先队列)

在最小长度电路板排列问题中,连接块的长度是指该连接块中第 1 块电路板到最后 1 块电路板之间的距离。例如在图示的电路板排列中,连接块 N4 N 4 的第 1 块电路板在插槽 3 中,它的最后 1 块电路板在插槽 6 中,因此 N4 N 4 的长度为 3。同理 N2 N 2 的长度为 2。图中连接块最大长度为 3。试设计一个优先队列式分支限界法找出所给 n 个电路板的最佳排列,使得 m 个连接块中最大长度达到最小。

对于给定的电路板连接块,设计一个优先队列式分支限界法,找出所给 n 个电路板的最佳排列,使得 m 个连接块中最大长度达到最小。

数据输入:
第一行有 2 个正整数 n 和 m (1≤m,n≤20)。接下来的 n 行中,每行有 m 个数。第 k 行的第 j 个数为 0 表示电路板 k 不在连接块 j 中,1 表示电路板 k 在连接块 j 中。


Java

package Chapter6FenZhiXianJieFa;

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

public class ZuiXiaoChangDuDianLuBanPaiLieYouXianDuiLie {

    private static class BoardNode implements Comparable{
        int[] x;
        int s,cd;
        int[] low,high;

        private int len(){
            int tmp = 0;
            for(int k=1; k<=m; k++)
                if(low[k]<=n && high[k]>0 && tmpreturn tmp;
        }

        public int compareTo(Object o){
            BoardNode boardNode = (BoardNode) o;
            int result = Integer.compare(cd, boardNode.cd);

            return result;
        }
    }

    private static int n,m;
    private static int[] bestx;
    private static int[][] B;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            n = input.nextInt();
            m = input.nextInt();

            B = new int[n+1][m+1];
            bestx =new int[n+1];

            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                    B[i][j] = input.nextInt();

            int bestd = FIFOBoards();

            System.out.println(bestd);
            for(int i=1; i<=n; i++)
                System.out.print(bestx[i]+" ");
        }
    }

    private static int FIFOBoards(){
        Queue Q = new PriorityQueue<>();
        BoardNode E = new BoardNode();
        E.x = new int[n+1];
        E.s=0; E.cd=0; E.low=new int[m+1]; E.high=new int[m+1];
        for(int i=1; i<=m; i++){E.high[i]=0; E.low[i]=n+1;}
        for(int i=1; i<=n; i++) E.x[i]=i;
        int bestd = n+1;
        bestx = null;
        while (true){
            if(E.s == n-1){
                for(int j=1; j<=m; j++)
                    if(B[E.x[n]][j]>0 && n>E.high[j]) E.high[j]=n;
                int ld=E.len();
                if(ld < bestd){
                    bestx = E.x;
                    bestd = ld;
                }
            }else {
                int curr = E.s+1;
                for(int i=E.s+1; i<=n; i++){
                    BoardNode N = new BoardNode();
                    N.low = new int[m+1];
                    N.high = new int[m+1];
                    for(int j=1; j<=m; j++){
                        N.low[j] = E.low[j]; N.high[j]=E.high[j];
                        if(B[E.x[i]][j] > 0){
                            if(curr < N.low[j]) N.low[j]=curr;
                            if(curr > N.high[j]) N.high[j]=curr;
                        }
                    }
                    N.cd = N.len();
                    if(N.cd < bestd){
                        N.x = new int[n+1];
                        N.s = E.s+1;
                        for(int j=1; j<=n; j++) N.x[j]=E.x[j];
                        N.x[N.s] = E.x[i];
                        N.x[i] = E.x[N.s];
                        Q.add(N);
                    }
                }
            }
            if(E.cd >= bestd) break;
            else{
                E = Q.poll();
            }
        }

        return bestd;
    }
}

Input & Output

8 5
1 1 1 1 1
0 1 0 1 0
0 1 1 1 0
1 0 1 1 0
1 0 1 0 0
1 1 0 1 0
0 0 0 0 1
0 1 0 0 1
4
5 4 3 1 6 2 8 7 


10 4
1 0 1 0 
0 0 0 1 
1 1 1 0 
0 1 0 0 
1 0 0 1 
0 1 1 1 
0 0 1 0 
1 1 0 0 
1 1 1 1 
1 1 0 0
6
4 10 3 8 9 6 1 5 7 2 

Reference

王晓东《计算机算法设计与分析》

你可能感兴趣的:(Algorithm,分支限界法,Java,计算机算法设计与分析,计算机算法设计与分析)