算法设计与分析: 6-9 布线问题

6-9 布线问题

问题描述

假设要将一组元件安装在一块线路板上,为此需要设计一个线路板布线方案。各元件的连线数由连线矩阵 conn 给出。元件 i 和元件 j 之间的连线数为 conn(i,j)。如果将元件 i 安装 在线路板上位置 r 处,而将元件 j 安装在线路板上位置 s 处,则元件 i 和元件 j 之间的距离 为 dist(r,s)。确定了所给的 n 个元件的安装位置,就确定了一个布线方案。与此布线方案相应的布线成本为 1i<jnconn(i,j)dist(r,s) ∑ 1 ≤ i < j ≤ n c o n n ( i , j ) ∗ d i s t ( r , s ) 。试设计一个优先队列式分支限界法,找出所给n 个元件的布线成本最小的布线方案。

对于给定的 n 个元件,设计一个优先队列式分支限界法,计算最佳布线方案,使布线费 用达到最小。

数据输入:
第一行有 1 个正整数 n (1≤n≤20)。接下来的 n-1 行, 每行 n-i 个数,表示元件 i 和元件 j 之间连线数,1≤ i< j≤ 20。


Java

package Chapter6FenZhiXianJieFa;

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

public class BuXian {

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

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

            return result;
        }

        private int len(int[][] conn, int ii){
            int sum = 0;
            for(int i=1; i<=ii; i++)
                for(int j=i+1; j<=ii; j++){
                    int dist = x[i]>x[j]?x[i]-x[j]:x[j]-x[i];
                    sum += conn[i][j]*dist;
                }

            return sum;
        }
    }

    private static int MAX = 100000;
    private static int n;
    private static int[] p;
    private static int[][] B;

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

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

            p = new int[n+1];
            B = new int[n+1][n+1];

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

            System.out.println(BBArrangeBoards(B,n));
            for(int i=1; i<=n; i++)
                System.out.print(p[i]+" ");
        }
    }

    private static int BBArrangeBoards(int[][] conn, int n){
        Queue H = new PriorityQueue<>();
        BoardNode E = new BoardNode();
        E.x = new int[n+1];
        E.s=0; E.cd=0;
        for(int i=1; i<=n; i++) E.x[i]=i;
        int bestd = MAX;
        while (E.cd < bestd){
            if(E.s == n-1){
                int ld = E.len(conn,n);
                if(ld < bestd){
                    p=E.x; bestd=ld;
                }
            }else{
                for(int i=E.s+1; i<=n; i++){
                    BoardNode N = new BoardNode();
                    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];
                    N.cd = N.len(conn, N.s);
                    if(N.cd < bestd) H.add(N);
                }


            }
            if(H.isEmpty()) return bestd;
            else E = H.poll();
        }

        return bestd;
    }
}

Input & Output

3
2 3
3
10
1 3 2 


9
18 1 10 18 10 14 8 4 
17 8 10 16 5 12 2 
11 0 7 14 19 16 
6 17 2 18 18 
6 0 8 9 
7 11 14 
13 6 
17
964
2 3 8 5 1 4 9 6 7 


9
2 6 5 10 4 19 0 0 
6 19 7 12 5 1 18 
12 8 14 0 10 13 
1 5 18 5 14 
7 4 17 7 
13 3 7 
18 14 
5
804
1 9 6 8 2 5 4 3 7 

Reference

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

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