算法设计与分析: 5-16 布线问题

5-16 布线问题

问题描述

假设要将一组元件安装在一块线路板上,为此需要设计一个线路板布线方案。各元件的连线数由连线矩阵 conn 给出。元件 i 和元件 j 之间的连线数为 conn(i,j) c o n n ( i , j ) 。如果将元件 i 安装 在线路板上位置 r 处,而将元件 j 安装在线路板上位置 s 处,则元件 i 和元件 j 之间的距离 为 dist(r,s) d i s t ( r , s ) 。确定了所给的 n 个元件的安装位置,就确定了一个布线方案。与此布线方案相应的布线成本为 1ijnconn(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

Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class BuXian {

    private static int n;
    private static int[][] conn;

    private static int[] x,bestx;
    private static int bestd;

    private static int MAX = 100000;

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

        while (true){
            bestd = MAX;

            n = input.nextInt();

            x = new int[n+1];
            bestx = new int[n+1];
            conn = new int[n+1][n+1];

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

            for(int i=1; i<=n; i++)
                x[i] = i;

            backtrack(1);

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

    private static void backtrack(int t){
        if(t == n){
            int tmp = len(t);
            if(tmp < bestd){
                bestd = tmp;
                for(int j=1; j<=n; j++)
                    bestx[j] = x[j];
            }
        }
        else
            for (int j=t; j<=n; j++){
                swap(x,t,j);
                backtrack(t+1);
                swap(x,t,j);
            }
    }

    private static int len(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 void swap(int[] x, int i, int j){
        int tmp;
        tmp = x[i];
        x[i] = x[j];
        x[j] = tmp;
    }
}

Input & Output

3
2 3
3
10
1 3 2 


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

Reference

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

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/IOIO_/article/details/81125738
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