实验二 电路布线问题.docx
《实验二 电路布线问题.docx》由会员分享,可在线阅读,更多相关《实验二 电路布线问题.docx(22页珍藏版)》请在冰豆网上搜索。
实验二电路布线问题
实验二电路布线问题
1.问题定义及需求分析
1、1课题目得与任务
问题描述:
印刷电路板将布线区域划分为n╳n个方格阵列。
在布线时,电路只能沿直线或直角布线。
为避免线路相交,已布线得方格要做封锁标记。
设起始位置为a,终止位置为b,求解电路布线问题。
实验要求:
设计印刷电路板得布线模拟程序。
1)采用栈或队列等数据结构。
2)采用穷举法得回溯搜索,求a到b可能得布线线路。
3)推荐采用层次优先搜索,求a到b最优得布线线路。
1、2数据形式
输入数据形式:
通过生成随机数得函数随机生成一个矩阵。
输入值得范围:
生成得矩阵中得数值为int型,为0或者1,其中0表示死路,1表示通路。
输出数据形式:
输出到显示器。
1、3程序功能
随机给定一个线路分布矩阵,利用穷举法,通过栈得应用,求出从a到b得可能布线线路;采用层次优先搜索,通过队列得应用,求出a到b得最优布线线路。
1、4测试数据
测试数据为随机生成得矩阵。
2.概要设计
2、1抽象数据类型
需要定义一个位置类型得数据,里面包含int型得x与y坐标,用来记录位置信息;再定义一个SWire得通道块数据类型,里面包含该通道块得位置数据,在路径上得序号与方向信息;另外还需要构建栈与队列得基本结构类型。
2、2主程序流程及各模块之间得调用关系
3.详细设计
3、1存储结构实现
typedefstruct{//位置
intx;
inty;
}Position;
typedefstruct{//移动标记
intord;
Positionseat;
intdi;
}SWire;
typedefstruct{//栈
SWire*base;
SWire*top;
intstacksize;
}Stack;
typedefstructQNode{//队列
Positiondata;
structQNode*next;
}QNode,*QP;
typedefstruct{
QPfron;
QPrear;
}LinkQ;
3、2负责模块得伪码算法
(1)intWirePath(int**Board,Positionstart,Positionfinish){
//寻找路径算法
//若有从电路板得入口start到出口end得通道,则求得一条存放在栈中
//(从栈底到栈顶)
InitStack(S);
curpos=start;//设定当前位置为入口位置
curstep=1;//探索第一步
do{
if(Pass(S,curpos)){//当前位置可通过,即就是未曾走到得通道块
FootPrint(curpos);//留下足迹
e=(curstep,curpos,1);
Push(S,e);//加入路径
if(curpos==finish){//到达出口(终点)
PrintStack(S);//输出路径
Printf(电路板得搜寻图)
}
return1;//返回
}
NextPos(curpos,1);//下一位置就是当前位置得东邻
curstep++;//探索下一步
}
else{//当前位置不能通过
Pop(S,e);
if(S、top!
=S、base){//栈空
while(e、di==5&&S、top!
=S、base){
MarkPrint(e、seat);
Pop(S,e);//留下不能通过得标记,并退回一步
}
}
if(e、di<5){
e、di++;
Push(S,e);//换下一个方向探索
NextPos(e、seat,e、di);//设定当前位置就是该新方向
//上得相邻块
curpos、x=e、seat、x;
curpos、y=e、seat、y;
}
}
}while(S、base!
=S、top);
printf(没有通路);
printf(电路板得搜寻图);
return0;
}
(2)intFindShortWay(int**Board,Positionstart,Positionfinish){
//搜寻最短布线路径算法
if(finish==start){//到达终点,结束
MShortPath=0;
return1;
}
curpos=start;//标记当前位置
if(Board[start、x][start、y]==0){没有通路!
return0;}
Board[start、x][start、y]=2;//有通路,则令其值为2
while
(1){//将第一个通道块赋值2,并将其相邻通道块从右开始,按顺时
//针依次入队列,当队列不空时,出队列一个通道块,对其相邻通道块做相
//同操作,直至所有得未标记通路通道块都被标记后为止。
for(i=1;i<5;i++){//对其相邻通道块赋值
neighbour=curpos;
NextPos(neighbour,i);
if(Board[neighbour、x][neighbour、y]==1||Board[neighbour、x][neighbour、y]==1||Board[neighbour、x][neighbour、y]==3){//该通道块可通过且未标记
Board[neighbour、x][neighbour、y]=Board[curpos、x][curpos、y]+1;//值+1
if(neighbour==finish)break;//到达终点,结束
EnQ(Q,neighbour);//将该通道块入队列
}//if
}//for
if(neighbour==finish)break;//已全部标记,结束循环
if(Q、fron==Q、rear){return0;}//没有通路,结束
DeQ(Q,curpos);//出队列
}//while
//反向搜寻最短布线路径
MShortPath=Board[neighbour、x][neighbour、y]2;
path[MShortPath]=(0,0);
curpos=finish;//标记当前位置为结束位置
for(j=MShortPath1;j>=0;j){//反向搜索最短路径
path[j]=curpos;
for(i=0;i<5;i++){//在相邻通道块中找符合得标记值
neighbour=curpos;
NextPos(neighbour,i);
if(Board[neighbour、x][neighbour、y]==j+2){break;}
}
curpos=neighbor;//当前位置为相邻通道块
}
printf(输出最短布线路径);
printf(输出最短路径搜寻矩阵);
return1;
}
4.调试分析
4、1问题分析与解决方法
(1)寻找可能路径
若当前位置可通过,则纳入当前路径,并继续朝着下一位置探索,即切换下一位置为当前位置,如此重复直至到达出口;若当前位置不可通,则应顺着来向退回到前一通道块,然后朝着除来向之外得其她方向继续探索;若该通道块得四周4个方块均不可通,则应从当前路径上删除该通道块。
所谓下一位置指得就是当前位置四周4个方向(东南西北)上相邻得方块。
假设以栈S记录当前路径,则栈顶中存放得就是当前路径上得最后一个通道块。
由此,纳入路径得操作即为当前位置入栈;从当前路径上删除前一通道块得操作即为出栈。
通过入栈与出栈操作,使得当前位置找寻到出口位置,从而实现对迷宫一个可能路径得求解。
(2)寻找最优路径
标记当前位置,通过队列,将当前位置周围得四个通道块入队列,将当前位置标记值m后,出队列,对该通道块执行相同得操作,并标记值m++,通过循环操作,直到当前位置为出口时终止。
借助队列,通过循环操作,使每个通道块都被赋值。
然后标记当前位置为出口,从出口向入口寻找符合递减值得通道块,从而确定出最短路径。
4、2算法得时空分析
(1)寻找可能路径
时间复杂度:
空间复杂度:
(2)寻找最优路径
时间复杂度:
空间复杂度:
4、3算法得改进设想
通过对搜寻可能路径得算法改进,实现能够同时输出多条可能路径得功能。
而最优路径也有可能有多条,因此可以改进搜索最优路径得算法,使其能够输出全部得最优路径。
可以考虑加入多重标记得方法实现。
4、4经验与体会
电路板布线问题实际上就就是迷宫求解问题,电路板上得布线要求可以转化成迷宫得通路与不通路得问题,当电线可以经过该点时,该点即为通路,而当电线不能经过该点时,它即为死路,利用1,0分别表示通路与死路,就可以建立类似迷宫求解得模型,通过栈与队列得一系列数据结构得辅助,来求解迷宫问题。
5.使用说明
运行程序,系统会自动给出一个随机电路板矩阵,自动输出一个可能得布线路径与最优布线路径,并给出搜寻路径得标记图;若该电路板不存在可行路径,则会提示没有通路。
6.测试结果(截屏)
(1)随机生成得电路板矩阵:
(2)可能布线路径:
(3)最短布线路径:
7.附录
7、1个人负责模块得程序代码
intWirePath(int**Board,Positionstart,Positionfinish){//寻找路径算法
inti,j;
StackS;
SWiree;
Positioncurpos;
intcurstep;
InitStack(S);//设定当前位置为入口位置
curpos、x=start、x;
curpos、y=start、y;
curstep=1;//探索第一步
do{
if(Pass(S,curpos)){//当前位置可通过,即未走过
FootPrint(curpos);//留下足迹
e、ord=curstep;
e、seat、x=curpos、x;
e、seat、y=curpos、y;
e、di=1;
Push(S,e);//加入路径
if(curpos、x==finish、x&&curpos、y==finish、y){//到达终点
PrintStack(S);
printf("\n搜寻路径图(3表示布线,1表示死路):
\n");
for(i=0;ifor(j=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
return1;
}
NextPos(curpos,1);//下一个位置就是当前位置得东邻
curstep++;//探索下一步
}
else{//当前位置不能通过
Pop(S,e);
if(S、top!
=S、base){
while(e、di==5&&S、top!
=S、base){
MarkPrint(e、seat);//留下不能通过标记
Pop(S,e);//退一步
}
}
if(e、di<5){
e、di++;
Push(S,e);//换下一个方向探索
NextPos(e、seat,e、di);//设定当前位置就是该新方向上得相邻块
curpos、x=e、seat、x;
curpos、y=e、seat、y;
}
}
}while(S、base!
=S、top);
printf("没有通路!
\n\n搜寻路径图(3表示布线,1表示死路):
\n");
for(i=0;ifor(j=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
return0;
}
intFindShortWay(int**Board,Positionstart,Positionfinish){//搜寻最短布线路径算法
if(finish、x==start、x&&finish、y==start、y){//起点为终点,结束
MShortPath=0;
return1;
}
LinkQQ;
InitQ(Q);
inti;
Positioncurpos,neighbour;
curpos、x=start、x;curpos、y=start、y;//设定起始位置为当前位置
if(Board[start、x][start、y]==0){printf("没有通路!
\n");return0;}
Board[start、x][start、y]=2;
while
(1){
//利用队列,将每个通道块都做上标记,起点标记为2,其余按到达步数依次累加
for(i=1;i<5;i++){
neighbour、x=curpos、x;
neighbour、y=curpos、y;
NextPos(neighbour,i);
if(Board[neighbour、x][neighbour、y]==1||Board[neighbour、x][neighbour、y]==1||Board[neighbour、x][neighbour、y]==3){//当前通道块可探索
Board[neighbour、x][neighbour、y]=Board[curpos、x][curpos、y]+1;//标记
if(neighbour、x==finish、x&&neighbour、y==finish、y)break;
//如果邻接通道块为终点,则结束循环
EnQ(Q,neighbour);//该通道块入队列
}//if
}//for
if(neighbour、x==finish、x&&neighbour、y==finish、y)break;
if(Q、fron==Q、rear){printf("没有通路!
\n");return0;}//所有通道块均被标记,结束
DeQ(Q,curpos);//出队列
}//while
//反向搜寻最短布线路径
MShortPath=Board[neighbour、x][neighbour、y]2;
Positionpath[MShortPath+1];
path[MShortPath]、x=0;
path[MShortPath]、y=0;
curpos、x=finish、x;
curpos、y=finish、y;
intj;
for(j=MShortPath1;j>=0;j){//反向搜寻符合值
path[j]=curpos;
for(i=0;i<5;i++){
neighbour、x=curpos、x;
neighbour、y=curpos、y;
NextPos(neighbour,i);
if(Board[neighbour、x][neighbour、y]==j+2){break;}//符合即结束记录
}
curpos、x=neighbour、x;
curpos、y=neighbour、y;
}
//输出最短布线路径
printf("(1,1)>");
for(i=0;path[i]、x!
=0&&path[i]、y!
=0;i++){
printf("(%d,%d)",path[i]、x,path[i]、y);
if(path[i]、x!
=8||path[i]、y!
=8){printf(">");}
}
printf("\n");
//输出最短路径搜寻矩阵
printf("\n搜寻路径图:
\n");
for(i=0;ifor(j=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
return1;
}
7、2程序全部代码
#include
#include
usingnamespacestd;
#include
#include
#defineSIZE100
#defineINCH10
typedefstruct{//位置
intx;
inty;
}Position;
typedefstruct{//移动标记
intord;
Positionseat;
intdi;
}SWire;
typedefstruct{//栈
SWire*base;
SWire*top;
intstacksize;
}Stack;
typedefstructQNode{//队列
Positiondata;
structQNode*next;
}QNode,*QP;
typedefstruct{
QPfron;
QPrear;
}LinkQ;
int**Board;//电路板
intMShortPath;//最短路径
constintn=10;//电路板大小
intCreateBoard{//创建一个电路板
inti,j;
Board=(int**)malloc(sizeof(int*)*(n));
for(i=0;iBoard[i]=(int*)malloc(sizeof(int)*(n));
}
i=0;
srand(time(NULL));
for(i=0;ifor(j=0;jif(i==0||i==n1||j==0||j==n1){
Board[i][j]=0;
}
else{
Board[i][j]=1;
if(rand%2==0){
if(rand%2==0){
Board[i][j]=0;
}
}
}
}
}
printf("随机生成得10X10电路板得分布情况为(1可通,0不可通):
\n");
for(i=0;ifor(j=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
return1;
}
intDestroyBoard{//摧毁电路板
free(Board);
return0;
}
intInitStack(Stack&S){//创建空栈
S、base=(SWire*)malloc(SIZE*sizeof(SWire));
if(!
S、base)return(0);
S、top=S、base;
S、stacksize=SIZE;
return1;
}
intPass(Stack&S,Positionf){//电线通过判定
if(Board[f、x][f、y]==0||Board[f、x][f、y]==3||Board[f、x][f、y]==1)return0;
return1;
}
intFootPrint(Positionf){//布线
Board[f、x][f、y]=3;
return1;
}
intPush(Stack&S,SWiree){//入栈
if(S、topS、base>=S、stacksize){
S、base=(SWire*)realloc(S、base,(S、stacksize+INCH)*sizeof(SWire));
if(!
S、base)return(0);
S、top=S、base+S、stacksize;
S、stacksize+=INCH;
}
*S、top=e;
S、top++;
return1;
}
intPop(Stack&S,SWire&e){//出栈
if(S、base==S、top)return(0);
e=*(S、top);
return1;
}
intNextPos(Position&f,inti){//1=EAST,2=SOURTH,3=WEST,4=NORTH//尝试相邻位置
if(i==1)f、y++;
if(i==2)f、x++;
if(i==3)f、y;
if(i==4)f、x;
return1;
}
intMarkPrint(Positionf){//留下不可布线得标志
Board[f、x][f、y]=1;
return1;
}
intPrintStack(Stack&S){//输出栈内存储得布线路径
do{
printf("(%d,%d)",S、base>seat、x,S、base>seat、y);
if((S、base>seat、x==8&&S、base>seat、y==8)){}
elseprintf(">");
S、base++;
}while(S、top!
=S、base);
printf("\n");
return1;
}
intWirePath(int**Board,Positionstart,Positionfinish){//寻找路径算法
inti,j;
StackS;
SWiree;
Positioncurpos;
intcurstep;
InitStack(S);
curpos、x=start、x;
curpos、y=start、y;
curstep=1;
do{
if(Pass(S,curpos)){
FootPrint(curpos);
e、ord=curstep;
e、seat、x=curpos、x;
e、seat、y=curpos、y;
e、di=1;
Push(S,e);
if(curpos、x==finish、x&&curpos、y==finish、y){
PrintStack(S);
printf("\n搜寻路径图(3表示布线,1表示死路):
\n");
for(i=0;ifor(j=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
return1;
}
NextPos(curpos,1);
curstep++;
}
else{
Pop(S,e);
if(S、top!
=S、base){
while(e、di==5&&S、top!
=S、base){
MarkPrint(e、seat);
Pop(S,e);
}
}
if(e、di<5){
e、di++;
Push(S,e);
NextPos(e、seat,e、di);
curpos、x=e、seat、x;
curpos、y=e、seat、y;
}
}
}while(S、base!
=S、top);
printf("没有通路!
\n\n搜寻路径图(3表示布线,1表示死路):
\n");
for(i=0;i