算法设计与分析——电路布线(动态规划)

Posted wkfvawl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法设计与分析——电路布线(动态规划)相关的知识,希望对你有一定的参考价值。

一、问题描述

在一块电路板的上下两端分别有n个接线柱。根据电路设计,要求用导线 (i,π(i)),将上端接线柱 i 与下端接线柱 π(i) 相连,
如图,其中 π(i),1<=i<=n,是(1,2……,n)的一个排列。导线(i,π(i))称为该电路板上的第i条连线。对于任何 1<=i<s<=n,第i条连线和第s条连线相交的充分且必要条件是 π(i) > π(s)。

技术图片

在制作电路板时,要求将这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、递归计算最优值

技术图片

void MNS(int C[],int n,int **size)  
{  
    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];//当i<c[i]的情形  
        }  
        for(int j=C[i]; j<=n; j++)  
        {  
            //当j>=c[i]时,考虑(i,c[i])是否属于MNS(i,j)的两种情况  
            size[i][j]=max(size[i-1][j],size[i-1][C[i]-1]+1);  
        }  
    }  
    size[n][n]=max(size[n-1][n],size[n-1][C[n]-1]+1);  
}  

3、构造最优解

技术图片

void Traceback(int C[],int **size,int n,int Net[],int& m)  
{  
    int j=n;  
    m=0;  
    for(int i=n;i>1;i--)  
    {  
        if(size[i][j]!=size[i-1][j])//此时,(i,c[i])是最大不相交子集的一条边  
        {  
            Net[m++]=i;  
            j=C[i]-1;//更新扩展连线柱区间  
        }  
    }  
    if(j>=C[1])//处理i=1的情形  
    {  
        Net[m++]=1;  
    }  
}  

4、计算复杂性

技术图片

 

以上是关于算法设计与分析——电路布线(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

动态规划电路布线问题

C语言程序,输入N个点的坐标,判断能否构成凸多边形

算法设计与分析之动态规划

算法设计与分析期中考试复习:代码和经典题目 分治二分动态规划(未完待续)

算法动态规划 ⑤ ( LeetCode 63.不同路径 II | 问题分析 | 动态规划算法设计 | 代码示例 )

算法动态规划 ⑤ ( LeetCode 63.不同路径 II | 问题分析 | 动态规划算法设计 | 代码示例 )