• A*算法在最短路问题的应用及其使用举例


    1 A*算法

        A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的:

    第K最短路-A*启发式搜索

    其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。另外定义h'(n)为n到目标节点最佳路径的实际值。如果h'(n)≥h(n)则如果存在从初始状态走到目标状态的最小代价的解,那么用该估价函数搜索的算法就叫A*算法。

    2 第K最短路的算法

        我们设源点为s,终点为t,我们设状态f(i)的g(i)为从s走到节点i的实际距离,h(i)为从节点i到t的最短距离,从而满足A*算法的要求,当第K次走到f(n-1)时表示此时的g(n-1)为第K最短路长度。C++代码如下:()

    CDOJ找的一道例题:(模板题)这里面用到SPFA算法(这是中国人创造的得意,用于求单源最短路的一种算法,关于SFPA时间复杂度的问题,,,不确定性,有时很大,有时很小,emmmm,貌似外国人不太认可,)

    Time Limit: 10000 MS     Memory Limit: 256 MB

    Submit Status

    6·1即将来临,游乐园推出了新的主题活动,雨过天晴,帆宝乐爷童心未泯,准备一探究竟。

    兴奋的他们一入园便和孩子们打成一片,不知不觉便走散了。

    当他们意识到的时候,只能通过手机来确认对方的位置。

    他们当然想尽快找到对方,然而由于孩子们实在是太多,只能选择距离稍远的但是游客稀少的路会合。

    帆宝希望找到第kk短的路径,这条路径是他认为的幸运路径。

    帆宝迫切地想知道该条路径的长度,而乐于助人的你也一定会帮助她的。

    Input

    第一行三个整数n,m,kn,m,k,分别表示游乐园的景点数目、景点之间的道路数目以及路径长度从小到大排列时希望选择的序号。

    第二行两个整数S,TS,T,分别表示帆宝乐爷所在景点的编号。

    接下来mm行,每行三个整数u,v,wu,v,w,表示编号为uu和vv的景点之间有一条长度为ww的单向通路。

    1≤n≤1000,0≤m≤100000,1≤k≤1000,1≤S,T,u,v≤N,1≤w≤1001≤n≤1000,0≤m≤100000,1≤k≤1000,1≤S,T,u,v≤N,1≤w≤100

    Output

    第一行一个整数xx,表示所选路径的长度

    无解输出−1−1

    Sample input and output

    Sample InputSample Output
    3 3 2
    1 2
    1 2 2
    1 3 4
    3 2 1
    
    5

    题意:给你起点,终点以及要求的第K短路;

    题解:首先将有向图以终点T为起点,计算出T到每一个边的最短距离(到第i条边dis[i]),

    然后建立一个优先队列,从优先队列中弹出f(p)最小的点p,如果p就是T,则T的次数加一。如果当前次数等于K则当前路即为地K小

    的路,,否则,,便利每一个p 所连的边,将其扩张出的到p临接点的信息加入到优先队列中;

    AC代码:

      1 #include <bits/stdc++.h>
      2 #define INF 0x3f3f3f3f
      3 using namespace std;
      4 const int AX = 1e5+66;
      5 const int MAXN = 1e3+66;
      6 int n,m,k;
      7 int s,t;
      8 int tot;
      9 int retot;
     10 struct edge{
     11     int to,w;
     12     int next1;
     13 }G[AX],RG[AX];
     14 
     15 struct Node{
     16     int v;
     17     int f,h,g;
     18     bool operator < (const Node &a) const{ return f==a.f? g>a.g : f>a.f; }
     19 };
     20 
     21 
     22 int dis[MAXN];
     23 int head[MAXN];
     24 int rehead[AX];
     25 int vis[MAXN];
     26 
     27 void add_edge(int u,int v,int c)
     28 {
     29     G[tot].to=v;
     30     G[tot].w=c;
     31     G[tot].next1=head[u];
     32     head[u]=tot++;
     33 
     34     RG[retot].to=u;
     35     RG[retot].w=c;
     36     RG[retot].next1=rehead[v];
     37     rehead[v]=retot++;
     38 }
     39 void SPFA()
     40 {
     41     for(int i=1;i<=n;i++) dis[i]=INF;
     42     dis[t]=0;
     43     queue<int> Q;
     44     Q.push(t);
     45     while(!Q.empty())
     46 {
     47         int u=Q.front();
     48         Q.pop();
     49         for(int i=rehead[u];i!=-1;i=RG[i].next1)
     50 {
     51             int v=RG[i].to ;
     52             int w=RG[i].w ;
     53             if(dis[v]>dis[u]+w)
     54 {
     55                 dis[v]=dis[u]+w;
     56                 Q.push(v);
     57             }
     58         }
     59     }   
     60 }
     61 
     62 int Astar(Node a)
     63 {
     64     memset(vis,0,sizeof(vis));
     65     if(dis[s]==INF) return -1;//如果没有与S相连的点 
     66     if(s==t) k++;
     67     priority_queue<Node> Q;
     68     Q.push(a);
     69     while(!Q.empty())
     70 {
     71         Node tmp=Q.top();
     72         Q.pop();
     73         int v=tmp.v;
     74         vis[v]++;
     75         if(vis[t]==k) return tmp.g;
     76         for(int i=head[v];i!=-1;i=G[i].next1)
     77 {
     78             Node p;
     79             p.v=G[i].to;
     80             p.h=dis[G[i].to];
     81             p.g=tmp.g+G[i].w;
     82             p.f=p.g+p.h;
     83             Q.push(p);
     84         }
     85     }
     86     return -1;
     87 }
     88 
     89 int main()
     90 {
     91     tot=0;
     92     retot=0;
     93     memset(head,-1,sizeof head);
     94     memset(rehead,-1,sizeof rehead);
     95     scanf("%d%d%d",&n,&m,&k);
     96     scanf("%d%d",&s,&t);
     97     int x,y,w;
     98     for(int i=0;i<m;i++)
     99 {
    100         scanf("%d%d%d",&x,&y,&w);
    101         add_edge(x,y,w);
    102     }
    103     SPFA();
    104     Node a;
    105     a.v=s;
    106     a.g=0;
    107     a.h=dis[s];
    108     a.f=a.g+a.h;
    109     int g=Astar(a);
    110     printf("%d
    ",g);
    111     return 0 ;
    112 }
    View Code

    后面我还会更新出 关于启发式搜索的讲解,以及Dijkstra,,SPFA,Folyd这三种关于不同最短路问题讲解及例题分析。

    越努力,越幸运!    加油!!!

  • 相关阅读:
    梦断代码读后感02
    UML大战需求与分析--阅读笔记4
    UML大战需求分析--阅读笔记3
    软件需求与分析课堂讨论一
    UML大战需求分析--阅读笔记02
    UML大战需求分析--阅读笔记01
    学习进度--大三下
    问题账户需求分析
    2016年秋季阅读计划
    个人总结
  • 原文地址:https://www.cnblogs.com/csushl/p/9386760.html
Copyright © 2020-2023  润新知