算法分析与设计.docx

上传人:b****4 文档编号:24656942 上传时间:2023-05-29 格式:DOCX 页数:16 大小:187.26KB
下载 相关 举报
算法分析与设计.docx_第1页
第1页 / 共16页
算法分析与设计.docx_第2页
第2页 / 共16页
算法分析与设计.docx_第3页
第3页 / 共16页
算法分析与设计.docx_第4页
第4页 / 共16页
算法分析与设计.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

算法分析与设计.docx

《算法分析与设计.docx》由会员分享,可在线阅读,更多相关《算法分析与设计.docx(16页珍藏版)》请在冰豆网上搜索。

算法分析与设计.docx

算法分析与设计

 

算法分析与设计

 

2015~2016学年第二学期

 

学院

专业

学号

姓名

指导教师

 

A*算法解决旅行商问题

1、问题描述

旅行商问题:

给定一个完全无向带权图G=(V,E),其每条边(u,v)∈E有一非负整数权值w(u,v)。

要求找出G的一条经过每个顶点一次且仅经过一次的回路,使得该回路上所有边的权值之和尽可能地小。

2、算法分析及流程图

1、算法概述

A*算法是基于估价函数f(x)的一种加权状态图启发式搜索算法。

A*算法的核心是估价函数f(n)它包括g(n)和h(n)两部分。

g(n)是已经走过的代价h(n)是n到目标的估计代价。

A算法限制其估价函数中的启发函数h(x)满足对所有的节点x均有h(x)≤h*(x)其中h*(x)是从节点x到目标节点的最小代价(若有多个目标节点则为其中最小的一个)[1]。

2、A*算法伪代码

Best_First_Search() 

Open = [起始节点]; 

Closed = []; 

 while (Open表非空) 

 { 

  从Open中取得一个节点X,并从OPEN表中删除。

 

  if(X是目标节点) 

  { 

   求得路径PATH;返回路径PATH; 

  } 

  for(每一个X的子节点Y) 

  { 

   if(Y不在OPEN表和CLOSE表中) 

   { 

    求Y的估价值; 并将Y插入OPEN表中; 

   } //还没有排序 

   else if (Y在OPEN表中) 

   { 

    if(Y的估价值小于OPEN表的估价值) 更新OPEN表中的估价值; 

   } 

   else //Y在CLOSE表中 

   { 

    if (Y的估价值小于CLOSE表的估价值) [2]

    { 

     更新CLOSE表中的估价值; 

从CLOSE表中移出节点,并放入OPEN表中; 

    } 

   } 将X节点插入CLOSE表中; 按照估价值将OPEN表中的节点排序; 

  }//end for 

 }//end while 

}//end func 

3、A*算法对旅行商问题分析

以城市数5为例具体分析:

(1)输入城市数,以及城市间代权。

首先旅行商选择A->C,即表中现在有了2个元素(A,C),接下来判断下一节点的选择需要依据f(B)f(D)f(E)的大小,优先选择小的。

据分析在下一步走完的时候,旅行商已经到过3个城市,即现行状态表的元素个数均为3,距离目标还有3个城市,包括返回A的路程,根据输入数据,我们假设剩下三个城市的平均距离等于最小距离8,则从B、D、E到达目标付出的代价不小于3*8=24,即h(B)=h(D)=h(E)=24,代入函数求f。

依据公式

f(B)=g(B)+h(B)=31+24=55

f(D)=g(D)+h(D)=27+24=51

f(E)=g(E)+h(E)=29+24=53

由此得到旅行商下一步要走向D城市,所设函数为

h=(目标状态表元素-现行状态表的元素数)*k

K为一个系数,如k取两城市间最小,且h

4、算法流程图

3、关键代码及实验结果

1、关键代码

boolAStar(NodeState&node,Mapmap)

