Astar算法的應用和實現

一、Astar算法c

Astar算法(A*)是一種常用的尋路算法,因為它可以在一張地圖中找到最短路徑,並且計算量不大,所以被廣泛應用於自動化尋路系統,遊戲中的NPC移動等方面。A*算法的思路是在搜索過程中維護一個開放列表和一個封閉列表,搜索過程中通過啟發式函數預測此路徑的長度,來選擇最優的路徑。使用C語言實現A*算法如下:

void Astar()
{
    while(!openList.empty())
    {
        AstarPt* present = openList.top();
        openList.pop();
        if (present->row == endPt->row && present->col == endPt->col) 
        {
            endPt->pre = present->pre;
            return;
        }
        closeList.push_back(present);
        getSuccessors(present);
    }
}

二、Astar算法與Dijkstra算法

Astar算法與Dijkstra算法都是用於尋路問題的經典算法。Dijkstra算法是一種基於圖論的貪心算法,在某些特殊情況下可能會陷入死循環,而Astar算法不會。Astar算法在計算過程中預測剩餘距離,因此總是朝着目標方向前進,相比於Dijkstra算法,它更加高效。而Dijkstra算法要求每個路徑權值都為正數,因為它在計算時會擴展所有相鄰節點,網格地圖中代價計算比較困難。因此,對於需要在網格地圖上搜索路徑的問題,Astar算法是更好的選擇。

三、Astar算法原理

Astar算法維護兩個列表:開放列表和封閉列表。初始時,將起點放入開放列表中。在每次循環中,從開放列表中選取預估代價最小的節點出隊,並將其放入封閉列表中。接下來,通過計算預估剩餘距離將當前節點的鄰居入隊到開放列表中。在路徑被找到之前,重複執行此過程。當路徑被找到時,從終點開始遍歷每個節點的pre指針,直到回到起始節點,即可得到這條路徑。

四、Astar算法Python

Python語言實現Astar算法非常方便,以下是一個簡單的實現例子:

def Astar(start, end, graph):
    openList = PriorityQueue()
    openList.put(start, 0)
    cameFrom = {}
    gScore = defaultdict(lambda: float('inf'))
    gScore[start] = 0
    fScore = defaultdict(lambda: float('inf'))
    fScore[start] = heuristic(start, end)   
    while not openList.empty():
        current = openList.get()
        if current == end:
            return construct_path(cameFrom, start, end)
        for neighbor in graph[current]:
            tentative_gScore = gScore[current] + graph[current][neighbor]
            if tentative_gScore < gScore[neighbor]:
                cameFrom[neighbor] = current
                gScore[neighbor] = tentative_gScore
                fScore[neighbor] = tentative_gScore + heuristic(neighbor, end)
                if neighbor not in openList.queue:
                    openList.put(neighbor, fScore[neighbor])
    return "No path"

五、Astar算法代碼

以下是一個簡單的偽代碼實現:

function A* (start,goal)
  closedList := {};     //已被評估過的點
  openList := {};       //待評估的點
  visitedFrom := {};    //記錄每個點來自於哪個點
  gScore := {};         //從起始點到此點已經花費的代價
  fScore := {};         //總代價 = 已花費的代價 + 剩餘代價
  push start into openList
  gScore[start] := 0
  fScore[start] := gScore[start] + heuristic_cost_estimate(start, goal) 

  while openList is not empty
      current := the node in openList having the lowest fScore[] value
      if current = goal
          return reconstruct_path(visitedFrom,goal)
      
      remove current from openList
      push current into closedList
      
      for each neighbor in neighbor_nodes(current)
          if neighbor in closedList
              continue
          tentative_gScore := gScore[current] + distance_between(current,neighbor) 
          if neighbor not in openList or tentative_gScore < gScore[neighbor] 
              visitedFrom[neighbor] := current
              gScore[neighbor] := tentative_gScore
              fScore[neighbor] := gScore[neighbor] + heuristic_cost_estimate(neighbor, goal)
              if neighbor not in openList
                  push neighbor into openList
  return failure

六、Astar算法例子

以下是一個基於地圖的Astar算法例子:

def heuristic_cost_estimate(current, goal):
    return abs(current.x - goal.x) + abs(current.y - goal.y)

def reconstruct_path(visitedFrom, current):
    total_path = [current]
    while current in visitedFrom:
        current = visitedFrom[current]
        total_path.append(current)
    return total_path

def Astar(start, goal, graph):
    closedList = []
    openList = [start]
    visitedFrom = {}
    gScore = {start: 0}
    fScore = {start: heuristic_cost_estimate(start, goal)}
    while openList:
        current = min(openList, key=lambda x:fScore[x])
        if current == goal:
            return reconstruct_path(visitedFrom, current)
        openList.remove(current)
        closedList.append(current)
        for neighbor in graph[current]:
            if neighbor in closedList:
                continue
            tentative_gScore = gScore[current] + graph[current][neighbor]
            if neighbor not in openList or tentative_gScore < gScore[neighbor]:
                visitedFrom[neighbor] = current
                gScore[neighbor] = tentative_gScore
                fScore[neighbor] = gScore[neighbor] + heuristic_cost_estimate(neighbor, goal)
                if neighbor not in openList:
                    openList.append(neighbor)
    return "No path"

七、Astar算法尋路

在遊戲開發中,Astar算法可以被用於尋路,以下是一個簡單的尋路實現例子:

public class AstarPathfinding : MonoBehaviour {

    Node startNode;
    Node endNode;

    public List FindPath(Node start, Node end)
    {
        startNode = start;
        endNode = end;

        List openSet = new List();
        HashSet closedSet = new HashSet();
        openSet.Add(startNode);

        while (openSet.Count > 0)
        {
            Node currentNode = openSet[0];
            for (int i = 1; i < openSet.Count; i++)
            {
                if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)
                {
                    currentNode = openSet[i];
                }
            }

            openSet.Remove(currentNode);
            closedSet.Add(currentNode);

            if (currentNode == endNode)
            {
                return RetracePath(startNode, endNode);
            }

            foreach (Node neighbor in currentNode.neighbors)
            {
                if (!neighbor.walkable || closedSet.Contains(neighbor))
                {
                    continue;
                }

                int newCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor);
                if (newCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                {
                    neighbor.gCost = newCostToNeighbor;
                    neighbor.hCost = GetDistance(neighbor, endNode);
                    neighbor.parent = currentNode;

                    if (!openSet.Contains(neighbor))
                    {
                        openSet.Add(neighbor);
                    }
                }
            }
        }

        return null;
    }

    //...
}

八、Astar算法和貪心算法

貪心算法和Astar算法有着類似的思路,都是在計算過程中維護一個開放列表和一個封閉列表,且都使用啟發式函數來決定哪個節點應該被擴展。但貪心算法只考慮當前擴展節點,而Astar算法還要考慮目標節點的距離,這使它變得更符合現實情況。Astar算法相對於貪心算法來說,能夠找到更優的路徑。

九、Astar算法優化

Astar算法的運行效率取決於啟發函數的選擇和數據結構的優化。設計一個好的啟發函數非常重要,它決定了算法的速度和精度。另外,在實際的應用過程中可以採用一些優化策略來加速運算,如減少存儲空間、預處理數據等。

十、Astar算法的優缺點

Astar算法的優點:

  • 可以找到最短路徑
  • 啟發式搜索可以減少搜索的時間和空間
  • 應用廣泛,特別是在遊戲AI、數據挖掘等領域

Astar算法的缺點:

  • 對數據結構要求較高
  • 啟發函數的設計非常重要,不好的啟發函數可能導致算法性能下降
  • 有可能陷入局部最優解

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/244630.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:03
下一篇 2024-12-12 13:03

相關推薦

  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 數據結構與算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序算法、字符串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • 神經網絡BP算法原理

    本文將從多個方面對神經網絡BP算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP算法簡介 BP算法是一種常用的神經網絡訓練算法,其全稱為反向傳播算法。BP算法的基本思想是通過正…

    編程 2025-04-29
  • 粒子群算法Python的介紹和實現

    本文將介紹粒子群算法的原理和Python實現方法,將從以下幾個方面進行詳細闡述。 一、粒子群算法的原理 粒子群算法(Particle Swarm Optimization, PSO…

    編程 2025-04-29
  • Python回歸算法算例

    本文將從以下幾個方面對Python回歸算法算例進行詳細闡述。 一、回歸算法簡介 回歸算法是數據分析中的一種重要方法,主要用於預測未來或進行趨勢分析,通過對歷史數據的學習和分析,建立…

    編程 2025-04-28
  • 象棋算法思路探析

    本文將從多方面探討象棋算法,包括搜索算法、啟發式算法、博弈樹算法、神經網絡算法等。 一、搜索算法 搜索算法是一種常見的求解問題的方法。在象棋中,搜索算法可以用來尋找最佳棋步。經典的…

    編程 2025-04-28

發表回復

登錄後才能評論