拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx

上传人:b****6 文档编号:5920998 上传时间:2023-01-02 格式:DOCX 页数:18 大小:18.57KB
下载 相关 举报
拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx_第1页
第1页 / 共18页
拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx_第2页
第2页 / 共18页
拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx_第3页
第3页 / 共18页
拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx_第4页
第4页 / 共18页
拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx

《拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx》由会员分享,可在线阅读,更多相关《拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx(18页珍藏版)》请在冰豆网上搜索。

拉斯维加斯算法结合分枝限界算法解决电路板布线问题.docx

拉斯维加斯算法结合分枝限界算法解决电路板布线问题

拉斯维加斯算法结合分枝限界算法解决电路板布线问题

一、算法说明:

拉斯维加斯算法的一个显著特征是它所作的随机性决策有可能导致算法找不到所需的解。

由于这个算法比较难懂,没有思路编写。

于是就先学习--LasVegas算法解决N皇后问题,LasVegas解决N皇后问题是采用随机放置位置策略和结合分枝限界相结合。

综合解决方案电路板布线问题采用了机放置位置策略和结合分枝限界相结合的方式来解决。

关键代码如下:

* 标号处:

这里是当前点相邻四个点是否可以放置,如果可以放置用selectPostion保存下来,并用num记录有多少个位置可以放置。

 

* 标号处:

这里利用上面保存的可以放置的点,然后随机取其中一个加入队列。

这就是Las Vegas的精髓!

 

* 标号处:

是初始化时间种子,是随机选择的关键,这个虽然简单,但是由于随机函数不了解,造成了很大伪随机。

srand((unsigned)time(NULL));//初始化时间种子----------

intnum=0;//方格未标记个数

PositionselectPostion[5];//选择可以到达位置保存

for(inti=0;i

{

//达到四个方向

nbr.row=here.row+offset[i].row;

nbr.col=here.col+offset[i].col;

if(grid[nbr.row][nbr.col]==-1)

{

//该方格未标记

grid[nbr.row][nbr.col]=grid[here.row][here.col]+1;

if((nbr.row==finish.row)&&(nbr.col==finish.col))

break;

selectPostion[num].row=nbr.row;----------

selectPostion[num].col=nbr.col;

num++;

}

}

if(num>0)//如果标记,则在这么多个未标记个数中随机选择一个位置

//将这个邻居入队

q_FindPath.push(selectPostion[rand()%(num)]);----------

二、结果分析

红色字表示输入

蓝色字表示输出结果

运行时间表示算法复杂度

1)样例一:

3*3棋盘

---------分支限界法之布线问题--------

在一个m*n的棋盘上,请分别输入m和n,代表行数和列数,然后输入回车

33(回车)

初始化棋盘格和加围墙

-------------------------------

-2-2-2-2-2

-2-1-1-1-2

-2-1-1-1-2

-2-1-1-1-2

-2-2-2-2-2

-------------------------------

请输入已经占据的位置行坐标列坐标,代表此位置不能布线

例如输入22表示坐标22不能布线;当输入的坐标为00表示结束输入

21(回车)

23(回车)

33(回车)

00(回车)

布线前的棋盘格

-------------------------------

-2-2-2-2-2

-2-1-1-1-2

-2-3-1-3-2

-2-1-1-3-2

-2-2-2-2-2

-------------------------------

请输入起点位置坐标

11(回车)

请输入终点位置坐标

31(回车)

没有找到路线,第1次尝试

没有找到路线,第2次尝试

没有找到路线,第3次尝试

-------------------------------

$代表围墙

#代表已经占据的点

*代表布线路线

=代表还没有布线的点

-------------------------------

$$$$$

$**=$

$#*#$

$**#$

$$$$$

-------------------------------

路径坐标和长度

(1,1)(1,2)(2,2)(3,2)(3,1)

路径长度:

5

布线完毕,查找4次

运行时间:

12ms

2)样例二:

5*5棋盘

---------分支限界法之布线问题--------

在一个m*n的棋盘上,请分别输入m和n,代表行数和列数

55(回车)

初始化棋盘格和加围墙

-------------------------------

-2-2-2-2-2-2-2

-2-1-1-1-1-1-2

-2-1-1-1-1-1-2

-2-1-1-1-1-1-2

-2-1-1-1-1-1-2

-2-1-1-1-1-1-2

-2-2-2-2-2-2-2

-------------------------------

请输入已经占据的位置行坐标列坐标,代表此位置不能布线

