启发式算法-A*算法
来源:互联网 发布:we淘宝官方旗舰店 编辑:程序博客网 时间:2024/06/06 21:03
A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法
A算法公式表示为: f(n)=g(n)+h(n)
其中
- f(n) 是从初始点经由节点n到目标点的估价函数
- g(n) 是在状态空间中从初始节点到n节点的实际代价
- h(n) 是从n到目标节点最佳路径的估计代价
启发信息给得越多(估价函数值越大),则A算法需要搜索处理的状态数就越少,效率就越高。但并不是估计值越大越好,有时估价函数值太大会使A算法不一定搜索到最优解。
此时可引入A*算法公式:f*(n) = g* (n) + h* (n)
其中
- g* (n)是从初始结点到n结点的最短路径代价
- h* (n)是从n结点到目的结点的最佳路径代价
当我们要求估价函数f(n)中的h(n)都小于等于h*(n)即: h(n) <=h*(n)时 A搜索算法就成为A*搜索算法,所得路径为最优路径。
如某一问题有解,那么利用A*搜索算法对该问题进行搜索则一定能搜索到解,并且一定能搜索到最优的解而结束!
问题分析:从节点A开始搜索至#节点,该节点对应的h* (n)即为该城市到目标城市的直线距离(即最佳路径代价),从A点到#节点走过的实际距离(即最短路径代价)则为g* (n)。每次搜索节点查找最小的g* (n) + h* (n)。
#include<stdio.h>#include<stdio.h>#include<stdlib.h>#include<string>int city_num=0;//城市数目int g[100][100];//存储城市间实际距离的邻接矩阵int closeNum=0;//close表大小int track[100];//行驶路径int tra_num=0;//途径城市的数目typedef struct node//代表城市的结构体 { int data; //城市名 int num;//估价函数值 struct node *next; //存储下一个结点的地址 int fa;//上一个城市 }LinkList;typedef struct distance { char city; int dist; }dis;//存储实际距离和数字与城市名的对应关系dis h[100];LinkList *head,*p,*q;void INITLIST(LinkList *L){ // L=(LinkList*)malloc(sizeof(LinkList)); //判断是否申请成功 if(!L){ printf("无内存空间可分配");exit(0);} L->next=NULL;} //INITLIST LinkList close[100];//close表void Init()//初始化,主要是将文件中的内容读入{ FILE *stream=fopen("text.txt","r"); int initNum=0;//城市数目 if(stream==NULL) printf("The file fscanf.out was not opened\n"); else { while(fscanf(stream,"%d%c",&h[initNum].dist,&h[initNum].city) !=EOF){//h数组存储各城市到达目标城市的直线距离 initNum++; } city_num=initNum; fclose(stream); } FILE *stream2=fopen("map.txt","r"); //int initNum=0; if(stream2==NULL) printf("The file fscanf.out was not opened\n"); else { for(int i=0;i<initNum;i++){ for(int j=0;j<initNum;j++){ if(fscanf(stream,"%d",&g[i][j]) !=EOF) //initNum++; continue; } } fclose(stream); }}int Initend()//仅仅是为了找到目标城市而已{ for(int i=0;i<city_num;i++){ if(h[i].dist==0) return i; } return -1;}int find(char c){ for(int i=0;i<city_num;i++){ if(h[i].city==c) return i; } return -1;}void addOpen(LinkList *p,int a,int dis,int f)//将走过的节点加入到open表{ LinkList *q; //p =(LinkList *)malloc(sizeof(LinkList));// q =(LinkList *)malloc(sizeof(LinkList)); q=head; p->data=a; p->fa=f; p->num=dis+h[a].dist; while(1){ if(q->next==NULL||q->next->num>p->num){ p->next=q->next; q->next=p; return; } q=q->next; }}void deleteOpen(int n)//将重新找到更短的路径从open表替换{ LinkList *r; r=head; while(r->next!=NULL){ if(r->next->data==n){ r->next=r->next->next; return; } else { r=r->next; } } return;}int findClose(int a)//查找某城市是否在close表中{ for(int i=0;i<city_num;i++){ if(close[i].data==a) return i; } return -1;}void deleteclose(int n)//在需要时从close表中转移出来{ for(int i=0;i<closeNum;i++){ if(close[i].data==n){ close[i].data=close[closeNum-1].data; close[i].num=close[closeNum-1].num; closeNum--; return; } } return;}int findOpen(int n,int dis)//查找某节点是否在open表中{ LinkList *r; r=head; int i=0; while(r->next!=NULL){ if(r->next->data==n){ if(r->next->num>dis+h[n].dist) return 1; else return 0; } else { r=r->next; i++; } } return -1;}void Track()//形成track表{ int a,b; track[tra_num++]=head->next->data; b=head->next->fa; track[tra_num++]=b; while(1){ for(int i=0;i<closeNum;i++){ if(close[i].data==b){ if(close[i].fa==-1) return; b=close[i].fa; track[tra_num++]=b; break; } } }}int main(){ Init(); char name; int end; printf("输入初始城市:"); scanf("%c",&name); end=Initend();//找到目标城市 head =(LinkList *)malloc(sizeof(LinkList)); INITLIST(head);//初始化open表 p =(LinkList *)malloc(sizeof(LinkList));//... p->next=head->next; head->next=p; p->num=h[find(name)].dist; p->data=find(name); p->fa=-1;//...起点城市入open表 LinkList *t; while(head->next->data!=end){ t=head->next; //addTrack(t); head->next=t->next;//open表头入close表 close[closeNum].data=t->data; close[closeNum].num=t->num; close[closeNum++].fa=t->fa; //printf("%d\n",t->data); for(int i=0;i<city_num;i++){ if(g[t->data][i]!=0){//如果找到与此城市相连的城市&&不在close表中 p =(LinkList *)malloc(sizeof(LinkList)); if(findClose(i)==-1&&findOpen(i,t->num-h[t->data].dist+g[t->data][i])==-1){ addOpen(p,i,t->num-h[t->data].dist+g[t->data][i],t->data);//添加到open表中(城市序号,到此城市要走的路) } if(findOpen(i,t->num-h[t->data].dist+g[t->data][i])==1){ deleteOpen(i); addOpen(p,i,t->num-h[t->data].dist+g[t->data][i],t->data); } if(findClose(i)!=-1){ if(close[findClose(i)].num>t->num-h[t->data].dist+g[t->data][i]+h[t->data].dist){ deleteclose(i); addOpen(p,i,t->num-h[t->data].dist+g[t->data][i],t->data); } } } // close[closeNum].data=t->data; // close[closeNum].next=NULL; // close[closeNum].num=t->num; // closeNum++; } } Track(); printf("最优路径为:"); for(int i=tra_num-1;i>=0;i--){ printf("%c ",h[track[i]].city); } printf("\n"); return 0;}
0 0
- 启发式算法-A*算法
- 启发式搜索A * 算法
- A*寻路 曼哈顿启发式算法
- A*启发式算法模拟实现
- 启发式A*算法的整理
- A*算法:启发式(heuristic)算法
- 启发式搜索A*算法 - [算法学习]
- 启发式搜索算法(A*算法)
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式算法
- 启发式搜索算法A*(2)
- A*启发式搜索算法详解 人工智能
- 【坑】使用PrintWrite返回JSON的时候中文乱码的解决办法
- JavaScript异步编程的Promise模式
- HDU 1061 (51Nod 1004 )n^n的末位数字
- Android 文本输入框EditText属性和方法说明(转载)
- 8.6 tempfile--临时文件和目录处理
- 启发式算法-A*算法
- poj 2549 Sumsets (枚举+二分)
- angular中的module和injector,即依赖注入
- HD 1213 How Many Tables(裸 并查集)
- Objective-C Runtime 解读 (二)
- 反应式宣言
- java项目——发邮件之阿里云邮箱推送服务(二)
- android自定义View之钟表诞生记
- jquery部分笔记