{

//递归出口

if(node.cityNum==map.num)//路径满

{

node.roadLen+=getLen(node.city,0,map);

returnfalse;

}

intl=map.num-node.cityNum;//剩下的城市数

int*nextCitys=(int*)malloc(sizeof(int)*l);

getNext(node.road,nextCitys,map.num);//得到剩下城市名(索引)

//初始化子节点

for(inti=0;i

{

node.children[i]=(NodeState*)malloc(sizeof(NodeState));

//分配一个子节点内存

initNode(node.children[i],map.num);//初始化子节点

cpyRoad(node.children[i]->road,node.road,map.num);

//获得之前走过的路径

node.children[i]->road[nextCitys[i]]=node.cityNum+1;

//在路径上加上该子节点

node.children[i]->city=nextCitys[i];

node.children[i]->cityNum=node.cityNum+1;//该节点顺位

node.children[i]->roadLen=node.roadLen+getLen(node.city,node.children[i]->city,map);//新的路径长度

node.children[i]->f=node.children[i]->roadLen+nearest(node.road,map);//计算估价值最后一个节点f值不准

}//根据估价值排序

sortNode(&node,l);

//向下搜索

booltoFind=true;//是否继续搜索

for(inti=0;i

{

if(toFind)//发现结果就不用继续递归了

toFind=AStar(*node.children[i],map);

}

returntoFind;

}

2、运行结果

(1)城市数为3

(2)城市数为5

4、总结

通过使用A*算法对旅行商问题的探究, 了解学习了A*这种智能算法A*算法在理论上目前是解决最短路径时间最优的,但是也有缺点:

它的空间增长是指数级别的。

但确切来讲,A*算法只能求解较优的解,并比一定是最优的,A*算法具有高效性。

5、参考文献

[1]李祥,A*算法2007

[2]雷德明,严新平 .多目标智能优化算法及其应用[M].2009.科学出版社

6、附录代码

头文件:

Astar.h

//********************************************

//代码目的:

用A*算法解决旅行商问题

//

//估价函数:

f=g+h其中g为该节点走过的路程,h为未走过的节点到起点(终点)距离中最短的那个

//

//实现的几个关键数据结构:

//路径用NodeState中的road数组表示ABCDEF。

对应于数组的索引012345。

,数组内容表示路径顺序,若没走过定义为0

//各个城市之间的距离用Map中的rec一维数组表示,这里i城市到j城市距离为rec[j*n+i]只使用下半矩阵(副对角线)i

//********************************************

#ifndefASTAR_H

#defineASTAR_H

#include

#include

#include

#defineSTRING"ABCDEFGHIJKLNMOPQRSTUVWXYZ"

#defineMAXNUM2000

//状态节点

typedefstructNodeState{

int*road;//路径

introadLen;//走过的路程

intf;//估价函数

intcityNum;//所走的城市的数目

intcity;//该节点代表的城市

NodeState**children;//指向子节点列表的指针

}NodeState;

//各个城市之间的距离矩阵

typedefstructMap{

intnum;//城市的个数

int*rec;//距离矩阵用一维表示二维

}Map;

//初始化节点初始化所有参数,对子节点列表和road设置长度

voidinitNode(NodeState*node,intn);

//A*算法主体调用完成后构造出一颗最优解搜索树

boolAStar(NodeState&node,Mapmap);

//获得下个城市可能的所有编号为road的大小

voidgetNext(introad[],intnextCitys[],intn);

//获得剩下路径到终点最近的距离

intnearest(introad[],Mapmap);//

//获得两个城市之间的距离

intgetLen(inti,intj,Mapmap);

//输入获得距离矩阵

MapinputMap();

//复制路径复制数组

voidcpyRoad(intdis[],intsrc[],intlen);

//根据估价值排序

voidsortNode(NodeState*p,intl);

#endif

display.h

#ifndefDISPLAY_H

#defineDISPLAY_H

#include"Astar.h"

voidshowRoad(int*road,intn)

{

int*sort=(int*)malloc(sizeof(int)*n);

for(inti=0;i

{

sort[road[i]-1]=i;//按照顺序排位

}

for(inti=0;i

{

printf("%c->",STRING[sort[i]]);

}

printf("A\n");

}

voiddisplay(NodeStatehead,intn)

{

if(head.cityNum==n)//找到最后的节点

{

showRoad(head.road,n);

printf("路径总代价为:

%d\n",head.roadLen);

}

for(inti=0;i

{

if(head.children[i]!

=NULL)

{

display(*head.children[i],n);

}

}

}

#endif

 

源文件

Astar.cpp

#include"Astar.h"

//根据估价值排序

voidsortNode(NodeState*p,intl)

{

intn=l;

for(inti=0;i

{

for(intj=0;j

{

if((p->children[j]->f)>(p->children[j+1]->f))

{

NodeState*temp=p->children[j];

p->children[j]=p->children[j+1];

p->children[j+1]=temp;

}

}

}

}

voidcpyRoad(intdis[],intsrc[],intlen)

{

for(inti=0;i

dis[i]=src[i];

}

intgetLen(inti,intj,Mapmap)

{

returni

map.rec[i+j*map.num]:

map.rec[j+i*map.num];

}

voidinitNode(NodeState*node,intn)

{

node->road=(int*)malloc(sizeof(int)*n);//分配路径

for(inti=0;i

node->road[i]=0;

node->f=node->roadLen=0;

node->cityNum=n;

node->children=(NodeState**)malloc(sizeof(NodeState*)*n-1);//最多的子节点数目

for(inti=0;i

node->children[i]=NULL;

}

voidgetNext(introad[],intnextCitys[],intn)

{

intj=0;

for(inti=0;i

{

if(!

road[i])//没走过

{

nextCitys[j]=i;

j++;

}

}

}

MapinputMap()

{

Mapmap;

intn=0;

printf("获得距离矩阵,先输入城市数目:

");

scanf("%d",&n);

getchar();

map.num=n;

map.rec=(int*)malloc(sizeof(int)*n*n);//n方

printf("输入数据:

\n");

for(inti=0;i

for(intj=i+1;j

{

printf("%c->%c:

",STRING[i],STRING[j]);

scanf("%d",&(map.rec[i+j*n]));

getchar();

}

returnmap;

}

intnearest(introad[],Mapmap)

{

intmin=MAXNUM;

boolflag=false;//判断是否还有没走过节点

for(inti=0;i

{

if(!

road[i])//没走过

{

flag=true;

intlen=getLen(0,i,map);//第i个城市到终点距离上层保证i>0

if(len

min=len;

}

}

if(!

flag)

return0;

returnmin;

}

boolAStar(NodeState&node,Mapmap)

{

//递归出口

if(node.cityNum==map.num)//路径满

{

node.roadLen+=getLen(node.city,0,map);

returnfalse;

}

intl=map.num-node.cityNum;//剩下的城市数

int*nextCitys=(int*)malloc(sizeof(int)*l);

getNext(node.road,nextCitys,map.num);//得到剩下城市名(索引)

//初始化子节点

for(inti=0;i

{

node.children[i]=(NodeState*)malloc(sizeof(NodeState));//分配一个子节点内存

initNode(node.children[i],map.num);//初始化子节点

cpyRoad(node.children[i]->road,node.road,map.num);//获得之前走过的路径

node.children[i]->road[nextCitys[i]]=node.cityNum+1;//在路径上加上该子节点

node.children[i]->city=nextCitys[i];

node.children[i]->cityNum=node.cityNum+1;//该节点顺位

node.children[i]->roadLen=node.roadLen+getLen(node.city,node.children[i]->city,map);//新的路径长度

node.children[i]->f=node.children[i]->roadLen+nearest(node.road,map);//计算估价值最后一个节点f值不准

}

//根据估价值排序

sortNode(&node,l);

//向下搜索

booltoFind=true;//是否继续搜索

for(inti=0;i

{

if(toFind)//发现结果就不用继续递归了

toFind=AStar(*node.children[i],map);

}

returntoFind;

}

 

main.cpp

#include"Astar.h"

#include"display.h"

voidmain()

{

//构建地图

Mapm=inputMap();

//初始化头节点

NodeStatehead;

initNode(&head,m.num);

head.city=0;

head.cityNum=1;

head.roadLen=0;

head.road[0]=1;

//开始A*算法

AStar(head,m);

///显示结果

display(head,m.num);

}

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

当前位置:首页 > 小学教育 > 小升初

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

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