算法设计与分析: 6-14 排列空间树问题

6-14 排列空间树问题


问题描述

试设计一个用队列式分支限界法搜索排列空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解电路板排列问题。
电路板排列问题是大规模电子系统设计中提出的实际问题。该问题的提法是,将 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 中的电路板用同一根导线连接在一起。在设计机箱时,插槽一侧的布线间隙由电路板排列的密度所确定。因此电路板排列 问题要求对于给定电路板连接条件(连接块),确定电路板的最佳排列,使其具有最小密度。

对于给定电路板连接条件,编程计算电路板的最佳排列,使其具有最小密度。

数据输入:
第 1 行是 2 个正整数 n 和 m,表示有 n 块电路板 和 m 个连接块。接下来的 n 行每行有 m 个数,第 i 行的第 j 个数 a[i][j]=1 表示第 i 块电路板 在第 j 个连接块中,否则第 i 块电路板不在第 j 个连接块中。


Java

package Chapter6FenZhiXianJieFa;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class PaiLieKongJianShu {

    private static class QNode{
        int i,cd;
        int[] x,now;
    }

    private static class Board{
        int n,m,bestd;
        int[] bestx,total;
        int[][] B;

        private void init(){
            E = new QNode();
            E.x = new int[n+1];
            E.i=0; E.cd=0;
            E.now = new int[m+1];
            total = new int[m+1];
            for(int i=1; i<=m; i++) {total[i]=0; E.now[i]=0;}
            for(int i=1; i<=n; i++){
                E.x[i] = i;
                for(int j=1; j<=m; j++) total[j]+=B[i][j];
            }
            bestd = m+1;
        }

        //叶结点判定
        private boolean answer(QNode E){
            return E.i==n-1;
        }

        //保存最优解
        private void save(QNode E){
            int ld = 0;//最后一块电路板的密度
            for(int j=1; j<=m; j++) ld+=B[E.x[n]][j];
            if(ldE.cd?ld:E.cd;
                for(int k=0; k<=n; k++) bestx[k]=E.x[k];
            }
        }

        //产生新结点
        private void newNode(QNode E, int i){
            N = new QNode();
            N.now = new int[m+1];
            for(int j=1; j<=m; j++)
                N.now[j] = E.now[j]+B[E.x[i]][j];
            int ld=0;//新插入电路板的密度
            for(int j=1; j<=m; j++)
                if(N.now[j]>0 && total[j]!=N.now[j]) ld++;
            N.cd = ld>E.cd?ld:E.cd;
        }

        //可行性约束
        private boolean constrain(QNode E){
            return true;
        }

        //边界约束
        private boolean bound(QNode E){
            return E.cdprivate void enQueue(Queue Q, QNode N, QNode E, int i){
            N.x = new int[n+1];
            N.i = E.i+1;
            for(int j=1; j<=n; j++) N.x[j]=E.x[j];
            N.x[N.i] = E.x[i];
            N.x[i] = E.x[N.i];
            Q.add(N);
        }

        private boolean getNext(Queue Q){
            if(Q.isEmpty()) return false;
            E = Q.poll();

            return true;
        }

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

        private void fifobb(){
            Queue Q = new LinkedList<>();
            init();
            //搜索排列空间树
            while (true){
                if(answer(E)) save(E);
                else
                    for(int i=E.i+1; i<=n; i++){
                        newNode(E,i);
                        if(constrain(N) && bound(N)) enQueue(Q,N,E,i);
                    }
                if(!getNext(Q)) break;
            }
            output();
        }
    }

    private static QNode E,N;

    public static void main(String[] args){
        int n,m;
        int[][] B;
        int[] bestx;
        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();

            Board board = new Board();
            board.B = B;
            board.n = n;
            board.m = m;
            board.bestx = bestx;
            board.fifobb();
        }
    }
}

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
2 3 4 5 1 6 7 8 


6 5
1 1 0 1 1 
1 1 0 1 1 
1 0 0 1 0 
0 1 0 0 0 
1 0 0 1 0 
1 0 0 0 0 
4
1 2 3 4 5 6 


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 
4
1 2 3 4 5 6 7 8 9 10 

Reference

王晓东《计算机算法设计与分析》(第3版)P230

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