动态规划——电路布线

动态规划——电路布线

问题描述

在一块电路板的上、下两端分别有 n 个接线柱。根据电路设计,要求用导线 (i,π(i)) 将上端接线柱 i 与下端接线柱 π(i) 相连。如下图所示,其中,π(i),1≤i≤n, 是{1,2,…,n}的一个排列。导线 (I,π(i)) 称为该电路板上的第 i 条连线。对于任何 1≤i≤j≤n, 第i条连线和第j条连线相交的充要条件是 π(i)>π(j).
在这里插入图片描述
在制作电路板时,要求将这n条线分布到若干个绝缘层上,在同一层上的连线不能相交。电路布线问题要确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。换句话说,该问题要求确定导线集Nets = { (i,π(i)),1<=i<=n }的最大不相交子集。

算法思路

1、最优子结构性质

在这里插入图片描述
N(i,j)表示上面节点i与下面节点j连线的左侧区域内(包括i j连线)的连线集合,MNS(i,j)表示连线左侧区域内最大不相交连线子集,Size(i,j)表示MNS(i,j)集合中连线的个数。

在这里注意N(i,j)和MNS(i,j)表示的都是集合!!内存储的是连线,Size(i,j)存储的才是最大不相交连线的个数!!
在这里插入图片描述

2、递归计算最优值

在这里插入图片描述

3、程序代码

package ch01;
/*
 * 电路布线问题(动态规划)
 */

public class dianlubuixian {
	public int[] c;
	public int[][] size;//最大不相交子集
	public int[] net;//电路数
	
	public  dianlubuixian(int[] cc) {
		this.c = cc;
		this.size = new int[cc.length][cc.length];//下标从1开始
		this.net = new int[cc.length];		
	}
	
	public void mnset(int[] c,int[][] size) {
		int n = c.length-1;
		for(int j=0;j<c[1];j++)
		{
			size[1][j] = 0;
		}
		for(int j=c[1];j<=n;j++)
		{
			size[1][j] = 1;
		}
		for (int i = 2; i < n; i++) {
			for(int j=0;j<c[i];j++)
			{
				size[i][j] = size[i-1][j];
			}
			for(int 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);
	}
	
	
	//构造最优解
	public int  traceback(int[] c,int[][] size,int[] net)
	{
		int n = c.length-1;
		int j = n;
		int m = 0;
		for(int 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;
		}
		System.out.println("最大不想交连线分别是:");
		for (int t = m-1; t >= 0; t--) {
			System.out.print("("+net[t]+","+c[net[t]]+")");
		}
		System.out.println();
		return m;
	}

	public static void main(String[] args) {
		int[] c  = {0,8,7,4,2,5,1,9,3,10,6};//下标从1开始,0不算,总共10个数
		dianlubuixian dianlubuixian  = new dianlubuixian(c);
		dianlubuixian.mnset(dianlubuixian.c, dianlubuixian.size);
		int  x = dianlubuixian.traceback(dianlubuixian.c, dianlubuixian.size, dianlubuixian.net);
		System.out.println("最大不相交连线数目为:"+x);
	}

}

4、运行结果

在这里插入图片描述

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 。单

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值