算法之布线问题

问题描述:印刷电路板将布线区域划分成n×m个方格阵列,精确的电路布线问题要求确定连接方格a到方格b的最短布线方案;布线时,电路只能沿着直线或直角(方格)布线;已经布线的方格被锁定,即不允许其它线路穿过。

问题分析:从起始位置a开始将它作为第一个扩展结点,与该结点相邻并且可到达的方格成为可行结点被加入到活结点队列中,并且将这些方格标记为1,即从起始方格a到这些方格的距离为1。接着从活结点队列中取出队首结点作为下一个扩展结点,并将当与此时扩展结点相邻且未标记过的方格记为2,并存入活结点队列中。这个过程一直持续到算法搜索到目标方格b或活结点队列为空。

#include <iostream>
#include <iomanip>
using namespace std;
#define n 7//方格大小
#define m 7

int a[n][m]={
    0,0,-1,0,0,0,0,
    0,0,-1,-1,0,0,0,
    0,0,0,0,-1,0,0,
    0,0,0,-1,-1,0,0,
    -1,0,0,0,-1,0,0,
    -1,-1,-1,0,0,0,0,
    -1,-1,-1,0,0,0,0
};//保存该电路板当前布线方案(-1表示该方格被锁定即障碍物)
int s[n][m];//活结点表
int dist = 1;//与初始结点的距离

//把结点(px,py)添加进活结点表,并设置与开始结点的距离
bool AddIntoS(int px,int py,int s[n][m],int a[n][m])
{
    if(px<0||px>n-1||py<0||py>m-1||a[px][py]!=0||s[px][py]==-1)return false;
    a[px][py]=dist;
    s[px][py]=1;
    return true;
}

//从活结点表中取出一个结点,返回-1表示活结点表为空
int FindOfIndexFromS(int s[n][m])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
          if(s[i][j]>0)return i*m+j;
    return -1;
}
//初始结点(sx,sy),目标结点(ex,ey)
void FindPath(int sx,int sy,int ex,int ey,int s[n][m],int a[n][m])
{
    AddIntoS(sx+1,sy,s,a);
    AddIntoS(sx-1,sy,s,a);
    AddIntoS(sx,sy+1,s,a);
    AddIntoS(sx,sy-1,s,a);//先单独处理初始结点周围的结点
    while(true)
    {
        int index=FindOfIndexFromS(s);
        if(index==-1)break;
        int px=index/m,
            py=index%m;
        dist=a[px][py]+1;
        s[px][py]=-1;
        AddIntoS(px+1,py,s,a);
        if(px+1==ex&&py==ey)break;
        AddIntoS(px-1,py,s,a);
        if(px-1==ex&&py==ey)break;
        AddIntoS(px,py+1,s,a);
        if(px==ex&&py+1==ey)break;
        AddIntoS(px,py-1,s,a);
        if(px==ex&&py-1==ey)break;
    }
    int temp=dist-1;
    while(temp>0)//生成路径,从目标结点开始查找与初始结点距离小1的邻结点
    {
        if(a[ex+1][ey]==temp)ex++;
        else if(a[ex-1][ey]==temp)ex--;
        else if(a[ex][ey+1]==temp)ey++;
        else if(a[ex][ey-1]==temp)ey--;
        else {
            cout<<"No Path!"<<endl;
            break;
        }
        cout<<ex<<" "<<ey<<endl;
        temp--;
    }
}


int main()
{
    a[2][1]=0;//起点
    a[3][5]=0;//终点
    FindPath(2,1,3,5,s,a);
}

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分支界限算法是一种常用于解决优化问题的算法,其中布线问题是其中一种应用场景。下面是分支界限算法实现布线问题算法正确性证明的介绍: 1. 算法描述: - 输入:布线问题的输入数据,如电路网格、连接需求等。 - 输出:布线问题的解,即满足连接需求的电路布线方案。 - 步骤: 1) 初始化一个空的解空间,将其作为当前最优解。 2) 选择一个合适的分支点,并根据某种策略生成分支节点。 3) 对每个分支节点进行评估,计算其上界(即当前最优解的上界)。 4) 如果某个分支节点的上界小于当前最优解,则剪枝该节点。 5) 如果某个分支节点的上界大于等于当前最优解,则将该节点加入解空间,并更新当前最优解。 6) 重复步骤2-5,直到找到满足条件的解或解空间为空。 2. 正确性证明: - 首先,分支界限算法通过不断生成分支节点和剪枝操作,可以保证搜索空间逐渐缩小,直到找到最优解或确定无解。 - 其次,分支界限算法通过上界的计算和比较,可以有效地剪枝掉一些不可能达到最优解的分支节点,从而减少搜索空间。 - 最后,由于布线问题是一个优化问题,即寻找最优解的问题,分支界限算法通过不断更新当前最优解,可以保证最终找到的解是最优解。 综上所述,分支界限算法实现布线问题算法正确性得到证明。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值