分支限界法——印刷电路板问题

实验内容:

印刷电路板将布线区域划分成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;
}
  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值