線路規(guī)劃,尋路算法介紹及代碼實現(xiàn)
尋路算法是計算機圖形學和人工智能領域中常用的算法之一,用于計算從一個點到另一個點的最短路徑或最優(yōu)路徑。在本文中,我將詳細介紹兩種常用的尋路算法:Dijkstra算法和A*算法。
Dijkstra算法
Dijkstra算法是一種廣度優(yōu)先搜索算法,用于尋找圖中兩點之間的最短路徑。算法的思路如下:
創(chuàng)建一個集合S,用于存放已經找到最短路徑的頂點。
創(chuàng)建一個集合Q,用于存放還未找到最短路徑的頂點。
初始化距離數(shù)組dist,將起始點到其余點的距離設置為無窮大,起始點到自身的距離設置為0。
重復以下步驟,直到集合Q為空:
- 在集合Q中找到距離起始點最近的頂點u,并將其加入集合S。
- 對于頂點u的每個鄰居頂點v,更新起始點到v的距離dist[v],如果dist[v] > dist[u] + edge(u, v),則更新dist[v]為dist[u] + edge(u, v)。
最終,dist數(shù)組中存儲的就是起始點到各個頂點的最短路徑。
下面是使用C#實現(xiàn)的Dijkstra算法的源代碼:
class DijkstraAlgorithm
{
private int[,] graph;
private int size;
public DijkstraAlgorithm(int[,] graph)
{
this.graph = graph;
this.size = graph.GetLength(0);
}
public int[] FindShortestPath(int start, int end)
{
int[] dist = new int[size];
bool[] visited = new bool[size];
for (int i = 0; i < size; i++)
{
dist[i] = int.MaxValue;
visited[i] = false;
}
dist[start] = 0;
for (int count = 0; count < size - 1; count++)
{
int u = GetMinDistance(dist, visited);
visited[u] = true;
for (int v = 0; v < size; v++)
{
if (!visited[v] && graph[u, v] != 0 && dist[u] != int.MaxValue
&& dist[u] + graph[u, v] < dist[v])
{
dist[v] = dist[u] + graph[u, v];
}
}
}
return dist;
}
private int GetMinDistance(int[] dist, bool[] visited)
{
int minDist = int.MaxValue;
int minIndex = -1;
for (int v = 0; v < size; v++)
{
if (!visited[v] && dist[v] <= minDist)
{
minDist = dist[v];
minIndex = v;
}
}
return minIndex;
}
}
A算法
A算法是一種啟發(fā)式搜索算法,用于尋找圖中兩點之間的最短路徑。算法的思路如下:
創(chuàng)建一個優(yōu)先隊列openSet,用于存放待探索的頂點。
創(chuàng)建一個數(shù)組gScore,用于存放起始點到每個頂點的實際代價。
創(chuàng)建一個數(shù)組fScore,用于存放起始點通過每個頂點到達目標點的估計代價。
將起始點加入openSet,并將gScore[start]設置為0,fScore[start]設置為起始點到目標點的估計代價。
重復以下步驟,直到openSet為空:
- 在openSet中找到fScore最小的頂點current。
- 如果current等于目標點,表示已經找到最短路徑,返回路徑。
- 將current從openSet中移除。
- 對于current的每個鄰居頂點neighbor,計算從起始點到neighbor的實際代價tempGScore,如果tempGScore小于gScore[neighbor],更新gScore[neighbor]為tempGScore,并計算fScore[neighbor] = gScore[neighbor] + 估計代價。如果neighbor不在openSet中,將其加入openSet。
如果openSet為空,表示無法到達目標點,返回空。
下面是使用Java實現(xiàn)的A*算法的源代碼:
import java.util.*;
class AStarAlgorithm {
private int[][] graph;
private int size;
public AStarAlgorithm(int[][] graph) {
this.graph = graph;
this.size = graph.length;
}
public List<Integer> findShortestPath(int start, int end) {
PriorityQueue<Node> openSet = new PriorityQueue<>();
int[] gScore = new int[size];
int[] fScore = new int[size];
int[] cameFrom = new int[size];
boolean[] visited = new boolean[size];
Arrays.fill(gScore, Integer.MAX_VALUE);
Arrays.fill(fScore, Integer.MAX_VALUE);
Arrays.fill(cameFrom, -1);
gScore[start] = 0;
fScore[start] = heuristicCostEstimate(start, end);
openSet.offer(new Node(start, fScore[start]));
while (!openSet.isEmpty()) {
int current = openSet.poll().index;
if (current == end) {
return reconstructPath(cameFrom, current);
}
visited[current] = true;
for (int neighbor = 0; neighbor < size; neighbor++) {
if (graph[current][neighbor] != 0 && !visited[neighbor]) {
int tempGScore = gScore[current] + graph[current][neighbor];
if (tempGScore < gScore[neighbor]) {
cameFrom[neighbor] = current;
gScore[neighbor] = tempGScore;
fScore[neighbor] = gScore[neighbor] + heuristicCostEstimate(neighbor, end);
if (!openSet.contains(new Node(neighbor, fScore[neighbor]))) {
openSet.offer(new Node(neighbor, fScore[neighbor]));
}
}
}
}
}
return null;
}
private int heuristicCostEstimate(int start, int end) {
// 估計代價的計算方法,例如歐幾里得距離、曼哈頓距離等
return Math.abs(end - start);
}
private List<Integer> reconstructPath(int[] cameFrom, int current) {
List<Integer> path = new ArrayList<>();
path.add(current);
while (cameFrom[current] != -1) {
current = cameFrom[current];
path.add(0, current);
}
return path;
}
private class Node implements Comparable<Node> {
public int index;
public int fScore;
public Node(int index, int fScore) {
this.index = index;
this.fScore = fScore;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.fScore, other.fScore);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Node other = (Node) obj;
return index == other.index;
}
@Override
public int hashCode() {
return Objects.hash(index);
}
}
}
以上是對Dijkstra算法和A*算法的詳細介紹,包括算法思路、過程和使用C#或Java實現(xiàn)的源代碼。這兩種算法都是常用的尋路算法,可以根據(jù)具體需求選擇使用。
當然在現(xiàn)在的城市里導航軟件軟件可以給我們規(guī)劃好。