算法分析与设计.docx
- 文档编号:24656942
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:16
- 大小:187.26KB
算法分析与设计.docx
《算法分析与设计.docx》由会员分享,可在线阅读,更多相关《算法分析与设计.docx(16页珍藏版)》请在冰豆网上搜索。
算法分析与设计
算法分析与设计
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); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 分析 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)