6-1 最小长度电路板排列问题(队列)
问题描述
最小长度电路板排列问题是大规模电子系统设计中提出的实际问题。该问题的提法是,将 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 Chapter6FenZhiXianJieFa;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class ZuiXiaoChangDuDianLuBanPaiLie {
private static class BoardNode{
int[] x;
int s,cd;
int[] low,high;
private int len(){
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 int n,m;
private static int[] bestx;
private static int[][] B;
public static void main(String[] args){
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();
int bestd = FIFOBoards();
System.out.println(bestd);
for(int i=1; i<=n; i++)
System.out.print(bestx[i]+" ");
}
}
private static int FIFOBoards(){
Queue<BoardNode> Q = new LinkedList<>();
BoardNode E = new BoardNode();
E.x = new int[n+1];
E.s=0; E.cd=0; E.low=new int[m+1]; E.high=new int[m+1];
for(int i=1; i<=m; i++){E.high[i]=0; E.low[i]=n+1;}
for(int i=1; i<=n; i++) E.x[i]=i;
int bestd = n+1;
bestx = null;
while (true){
if(E.s == n-1){
for(int j=1; j<=m; j++)
if(B[E.x[n]][j]>0 && n>E.high[j]) E.high[j]=n;
int ld=E.len();
if(ld < bestd){
bestx = E.x;
bestd = ld;
}
}else {
int curr = E.s+1;
for(int i=E.s+1; i<=n; i++){
BoardNode N = new BoardNode();
N.low = new int[m+1];
N.high = new int[m+1];
for(int j=1; j<=m; j++){
N.low[j] = E.low[j]; N.high[j]=E.high[j];
if(B[E.x[i]][j] > 0){
if(curr < N.low[j]) N.low[j]=curr;
if(curr > N.high[j]) N.high[j]=curr;
}
}
N.cd = N.len();
if(N.cd < bestd){
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];
Q.add(N);
}
}
}
if(Q.isEmpty()) break;
else{
E = Q.poll();
}
}
return bestd;
}
}
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
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
6
2 4 5 3 6 8 9 10 1 7
10 6
0 0 0 1 1 0
0 1 1 1 0 0
1 0 1 0 0 0
0 0 1 0 0 0
0 1 1 1 0 0
1 1 0 0 0 0
1 1 0 0 1 1
0 0 0 0 0 1
0 1 1 1 1 1
1 1 1 1 1 1
6
1 4 2 5 7 9 10 3 6 8
Reference
王晓东《计算机算法设计与分析》(第3版)P225