实验内容:
印刷电路板将布线区域划分成n×m个方格如图a所示。精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线,如图b所示。为了避免线路相交,已布了线的方格做了封锁标记,其它线路不允穿过被封锁的方格。
一个布线的例子:图中包含障碍。起始点为a,目标点为b。
代码
#include <iostream>
#include <queue>
//#include <windows.h>
#include<iomanip>
//#include <Windows.h>
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<< setw(3)<<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<<"000000000000000000000"<<endl;
return true;
} //start=finish
//初始化相对位移
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;//上
Position here,next;
here.row=start.row;
here.col=start.col;
grid[start.row][start.col]=1;
queue<Position> Q;
do //标记相邻可达方格
{
for(int I=0; I<4; I++) //相邻四格
{
next.row=here.row + offset[I].row;
next.col=here.col+offset[I].col;
if(grid[next.row][next.col]==0&&next.row!=-1 && next.col!=-1 ) //能走并且没有越界 // grid[next.row][next.col]>=grid[here]+quanzhi
{
grid[next.row][next.col]=grid[here.row][here.col]+1; //+
if((next.row==finish.row) &&(next.col==finish.col)) break; //完成布线
//调试
// Sleep (3000);
// system("cls");
// showPath();
Q.push(next);
}
}
//是否到达目标位置finish?
if((next.row==finish.row)&&(next.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<4; i++)
{
next.row=here.row+offset[i].row;
next.col=here.col+offset[i].col;
if(grid[next.row][next.col]==j)
{
break;
}
}
here=next;//向前移动
}
return PathLen;
}
int main()
{
//添加阻挡点
grid[2][3]=-1;
grid[1][3]=-1;
grid[2][2]=-1;
grid[2][1]=-1;
// 设开始点和结束点
Position start;
start.row=1;
start.col=1;
cout<<"布线起点"<<endl;
cout<<start.col<<" "<<start.row<<endl;
Position finish;
finish.row=3;
finish.col=4;
cout<<"布线结束点"<<endl;
cout<<finish.row<<" "<<finish.col<<endl;
int PathLen=0;
Position *path;
cout<<"布线前"<<endl;
showPath();
FindPath(start,finish,PathLen,path);
cout<<"布线后"<<endl;
showPath();
cout<<"路径"<<endl;
for(int i=0; i<PathLen; i++)
{
cout<<path[i].row<<" "<<path[i].col<<endl;
}
return 0;
}