问题描述
印刷电路板将布线区域划分成n×m个方格如图a所示。精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线,如图b所示。为了避免线路相交,已布了线的方格做了封锁标记,其它线路不允穿过被封锁的方格。
一个布线的例子:图中包含障碍。起始点为a,目标点为b。
算法思想
解此问题的队列式分支限界法从起始位置a开始将它作为第一个扩展结点。与该扩展结点相邻并且可达的方格成为可行结点被加入到活结点队列中,并且将这些方格标记为1,即从起始方格a到这些方格的距离为1。
接着,算法从活结点队列中取出队首结点作为下一个扩展结点,并将与当前扩展结点相邻且未标记过的方格标记为2,并存入活结点队列。这个过程一直继续到算法搜索到目标方格b或活结点队列为空时为止。即加入剪枝的广度优先搜索。
算法具体代码如下:
1、Queue.h
#includeusing namespace std;template class Queue{ public: Queue(int MaxQueueSize=50); ~Queue(){delete [] queue;} bool IsEmpty()const{return front==rear;} bool IsFull(){return ( ( (rear+1) %MaxSize==front )?1:0);} T Top() const; T Last() const; Queue & Add(const T& x); Queue & AddLeft(const T& x); Queue & Delete(T &x); void Output(ostream& out)const; int Length(){return (rear-front);} private: int front; int rear; int MaxSize; T *queue;};template Queue ::Queue(int MaxQueueSize){ MaxSize=MaxQueueSize+1; queue=new T[MaxSize]; front=rear=0;}template T Queue ::Top()const{ if(IsEmpty()) { cout<<"queue:no element,no!"< T Queue ::Last()const{ if(IsEmpty()) { cout<<"queue:no element"< Queue & Queue ::Add(const T& x){ if(IsFull())cout<<"queue:no memory"< Queue & Queue ::AddLeft(const T& x){ if(IsFull())cout<<"queue:no memory"< Queue & Queue ::Delete(T & x){ if(IsEmpty())cout<<"queue:no element(delete)"< void Queue ::Output(ostream& out)const{ for(int i=rear%MaxSize;i>=(front+1)%MaxSize;i--) out< ostream& operator << (ostream& out,const Queue & x){x.Output(out);return out;}
2、6d4.cpp
//布线问题 队列式分支限界法求解 #include "stdafx.h"#include "Queue.h"#include#include using namespace std;ifstream fin("6d4.txt"); const int n = 7;const int m = 7;int grid[n+2][m+2]; struct Position { int row; int col; }; bool FindPath(Position start,Position finish,int& PathLen,Position *&path);int main(){ int PathLen; Position start,finish,*path; start.row = 3; start.col = 2; finish.row = 4; finish.col = 6; cout<<"布线起点"< >grid[i][j]; cout< <<" "; } cout< Q; do {//标记相邻可达方格 for(int i=0; i =0; j--) { path[j]=here;//找前驱位置 for(int i=0; i
程序运行结果如图: