1. 程式人生 > >A*演算法介紹及其使用舉例

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 Input Sample 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程式碼:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e5+66;
const int MAXN = 1e3+66;
int n,m,k;
int s,t;
int tot;
int retot;
struct edge{
    int to,w;
    int next1;
}G[AX],RG[AX];

struct Node{
    int v;
    int f,h,g;
    bool operator < (const Node &a) const{ return f==a.f? g>a.g : f>a.f; }
};


int dis[MAXN];
int head[MAXN];
int rehead[AX];
int vis[MAXN];

void add_edge(int u,int v,int c)
{
    G[tot].to=v;
    G[tot].w=c;
    G[tot].next1=head[u];
    head[u]=tot++;

    RG[retot].to=u;
    RG[retot].w=c;
    RG[retot].next1=rehead[v];
    rehead[v]=retot++;
}
void SPFA()
{
    for(int i=1;i<=n;i++) dis[i]=INF;
    dis[t]=0;
    queue<int> Q;
    Q.push(t);
    while(!Q.empty())
{
        int u=Q.front();
        Q.pop();
        for(int i=rehead[u];i!=-1;i=RG[i].next1)
{
            int v=RG[i].to ;
            int w=RG[i].w ;
            if(dis[v]>dis[u]+w)
{
                dis[v]=dis[u]+w;
                Q.push(v);
            }
        }
    }   
}

int Astar(Node a)
{
    memset(vis,0,sizeof(vis));
    if(dis[s]==INF) return -1;//如果沒有與S相連的點 
    if(s==t) k++;
    priority_queue<Node> Q;
    Q.push(a);
    while(!Q.empty())
{
        Node tmp=Q.top();
        Q.pop();
        int v=tmp.v;
        vis[v]++;
        if(vis[t]==k) return tmp.g;
        for(int i=head[v];i!=-1;i=G[i].next1)
{
            Node p;
            p.v=G[i].to;
            p.h=dis[G[i].to];
            p.g=tmp.g+G[i].w;
            p.f=p.g+p.h;
            Q.push(p);
        }
    }
    return -1;
}

int main()
{
    tot=0;
    retot=0;
    memset(head,-1,sizeof head);
    memset(rehead,-1,sizeof rehead);
    scanf("%d%d%d",&n,&m,&k);
    scanf("%d%d",&s,&t);
    int x,y,w;
    for(int i=0;i<m;i++)
{
        scanf("%d%d%d",&x,&y,&w);
        add_edge(x,y,w);
    }
    SPFA();
    Node a;
    a.v=s;
    a.g=0;
    a.h=dis[s];
    a.f=a.g+a.h;
    int g=Astar(a);
    printf("%d\n",g);
    return 0 ;
}

後面我還會更新出 關於啟發式搜尋的講解,以及Dijkstra,,SPFA,Folyd這三種關於不同最短路問題講解及例題分析。

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

相關推薦

A*演算法介紹及其使用舉例

1 A*演算法     A*演算法在人工智慧中是一種典型的啟發式搜尋演算法,啟發中的估價是用估價函式表示的: 其中f(n)是節點n的估價函式,g(n)表示實際狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。另外定義h'(

MD5摘要演算法介紹及其實現

Message Digest Algorithm MD5(訊息摘要演算法第五版)為電腦保安領域廣泛使用的一種雜湊函式,用以提供訊息的完整性保護。 演算法特點 MD5演算法,符合一般摘要演算法的特點: 1、壓縮性:任意長度的資料,算出的MD5值長度都是固

基本Kmeans演算法介紹及其實現

1.基本Kmeans演算法[1] 選擇K個點作為初始質心 repeat 將每個點指派到最近的質心,形成K個簇 重新計算每個簇的質心 until 簇不發生變化或達到最大迭代次數時間複雜度:O(tKmn),其中,t為迭代次數,K為簇的數目,m為記錄數,n為維數 空間複雜

利用銀行家演算法避免死鎖的介紹舉例

一、資料結構   1.多個程序: { P0,P1,P2,P4 } 代表1,2,3,4四個需要臨界資源的程序   2.幾種資源:{ A, B ,C } 代表A,B,C三種臨界資源   3.Max:最大需求矩陣(程序完成執行需要的各資源總量)     Allocation:分配矩陣(某個程序現在

資料結構與演算法:B+樹(B+Tree)介紹及其與B樹比較

定義 前面介紹了B樹及其基本操作,B+樹是B樹的一個變種。與B樹一樣,B+樹通常用於諸如資料庫和磁碟檔案系統等輔助儲存系統,輔助儲存系統一般容量大,但是資料存取速度比記憶體慢幾個數量級。B樹和B+樹結構減少輔存系統訪問次數,從而加快整體資料存取速度。兩者有一些共

【資料結構與演算法】之單鏈表、雙鏈表、迴圈連結串列的基本介紹及其Java程式碼實現---第三篇

一、連結串列的基本介紹 連結串列的定義:連結串列是一種遞迴的資料結構,它或者為空(null),或者是指向一個結點(node)的引用,該結點含有一個泛型的元素和一個指向另一條連結串列的引用。----Algorithms  Fourth  Edition   常見的連結串

【資料結構與演算法】之棧的基本介紹及其陣列、連結串列實現---第四篇

一、棧的基本介紹 1、棧的基本概念 棧是一種限制在一端進行插入和刪除操作的線性表資料結構。棧中有兩個比較重要的操作:push(壓棧:將元素壓入棧頂)和pop(彈棧:從棧頂彈出一個元素)。都滿足先進後出、後進先出的特點! 從圖中可以看出,我們常把棧的上面稱為棧

【資料結構與演算法】之佇列的基本介紹及其陣列、連結串列實現---第五篇

一、佇列的基本概念 1、定義 佇列是一種先進先出的線性表。它只允許在表的前端進行刪除操作,而在表的後端進行插入操作,具有先進先出、後進後出的特點。進行插入操作的一端成為隊尾(tail),進行刪除操作的一端稱為隊頭(head)。當佇列中沒有元素時,則稱之為空佇列。 在

SSE2介紹及其簡單用法舉例

                SSE2,全名為Streaming SIMD Extensions 2,是一種IA-32架構的SIMD指令集。SSE2是在2001年隨著Intel發表第一代Pentium 4處理器也一併推出的指令集。它延伸較早的SSE指令集,而且可以完全取代MMX指令集。在2004年,Inte

[資料結構與演算法]-二叉堆(binary heap)介紹及其實現(Java)

本文歡迎轉載,轉載前請聯絡作者。若未經允許轉載,轉載時請註明出處,謝謝! http://blog.csdn.net/colton_null 作者:喝酒不騎馬 Colton_Null from CSDN 一.什麼是二叉堆? 二叉堆(binary heap)

演算法】排序02——歸併排序介紹及其在分治演算法思想上與快排的區別(含歸併程式碼)

1、歸併排序是什麼? 歸併排序和快速排序一樣,都採用了分治演算法的思想,時間複雜度都為O[ nlog (n)],但其空間複雜度更大一點,為O[ log (n)],不過相對的,歸併是一種穩定排序,這一點和快排是不同的。 歸併排序的思想流程:   先分,我們先舉例一個序列 [ 5 6 9 8 7 4

git 介紹及其使用總結

實現 之前 demo hang 喜歡 權限 sof 區別 rec 版本控制 Git 目錄 目錄 2 第1章 Shell和vi 4 1.1 什麽是shell 4 1.2 shell分類 4 1.3 認識bash這個shell 5

路由交換基礎(一)——VLAN、Trunk、以太網通道介紹及其配置

vlan trunk ether-channel 一、VLANvlan技術產生和應用背景 在傳統的 LAN 中,所有的設備都是屬於同一個廣播域,所以一旦部分主機出現問題,就有可能影響同廣播域的其他主機,影響範圍廣泛。 為了縮小故障影響範圍和實現快速故障定位,我們使用VL

Flume介紹及其安裝

日誌收集 Flume Flume簡介 Flume配置文件 Flume安裝 一. Flume是什麽? Flume是一個分布式,可靠的系統。它能夠高效的收集,整合數據,還可以將來自不同源的大量數據移動到數據中心存儲。 Flume是Apache下的一個頂級項目。Flume不僅可以收集整合日誌數據

Linux I/O復用中select poll epoll模型的介紹及其優缺點的比較

創建 等待 歸類 好的 第一個 class ews tor client 關於I/O多路復用: I/O多路復用(又被稱為“事件驅動”),首先要理解的是。操作系統為你

squid介紹及其簡單配置

最大 tar val 多條 反向代理 htm 允許 時間 inter 1.Squid是什麽? Squid是一種用來緩沖Internet數據的軟件。它是這樣實現其功能的,接受來自人們需要下載的目標(object)的請求並適當地處理這些請求。也就是說,如果一個人想下載一we

LRU基本介紹及其實現方式

fifo隊列 ride ati implement 建立 復雜 介紹 .get util 原文地址: http://note.youdao.com/noteshare?id=1abbeb1deee85f0203001e9bc34f65b4 參考 LRU算法 dubbo-c

Vue.js常用指令介紹舉例應用

什麼是vue.js指令? 指令是帶有v-字首的特殊屬性。 vue.js指令的用途? 在表示式的值改變時,將某些行為應用到DOM上。 官方文件:https://cn.vuejs.org/v2/api/#指令 指令介紹 v-show:控制一個元素的display屬性顯示或者隱藏 v-on:為

A*演算法實現(圖形化表示)——C++描述

概要   A*演算法是一種啟發式尋路演算法,BFS是一種盲目的無目標的搜尋演算法,相比於BFS,A*演算法根據適應度構建優先佇列,根據適應度值可以很好的向目標點移動,具體詳情,請看搜尋相關文件,我在只是實現了在無障礙的情況下的A*演算法,有障礙的情況類似。 開發環境   visual studio 20

不平衡資料分類演算法介紹與比較

介紹 在資料探勘中,經常會存在不平衡資料的分類問題,比如在異常監控預測中,由於異常就大多數情況下都不會出現,因此想要達到良好的識別效果普通的分類演算法還遠遠不夠,這裡介紹幾種處理不平衡資料的常用方法及對比。 符號表示 記多數類的樣本集合為L,少數類的樣本集合為S。