例如输入22表示坐标22不能布线;当输入的坐标为00表示结束输入

31(回车)

32(回车)

34(回车)

35(回车)

45(回车)

00(回车)

布线前的棋盘格

-------------------------------

-2-2-2-2-2-2-2

-2-1-1-1-1-1-2

-2-1-1-1-1-1-2

-2-3-3-1-3-3-2

-2-1-1-1-1-3-2

-2-1-1-1-1-1-2

-2-2-2-2-2-2-2

-------------------------------

请输入起点位置坐标

11(回车)

请输入终点位置坐标

52(回车)

没有找到路线,第1次尝试

没有找到路线,第2次尝试

没有找到路线,第3次尝试

没有找到路线,第4次尝试

没有找到路线,第5次尝试

没有找到路线,第6次尝试

-------------------------------

$代表围墙

#代表已经占据的点

*代表布线路线

=代表还没有布线的点

-------------------------------

$$$$$$$

$*====$

$***==$

$##*##$

$==*=#$

$=**==$

$$$$$$$

-------------------------------

路径坐标和长度

(1,1)(2,1)(2,2)(2,3)(3,3)(4,3)(5,3)(5,2)

路径长度:

8

布线完毕,查找7次

运行时间:

16ms

 

3)样例三:

10*10棋盘

---------分支限界法之布线问题--------

在一个m*n的棋盘上,请分别输入m和n,代表行数和列数

1010(回车)

初始化棋盘格和加围墙

-------------------------------

-2-2-2-2-2-2-2-2-2-2-2-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-2-2-2-2-2-2-2-2-2-2-2

-------------------------------

请输入已经占据的位置行坐标列坐标,代表此位置不能布线

例如输入22表示坐标22不能布线;当输入的坐标为00表示结束输入

51(回车)

52(回车)

53(回车)

54(回车)

55(回车)

57(回车)

58(回车)

59(回车)

00(回车)

布线前的棋盘格

-------------------------------

-2-2-2-2-2-2-2-2-2-2-2-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-3-3-3-3-3-1-3-3-3-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-1-1-1-1-1-1-1-1-1-1-2

-2-2-2-2-2-2-2-2-2-2-2-2

-------------------------------

请输入起点位置坐标

11(回车)

请输入终点位置坐标

99(回车)

没有找到路线,第1次尝试

没有找到路线,第2次尝试

没有找到路线,第3次尝试

没有找到路线,第4次尝试

没有找到路线,第5次尝试

没有找到路线,第6次尝试

没有找到路线,第7次尝试

-------------------------------

$代表围墙

#代表已经占据的点

*代表布线路线

=代表还没有布线的点

-------------------------------

$$$$$$$$$$$$

$*=====**==$

$**********$

$=========*$

$=====*****$

$#####*###=$

$=====*====$

$=====*====$

$=====*====$

$=====****=$

$==========$

$$$$$$$$$$$$

-------------------------------

路径坐标和长度

(1,1)(2,1)(2,2)(2,3)(2,4)(2,5)(2,6)(2,7)(1,7)(1,8)(2,8)(2,9)(2,10)(3,10)(4,10)(4,9)(4,8)(4,7)(4,6)(5,6)(6,6)(7,6)(8,6)(9,6)(9,7)(9,8)(9,9)

路径长度:

27

布线完毕,查找8次

运行时间:

31ms

代码:

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

//表示方格上位置的结构体

structPosition

{

introw;

intcol;

};

//分支限界算法

boolFindPath(Positionstart,Positionfinish,int&PathLen,Position*&path,int**grid,intm,intn)

