5-2 最小长度电路板排列问题
问题描述
最小长度电路板排列问题是大规模电子系统设计中提出的实际问题。该问题的提法是,将 n 块电路板以最佳排列方案插入带有 n 个插槽的机箱中。n 块电路板的不同的排列方式对 应于不同的电路板插入方案。
设
是n块电路板的集合。集合
是n块电路
板的 m 个连接块。其中每个连接块
是 B 的一个子集,且
中的电路板用同一根导线连接在一起。
例如,设 n=8,m=5。给定 n 块电路板及其 m 个连接块如下:
;
;
;
;
;
;
。 这 8 块电路板的一个可能的排列如图所示。
在最小长度电路板排列问题中,连接块的长度是指该连接块中第 1 块电路板到最后 1 块电路板之间的距离。例如在图示的电路板排列中,连接块 的第 1 块电路板在插槽 3 中, 它的最后 1 块电路板在插槽 6 中,因此 的长度为 3。同理 的长度为 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 Chapter5HuiSuFa;
import java.util.Scanner;
public class ZuiXiaoChangDuDianLuBanPaiLie {
private static int n,m;
private static int[] bestx;
private static int[][] B;
private static int[] x,low,high;
private static int bestd;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
n = input.nextInt();
m = input.nextInt();
bestx = new int[n+1];
B = new int[n+1][m+1];
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
B[i][j] = input.nextInt();
int minLen = arrangeBoards();
System.out.println(minLen);
for(int i=1; i<=n; i++)
System.out.print(bestx[i]+" ");
}
}
private static int arrangeBoards(){
x = new int[n+1];
low = new int[m+1];
high = new int[m+1];
bestd = n+1;
for(int i=1; i<=n; i++)
x[i] = i;
backtrack(1);
return bestd;
}
private static void backtrack(int i){
if(i == n){
int tmp = len(i);
if(tmp < bestd){
bestd = tmp;
for(int j=1; j<=n; j++)
bestx[j] = x[j];
}
}else{
for(int j=i; j<=n; j++){
swap(x,i,j);
int ld = len(i);
if(ld < bestd)
backtrack(i+1);
swap(x,i,j);
}
}
}
private static int len(int ii){
for(int i=1; i<=m; i++){
high[i] = 0;
low[i] = n+1;
}
for(int i=1; i<=ii; i++)
for(int k=1; k<=m; k++)
if(B[x[i]][k] > 0){
if(i < low[k]) low[k] = i;
if(i > high[k]) high[k] = i;
}
int tmp = 0;
for(int k=1; k<=m; k++)
if(low[k]<=n && high[k]>0 && tmp<high[k]-low[k])
tmp = high[k] - low[k];
return tmp;
}
private static void swap(int[] x, int i, int j){
int tmp;
tmp = x[i];
x[i] = x[j];
x[j] = tmp;
}
}
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
Reference
王晓东《计算机算法设计与分析》(第3版)P179