分支限界 java_0035算法笔记——【分支限界法】布线问题
问题描述
印刷电路板将布线区域划分成n×m个方格如图a所示。精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线,如图b所示。为了避免线路相交,已布了线的方格做了封锁标记,其它线路不允穿过被封锁的方格。
一个布线的例子:图中包含障碍。起始点为a,目标点为b。
算法思想
解此问题的队列式分支限界法从起始位置a开始将它作为第一个扩展结点。与该扩展结点相邻并且可达的方格成为可行结点被加入到活结点队列中,并且将这些方格标记为1,即从起始方格a到这些方格的距离为1。
接着,算法从活结点队列中取出队首结点作为下一个扩展结点,并将与当前扩展结点相邻且未标记过的方格标记为2,并存入活结点队列。这个过程一直继续到算法搜索到目标方格b或活结点队列为空时为止。即加入剪枝的广度优先搜索。
算法具体代码如下:
1、Queue.h
#include
using 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<
return 0;
}
else return queue[(front+1) % MaxSize];
}
template
T Queue ::Last()const
{
if(IsEmpty())
{
cout<
return 0;
}
else return queue[rear];
}
template
Queue& Queue::Add(const T& x)
{
if(IsFull())cout<
else
{
rear=(rear+1)% MaxSize;
queue[rear]=x;
}
return *this;
}
template
Queue& Queue::AddLeft(const T& x)
{
if(IsFull())cout<
else
{
front=(front+MaxSize-1)% MaxSize;
queue[(front+1)% MaxSize]=x;
}
return *this;
}
template
Queue& Queue ::Delete(T & x)
{
if(IsEmpty())cout<
else
{
front=(front+1) % MaxSize;
x=queue[front];
}
return *this;
}
template
void Queue ::Output(ostream& out)const
{
for(int i=rear%MaxSize;i>=(front+1)%MaxSize;i--)
out<
}
template
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<
cout<
cout<
cout<
cout<
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
{
fin>>grid[i][j];
cout<
}
cout<
}
FindPath(start,finish,PathLen,path);
cout<
cout<
for(int i=0; i
{
cout<
}
return 0;
}
bool FindPath(Position start,Position finish,int& PathLen,Position *&path)
{
//计算从起始位置start到目标位置finish的最短布线路径
if((start.row == finish.row) && (start.col == finish.col))
{
PathLen = 0;
return true;
}
//设置方格阵列“围墙”
for(int i=0; i<= m+1; i++)
{
grid[0][i]=grid[n+1][i]=1; //顶部和底部
}
for(int i=0; i<= n+1; i++)
{
grid[i][0]=grid[i][m+1]=1; //左翼和右翼
}
//初始化相对位移
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]=2;//标记可达方格位置
Queue Q;
do {//标记相邻可达方格
for(int i=0; i
{
nbr.row=here.row + offset[i].row;
nbr.col=here.col+offset[i].col;
if(grid[nbr.row][nbr.col]==0)//该方格未被标记
{
grid[nbr.row][nbr.col]=grid[here.row][here.col]+1;
if((nbr.row==finish.row) && (nbr.col==finish.col))
{
break; //完成布线
}
Q.Add(nbr);
}
}
//是否到达目标位置finish?
if((nbr.row==finish.row) && (nbr.col==finish.col))
{
break;//完成布线
}
//活结点队列是否非空?
if(Q.IsEmpty())
{
return false;//无解
}
Q.Delete(here);//取下一个扩展结点
}while(true);
//构造最短布线路径
PathLen=grid[finish.row][finish.col]-2;
path=new Position[PathLen];//从目标位置finish开始向起始位置回溯
here=finish;
for(int j=PathLen-1; j>=0; j--)
{
path[j]=here;//找前驱位置
for(int i=0; i
{
nbr.row=here.row+offset[i].row;
nbr.col=here.col+offset[i].col;
if(grid[nbr.row][nbr.col]==j+2)
{
break;
}
}
here=nbr;//向前移动
}
return true;
}
程序运行结果如图:
分支限界 java_0035算法笔记——【分支限界法】布线问题相关推荐
- 分支限界法 01背包c语言,算法笔记分支限界法01背包问题
<算法笔记分支限界法01背包问题>由会员分享,可在线阅读,更多相关<算法笔记分支限界法01背包问题(12页珍藏版)>请在人人文库网上搜索. 1.问题描述给定n种物品和一背包.物 ...
- 《算法笔记》中文版 - 包括数组,链表,树,图,递归,DP,有序表等相关数据结构与算法的讲解及代码实现...
来源:专知本文为资源,建议阅读5分钟本文为你分享<算法笔记>中文版. https://github.com/Dairongpeng/algorithm-note 目录概览 第一节 复杂度. ...
- 数据结构与算法笔记 - 绪论
数据结构与算法笔记 - 绪论 1. 什么是计算 2. 评判DSA优劣的参照(直尺) 3. 度量DSA性能的尺度(刻度) 4. DSA的性能度量的方法 5. DSA性能的设计及其优化 x1. 理论模型与 ...
- 数据结构与算法笔记(十六)—— 二叉搜索树
一.二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: 若左子树不为空,则左子树上所有节点的 ...
- 数据结构与算法笔记(十五)—— 散列(哈希表)
一.前沿 1.1.直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.假设某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,-,m-1)的关键字,此处m是一个不很大 ...
- 《algorithm-note》算法笔记中文版正式发布!
无论是做机器学习.深度学习.自然语言处理还是其它领域,算法的重要性不言而喻!吃透算法底层原理.掌握算法数学推导和代码实现,对提高自己的硬核实力来说非常重要!今天给大家推荐一个超赞的开源算法笔记!中文版 ...
- 【算法】《algorithm-note》算法笔记中文版正式发布!
无论是做机器学习.深度学习.自然语言处理还是其它领域,算法的重要性不言而喻!吃透算法底层原理.掌握算法数学推导和代码实现,对提高自己的硬核实力来说非常重要!今天给大家推荐一个超赞的开源算法笔记!中文版 ...
- c++ string 删除字符_算法笔记|(5)第二章C、C++的快速入门字符数组的存放方式string.h文件...
字符数组的存放方式 由于字符数组是由若干个char类型的元素组成的,因此字符数组的每一位都是一个char字符,除此之外,在一维字符数组或者二维字符数组的第二维的末尾都有一个空字符\0表示存放的字符串的 ...
- 算法笔记(JavaScript版)——排序
算法笔记(JavaScript版)--排序 本文内容根据Rebert Sedgewick和Kevin Wayne的<算法(第四版)>整理,原代码为java语言,自己修改为JavaScrip ...
- 三维重建7:Visual SLAM算法笔记
VSLAM研究了几十年,新的东西不是很多,三维重建的VSLAM方法可以用一篇文章总结一下. 此文是一个好的视觉SLAM综述,对视觉SLAM总结比较全面,是SLAM那本书的很好的补充.介绍了基于滤波器的 ...
最新文章
- shiro学习总结(一)----初识shiro
- 如何学好C、C++------思维方式的转变
- matlab仿真软件 高阶调制,高阶差分幅度相移键控调制解调系统及仿真
- centos安装 TA-Lib
- cookie、Session、Token、sessionStorage、localStorage简介__Token放在 cookie, sessionStorage 和 localStorage中区别
- 2020级C语言大作业 - 王国保卫战
- SpringBoot数据访问Mybatis注解版,配置版,注解与配置一体版
- ActiveX控件属性
- clearcanvas解析
- 数据分析师——软件篇
- 女人总浑身都没有力气怎么回事儿
- 手握IP却不知如何讲好城市故事?“宝藏天津”慢直播支招城市营销
- 王道考研数据结构之------循环单链表
- Java SSL实现使用详解
- C++ priority_queue 用法详解
- 太原用计算机单位的工资,太原个税计算器_太原税后月薪|工资计算器_太原个人所得税查询 - Tax518...
- Job和CronJob介绍
- 家庭数据中心-私有云服务器定义和选择
- python求解组合数_6-2 jmu-python-组合数据类型-1.计算坐标点欧氏距离 (10分)
- 复旦女博士被“送”5篇论文后要分手,代写情夫自杀?复旦大学深夜回应!