{

//找到最短布线路径,则返回真,否则返回假

//起点和终点想同,不用布线

if((start.row==finish.row)&&start.col==finish.col)

{

PathLen=0;

returntrue;

}

 

//设置方向移动坐标值:

东、南、西、北

Positionoffset[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;//上

//相邻的方格数

intNumNeighBlo=4;

Positionhere,nbr;

//设置当前方格,即搜索单位

here.row=start.row;

here.col=start.col;

//由于0和1用于表示方格的开放和封锁,故距离:

2-03-1

grid[start.row][start.col]=0;//-2表示强-1表示可行-3表示不能当作路线

//队列式搜索,标记可达相邻方格

queueq_FindPath;

do

{

intnum=0;//方格未标记个数

PositionselectPostion[5];//选择位置保存

for(inti=0;i

{

//达到四个方向

nbr.row=here.row+offset[i].row;

nbr.col=here.col+offset[i].col;

if(grid[nbr.row][nbr.col]==-1)

{

//该方格未标记

grid[nbr.row][nbr.col]=grid[here.row][here.col]+1;

if((nbr.row==finish.row)&&(nbr.col==finish.col))

break;

selectPostion[num].row=nbr.row;

selectPostion[num].col=nbr.col;

num++;

}

}

//printf("---------%lld\n",num);

if(num>0)//如果标记,则在这么多个未标记个数中随机选择一个位置

//随机选一个入队

//printf("---------%d\n",rand()%(num));

q_FindPath.push(selectPostion[rand()%(num)]);

//是否到达目标位置finish

if((nbr.row==finish.row)&&(nbr.col==finish.col))

break;

//活结点队列是否为空

if(q_FindPath.empty())returnfalse;//无解

//访问对首元素出队

here=q_FindPath.front();

q_FindPath.pop();

 

}while(true);

//构造最短布线路径

PathLen=grid[finish.row][finish.col];

path=newPosition[PathLen];//路径

//从目标位置finish开始向起始位置回溯

here=finish;

for(intj=PathLen-1;j>=0;j--)

{

path[j]=here;

//找前驱位置

for(inti=0;i<=NumNeighBlo;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;

}

returntrue;

}

intmain()

{

cout<<"---------分支限界法之布线问题--------"<

intpath_len;

intpath_len1;

intm,n;

Position*path;

Position*path1;

Positionstart,finish;

Positionstart1,finish1;

cout<<"在一个m*n的棋盘上,请分别输入m和n,代表行数和列数,然后输入回车"<

cin>>m>>n;

//创建棋盘格

int**grid=newint*[m+2];

int**grid1=newint*[m+2];

for(inti=0;i

{

grid[i]=newint[n+2];

grid1[i]=newint[n+2];

}

//初始化棋盘格

for(inti=1;i<=m;i++)

{

for(intj=1;j<=n;j++)

{

grid[i][j]=-1;

}

}

//设置方格阵列的围墙

for(inti=0;i<=n+1;i++){

grid[0][i]=grid[m+1][i]=-2;//上下的围墙

}

for(inti=0;i<=m+1;i++){

grid[i][0]=grid[i][n+1]=-2;//左右的围墙

}

cout<<"初始化棋盘格和加围墙"<

cout<<"-------------------------------"<

for(inti=0;i

{

for(intj=0;j

{

cout<

}

cout<

}

cout<<"-------------------------------"<

 

cout<<"请输入已经占据的位置行坐标列坐标,代表此位置不能布线"<

cout<<"例如输入22(然后输入回车),表示坐标22不能布线;当输入的坐标为00(然后输入回车)表示结束输入"<

 

//添加已经布线的棋盘格

while(true)

{

intci,cj;

cin>>ci>>cj;

if(ci>m||cj>n)

{

cout<<"输入非法";

cout<<"行坐标<"<

continue;

}elseif(ci==0||cj==0){

break;

}else{

grid[ci][cj]=-3;

}

}

 

//布线前的棋盘格

cout<<"布线前的棋盘格"<

cout<<"-------------------------------"<

for(inti=0;i

{

for(intj=0;j

{

cout<

}

cout<

}

cout<<"-------------------------------"<

 

cout<<"请输入起点位置坐标"<

cin>>start.row>>start.col;

cout<<"请输入终点位置坐标"<

cin>>finish.row>>finish.col;

DWORDstartTime,stopTime;

startTime=GetTickCount();//程序开始时间

srand((unsigned)time(NULL));

inttime=0;//为假设运行次数

//初始值值拷贝

start1=start;

finish1=finish;

path_len1=path_len;

path1=NULL;

for(inti=0;i

{

for(intj=0;j

{

grid1[i][j]=grid[i][j];

}

}

boolresult=FindPath(start1,finish1,path_len1,path1,grid1,m,n);

while(result==0&&time<100){

//初始值值拷贝

start1=start;

finish1=finish;

path_len1=path_len;

path1=NULL;

for(inti=0;i

{

for(intj=0;j

{

grid1[i][j]=grid[i][j];

}

}

time++;

cout<

cout<<"没有找到路线,第"<

result=FindPath(start1,finish1,path_len1,path1,grid1,m,n);

}

stopTime=GetTickCount();//程序结束时间

if(result)

{

cout<<"-------------------------------"<

cout<<"$代表围墙"<

cout<<"#代表已经占据的点"<

cout<<"*代表布线路线"<

cout<<"=代表还没有布线的点"<

cout<<"-------------------------------"<

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1