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 个元件的安装位置,就确定了一个布线方案。与此布线方案相应的布线成本为 ∑1≤i≤j≤nconn(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