电路布线问题--分支限界法求解
一 问题描述:
布线问题:印刷电路板将布线区域划分成n×m个方格阵列,要求确定连接方格阵列中的方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线,为了避免线路相交,已布了线的方格做了封锁标记,其他线路不允许穿过被封锁的方格。
二 算法应用:
用分支限界法解此布线问题。分支限界法类似回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但分支限界法只找出满足约束条件的一个最优解,并且以广度优先或最小耗费优先的方式搜索解空间树T。树T是一棵子集树或排列树。在搜索时,每个结点只有一次机会成为扩展结点,并且一次性产生其所有儿子结点。从活结点表中选择下一扩展结点有两种方式:(1)队列式(FIFO) (2)优先队列式。分支限界法广泛应用于单源最短路径问题,最大团问题,布线问题,电路板排列问题等。
三 求解思路:
用队列式分支限界法来考虑布线问题。布线问题的解空间是一个图,则从起始位置a开始将它作为第一个扩展结点。与该扩展结点相邻并可达的方格成为可行结点被加入到活结点队列中,并且将这些方格标记为1,即从起始方格a到这些方格的距离为1。接着,从活结点队列中取出队首结点作为下一个扩展结点,并将与当前扩展结点相邻且未标记过的方格标记为2,并存入活结点队列。这个过程一直继续到算法搜索到目标方格b或活结点队列为空时为止。
四 算法思路:
在实现上述算法时,
(1)定义一个表示电路板上方格位置的类Position。
它的2个成员row和col分别表示方格所在的行和列。在方格处,布线可沿右、下、左、上4个方向进行。沿这4个方向的移动分别记为0,1,2,3。下表中,offset[i].row和offset[i].col(i= 0,1,2,3)分别给出沿这4个方向前进1步相对于当前方格的相对位移。
移动i
|
方向
|
offset[i].row
|
offset[i].col
|
0
1
2
3
|
右
下
左
上
|
0
1
0
-1
|
1
0
-1
0
|
(2)用二维数组grid表示所给的方格阵列。
初始时,grid[i][j]= 0, 表示该方格允许布线,而grid[i][j]= 1表示该方格被封锁,不允许布线。
五 举例说明:
一个7×7方格阵列布线如下:
起始位置是a =(3,2),目标位置是b =(4,6),阴影方格表示被封锁的方格。当算法搜索到目标方格b时,将目标方格b标记为从起始位置a到b的最短距离。此例中, a到b的最短距离是9。
代码转自http://blog.csdn.net/ei__nino/article/details/8195906
#include <iostream>
#include <queue>
using namespace std;
int m=8;
int n=8;
int grid[10][10];
int indexcount=0;
struct Position
{
int row;
int col;
};
void showPath()
{
for(int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
cout<<grid[i][j]<<" ";
cout<<endl;
}
cout<<"------------------"<<endl;
}
bool FindPath(Position start,Position finish,int &PathLen,Position *&path)
{
//计算从起点位置start到目标位置finish的最短布线路径,找到最短布线路//径则返回true,否则返回false
if((start.row==finish.row) && (start.col==finish.col))
{
PathLen=0;
cout<<"start=finish"<<endl;
return true;
} //start=finish
//设置方格阵列“围墙”
//初始化图,-1为未访问
for(int i=1; i<9; i++)
{
for(int j=1; j<9; j++)
grid[i][j]=-1;
}
//添加阻挡点
grid[2][3]=-2;
for(int i=0; i<= m+1; i++)
grid[0][i]=grid[n+1][i]=-2; //顶部和底部
for(int i=0; i<= n+1; i++)
grid[i][0]=grid[i][m+1]=-2; //左翼和右翼
//初始化相对位移
cout<<"完整图"<<endl;
showPath();
Position offset[4];
offset[0].row=0;
offset[0].col=1;//右
offset[1].row=1;
offset[1].col=0;//下
offset[2].row=0;
offset[2].col=-1;//左
offset[3].row=-1;
offset[3].col=0;//上
int NumOfNbrs=4;//相邻方格数
Position here,nbr;
here.row=start.row;
here.col=start.col;
grid[start.row][start.col]=0;
//标记可达方格位置
cout<<"布线前图"<<endl;
showPath();
queue<Position> Q;
do //标记相邻可达方格
{
for(int I=0; I<NumOfNbrs; I++)
{
nbr.row=here.row + offset[I].row;
nbr.col=here.col+offset[I].col;
if(grid[nbr.row][nbr.col]==-1)
{
//该方格未被标记
//cout<<grid[nbr.row][nbr.col]<<endl;//显示路标值
grid[nbr.row][nbr.col]=grid[here.row][here.col]+1;
//cout<<nbr.col<<" "<<nbr.row<<endl;//显示坐标
}
if((nbr.row==finish.row) &&(nbr.col==finish.col)) break; //完成布线
Q.push(nbr);
}
//是否到达目标位置finish?
if((nbr.row==finish.row)&&(nbr.col==finish.col)) break;//完成布线
//活结点队列是否非空?
if(Q.empty()) return false;//无解
here = Q.front();
//cout<<here.col<<" "<<here.row<<endl;
Q.pop();//取下一个扩展结点
indexcount++;
// cout<<"下一节点"<<indexcount<<endl;
}
while(true);
//构造最短布线路径
PathLen=grid[finish.row][finish.col];
path=new Position[PathLen];
//从目标位置finish开始向起始位置回溯
here=finish;
for(int j=PathLen-1; j>=0; j--)
{
path[j]=here;
//找前驱位置
for(int i=0; i<NumOfNbrs; i++)
{
nbr.row=here.row+offset[i].row;
nbr.col=here.col+offset[i].col;
if(grid[nbr.row][nbr.col]==j)
{
// cout<<j<<endl;
break;
}
}
here=nbr;//向前移动
}
return PathLen;
}
int main()
{
Position start;
start.col=1;
start.row=1;
cout<<"布线起点"<<endl;
cout<<start.col<<" "<<start.row<<endl;
Position finish;
finish.row=3;
finish.col=4;
cout<<"布线结束点"<<endl;
cout<<finish.col<<" "<<finish.row<<endl;
int PathLen=0;
Position *path;
FindPath(start,finish,PathLen,path);
cout<<"布线后路径图"<<endl;
showPath();
cout<<"路径"<<endl;
for(int i=0; i<PathLen; i++)
{
cout<<path[i].col<<" "<<path[i].row<<endl;
}
cout << "布线问题完毕!" << endl;
system("pause");
return 0;
}
分享到:
相关推荐
算法设计--电路布线问题(分支限界法求解).rar
用分支限界法实现布线问题java代码,分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
布线问题 分支限界算法 java算法分析
1) 动态规划法求解问题的一般思路,动态规划法求解本问题的思路及其C/C++程序实现与算法的效率分析。...4) 分支限界法求解问题的一般思路,分支限界法求解本问题的思路及其C/C++程序实现与算法的效率分析。 有代码!!
0-1背包问题 动态规划 分支限界 回溯 贪心四种方法
分支限界法 实现布线问题 java中的Swing实现,带有详细的算法说明和图像展示···
分支限界法 实例 分支限界法与回溯算法的区别
分支限界法0-1背包问题 示例输入(规定物品数量为10,背包容量为50,输入为20个数,前十个为物品重量,后十个数为物品价值): 12 3 11 5 6 8 9 4 7 10 6 2 7 3 2 9 8 10 4 5 示例输出(最大价值): 44
本文档主要讲解了分支限界法的基本思想,与回溯法的区别。然后分析了分支限界法解决0-1背包问题及旅行售货员问题
使用C++,基于分支限界法的批处理作业调度,经过调试课直接使用
使用分支限界法解决N皇后问题。因为是广度优先,而且占用比较多的额外空间,所以并不是解N皇后问题的很好的算法,主要是理解分支限界法的使用。
1.分支限界法求解单源最短路径 2.C++源码+程序说明文档 3.源码带详细注释
分支限界法之最小重量机器设计问题 这个算法有些难以理解 主要是你得搞清楚优先级队列的使用 该代码注释详细
算法设计与分析,分支限界法的基本思想。 常见的两种分支限界法及背包问题详解。
单源最短路径--分支限界法
算法分析与设计电路布线问题算法分析与设计电路布线问题算法分析与设计电路布线问题算法分析与设计电路布线问题算法分析与设计电路布线问题算法分析与设计电路布线问题
有很长时间没有上传了,主要是因为这些天出了些小事。这个是用分支限界法求解单源最短路径问题的算法。
完全版分支界限法求解背包问题,易于理解 分支界限法0-1背包问题
本例采用队列式分支限界法解决布线问题,参考:算法设计与分析
布线问题,和迷宫问题是同一类问题。都是通过广度优先搜索来解决的。当然,深度就更好了。