0
点赞
收藏
分享

微信扫一扫

动态规划电路布线问题(Java代码实现)


电路布线

问题分析

  • 电路布线的官方解释我就不加赘述了,通俗的讲,就是求最大不相交子集,也就是尽可能多的在线路不相交的情况下的布线情况。那么,这里再说一下,什么是相交,对于所有上端的接线柱 1<=i<j<=n, 相交即下端接线柱Π(i) > Π(j), 举个例子,比如上端接线柱1,2, 下端接线柱对应的是4,5的话就不相交,对应的是5,4的话就相交。

动态规划电路布线问题(Java代码实现)_Java实现电路布线

  • 我们直接拿上述这个图为例
  • 记 N(i,j) = {t|(t, Π(t))∈ Nets,t ≤ i, Π(t) ≤ j}。 N(i, j)的最大不相交子集为 MNS(i,j)。 Size(i,j) = |MNS(i,j)|(最大不相交子集线路的条数)
  • N(i,j): 上端接线柱从1到i,下端接线柱从1到j,在这个范围内的接线情况。 也就是 t ∈ (1~i), Π(t) ∈ (1~j)。 比如上述图中,如果是 N(4, 6), 那么能够出现的线只有两条,即{4->2, 3->4},那么Size(4,6) = 1
  1. 当 i = 1时,
    动态规划电路布线问题(Java代码实现)_电路布线问题_02
  2. 当 i > 1时,
  1. j < Π(i)。 此时,(i, Π(i)) ∉ N(i,j)。 故 N(i,j) = N(i-1,j), Size(i,j) = Size(i-1,j)。 为什么是这样?因为 i->Π(i) 就是连接的那条线,既然 j < Π(i), 也就是说动态规划电路布线问题(Java代码实现)_Java实现电路布线_03,那么显然,N(i,j) = N(i-1,j)
  2. 当 j ≥ Π(i), (i,Π(i)) ∈ MNS(即要这根线)(i,j)。 对于任意 (t,Π(t)) ∈ MNS(i,j) 有 t < i 且 Π(t) < Π(i)。 这种情况下,MNS(i,j) - {(i,Π(i))}是N(i-1, Π(i)-1) 的最大不相交子集。
  3. 若 (i,Π(i)) ∉ N(i,j)(即不要这根线), 则对任意 (t,Π(t)) ∈ MNS(i,j) 有 t < i。 从而 MNS(i,j) ∈ N(i-1,j)。 因此,Size(i,j) ≤ Size(i-1,j)。 另一方面,MNS(i-1,j) ∈ N(i,j),故又有 Size(i,j) ≥ Size(i-1,j), 从而 Size(i,j) = Size(i-1,j)。 (此处叙述了这么多,无非就是不要这根线,那么 Size(i,j) = Size(i-1,j))
  1. 综上,我们就得出下面这样一个状态转移方程
  • 当 i = 1时
    动态规划电路布线问题(Java代码实现)_动态规划_04
  • 当 i > 1时

动态规划电路布线问题(Java代码实现)_Java实现电路布线_05

Java源代码

/*
* 若尘
*/
package wireset;

import java.util.Arrays;

/**
* 动态规划电路布线问题
* @author ruochen
* @version 1.0
*/

public class WireSet {

private static int size[][];
private static final int[] C = {0, 9, 7, 4, 2, 5, 1, 9, 3, 10, 6};
private static final int num = 10;

public static void main(String[] args) {
int NET[] = new int[9];
MNS(C, 10);
Traceback(C, 10, NET);
System.out.println(Arrays.toString(NET));
}

/**
*
* @param C 导线上下接线柱对应的关系
* @param n 导线数量
*/
public static void MNS(int[] C, int n) {
int i, j;
size = new int[num + 1][num + 1];

// 判断第一行, i = 1 的情况
for (j = 0; j < C[1]; j++) {
size[1][j] = 0;
}
for (j = C[1]; j <= n; j++) {
size[1][j] = 1;
}

// 2->n 的情况
for (i = 2; i < n; i++) {
for (j = 0; j < C[i]; j++) {
// i > 1 && j < Π(i) 的情况
size[i][j] = size[i-1][j];
}
for (j = C[i]; j <= n; j++) {
size[i][j] = Math.max(size[i-1][j], size[i-1][C[i]-1] + 1);
}
}
size[n][n] = Math.max(size[n-1][n], size[n-1][C[n]-1] + 1);
}

/**
* 获得一个记录可连接导线的数组
* @param C 导线上下两接线柱对应的关系
* @param n 导线数量
* @param NET 记录可连接的导线
*/
public static void Traceback(int[] C, int n, int NET[]) {
int i, j = n;
int m = 0;
for (i = n; i > 1; i--) {
if (size[i][j] != size[i-1][j]) {
NET[m++] = i;
j = C[i] - 1;
}
// 第一条线
if (j >= C[1]) {
NET[m++] = 1;
}
}
}

}

[1, 9, 1, 1, 7, 5, 3, 0, 0]


举报

相关推荐

0 条评论