どのようなDijkstraのアルゴリズム、A-Star比較?
-
19-09-2019 - |
質問
ただのんの マリオAI競争 行っているとのことも良マリオボットを活用したA*(一つ星)Pathingアルゴリズムです。
私の質問は、どのような星との比較Dijkstra?見ています。
この人の利用に。特にpathingゲーム?
解決
ダイクストラは*(ヒューリスティックがゼロである)のための特別な場合である。
他のヒント
Dijkstra:
きのあるコスト関数は、実質価値ソースから各ノード: f(x)=g(x)
.
できるようにするためのlibsoupおよ最短経路からのソースは他のノードを考慮しただけです。
A-検索:
において最も手間のかかるコスト関数.
g(x)
:同Dijkstra.実際のコストをノードx
.h(x)
:渡嘉敷漁業協同組合からのノードx
ゴノードです。では、ヒューリスティック機能です。このヒューリスティック機能などが過大評価、コストの低減ができます。ということは、クリーンに到達目標のノードからノードx
必要以上h(x)
.と呼ばれる許容ヒューリスティック.
の総コストの各ノードの計算 f(x)=g(x)+h(x)
※検索のみが広がるノードがよさそうで期待できます。しみいただけ、その目標を達成するためのノードから、現在のノードは全その他のノード。では最適の場合、ヒューリスティックの機能は許容.
シンプルなヒューリスティック機能は、将来のコスト以上が必要となりますの探索もしくはノードよりDijkstra.
前の何のポスターと、プラスダイクストラは何のヒューリスティックを持っていないし、各ステップのピックで、最小のコストでエッジので、それはあなたのグラフのより多くの「カバー」をする傾向があります。そのためダイクストラは*よりも有用である可能性があります。良い例は、(あなたがそれを複数回実行する必要があります*の場合:一度各候補ノードのために)最も近いである1、あなたはいくつかの候補ターゲットノードを持っていますが、あなたは知っていないときである。
ダイクストラ法は、経路探索のために使用されることはありませんでしょう。あなたは(特に2Dの世界では、ゲームのため通常は簡単)まともなヒューリスティックを考え出すことができる場合は*を使用すると、非常に簡単ではありません。それは、より少ないメモリを使用しているため、探索空間によっては、*を深化反復は時々望ましいます。
ダイクストラは*のための特別なケースです。
ダイクストラは、他のすべての開始ノードから最小コストを見つけます。 *は、目標ノードへの開始ノードから最小コストを見つけます。
ダイクストラ法は、パスの発見のために使用されることはありませんでしょう。 *のいずれかを使用すると、まともなヒューリスティックを考え出すことができます。それは、より少ないメモリを使用しているため、探索空間に応じて、反復*が望ましいます。
ダイクストラ法のためのコードがあります:
// A C / C++ program for Dijkstra's single source shortest path algorithm.
// The program is for adjacency matrix representation of the graph
#include <stdio.h>
#include <limits.h>
// Number of vertices in the graph
#define V 9
// A utility function to find the vertex with minimum distance value, from
// the set of vertices not yet included in shortest path tree
int minDistance(int dist[], bool sptSet[])
{
// Initialize min value
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
int printSolution(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t %d\n", i, dist[i]);
}
void dijkstra(int graph[V][V], int src)
{
int dist[V]; // The output array. dist[i] will hold the shortest
// distance from src to i
bool sptSet[V]; // sptSet[i] will true if vertex i is included in shortest
// path tree or shortest distance from src to i is finalized
// Initialize all distances as INFINITE and stpSet[] as false
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
// Distance of source vertex from itself is always 0
dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V-1; count++)
{
// Pick the minimum distance vertex from the set of vertices not
// yet processed. u is always equal to src in first iteration.
int u = minDistance(dist, sptSet);
// Mark the picked vertex as processed
sptSet[u] = true;
// Update dist value of the adjacent vertices of the picked vertex.
for (int v = 0; v < V; v++)
// Update dist[v] only if is not in sptSet, there is an edge from
// u to v, and total weight of path from src to v through u is
// smaller than current value of dist[v]
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX
&& dist[u]+graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}
// print the constructed distance array
printSolution(dist, V);
}
// driver program to test above function
int main()
{
/* Let us create the example graph discussed above */
int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}
};
dijkstra(graph, 0);
return 0;
}
*アルゴリズムのためのコードがあります:
class Node:
def __init__(self,value,point):
self.value = value
self.point = point
self.parent = None
self.H = 0
self.G = 0
def move_cost(self,other):
return 0 if self.value == '.' else 1
def children(point,grid):
x,y = point.point
links = [grid[d[0]][d[1]] for d in [(x-1, y),(x,y - 1),(x,y + 1),(x+1,y)]]
return [link for link in links if link.value != '%']
def manhattan(point,point2):
return abs(point.point[0] - point2.point[0]) + abs(point.point[1]-point2.point[0])
def aStar(start, goal, grid):
#The open and closed sets
openset = set()
closedset = set()
#Current point is the starting point
current = start
#Add the starting point to the open set
openset.add(current)
#While the open set is not empty
while openset:
#Find the item in the open set with the lowest G + H score
current = min(openset, key=lambda o:o.G + o.H)
#If it is the item we want, retrace the path and return it
if current == goal:
path = []
while current.parent:
path.append(current)
current = current.parent
path.append(current)
return path[::-1]
#Remove the item from the open set
openset.remove(current)
#Add it to the closed set
closedset.add(current)
#Loop through the node's children/siblings
for node in children(current,grid):
#If it is already in the closed set, skip it
if node in closedset:
continue
#Otherwise if it is already in the open set
if node in openset:
#Check if we beat the G score
new_g = current.G + current.move_cost(node)
if node.G > new_g:
#If so, update the node to have a new parent
node.G = new_g
node.parent = current
else:
#If it isn't in the open set, calculate the G and H score for the node
node.G = current.G + current.move_cost(node)
node.H = manhattan(node, goal)
#Set the parent to our current item
node.parent = current
#Add it to the set
openset.add(node)
#Throw an exception if there is no path
raise ValueError('No Path Found')
def next_move(pacman,food,grid):
#Convert all the points to instances of Node
for x in xrange(len(grid)):
for y in xrange(len(grid[x])):
grid[x][y] = Node(grid[x][y],(x,y))
#Get the path
path = aStar(grid[pacman[0]][pacman[1]],grid[food[0]][food[1]],grid)
#Output the path
print len(path) - 1
for node in path:
x, y = node.point
print x, y
pacman_x, pacman_y = [ int(i) for i in raw_input().strip().split() ]
food_x, food_y = [ int(i) for i in raw_input().strip().split() ]
x,y = [ int(i) for i in raw_input().strip().split() ]
grid = []
for i in xrange(0, x):
grid.append(list(raw_input().strip()))
next_move((pacman_x, pacman_y),(food_x, food_y), grid)
あなたは*ダイクストラのガイド付きバージョンを考慮することができます。つまり、代わりにすべてのノードを探索し、あなたは方向を選択するヒューリスティックを使用します。
、より具体的に言えば、あなたがプライオリティキューでアルゴリズムを実装している場合、あなたが訪問しているノードの優先順位は、コストの機能(以前のノードがコスト+ここで取得するには費用がかかる)とヒューリスティックになりますここからゴールまでの推定。ダイクストラでいる間、優先順位はノードだけに実際のコストに影響されます。いずれの場合も、停止基準は、目標を達成されます。
ダイクストラは、他のすべての開始ノードから最小コストを見つけます。 *は、目標ノードへの開始ノードから最小コストを見つけます。
したがって、それはあなたが必要とするすべては1つのノードから別のノードの最短距離であるときダイクストラはあまり効率的であろうと思われます。
あなたはASTARのために擬似コードを見れば:
foreach y in neighbor_nodes(x)
if y in closedset
continue
あなたはダイクストラの同じ見れば、一方:
for each neighbor v of u:
alt := dist[u] + dist_between(u, v) ;
ですから、ポイントは、ASTARは、複数回
をノードの評価はありません
それは、一度ノードを見ていることは十分、原因
であると考えていますので、
そのヒューリスティックへ。
大藤、ダイクストラ法は場合に、自分自身を修正する恥ずかしがり屋ではありません
ノードが再びポップアップします。
どちらがより速く、より適切なパスを見つけるためのASTARをを確認する必要があります。
ダイクストラ法は間違いなく最短経路を見つけます。一方のA *にヒューリスティックに依存します。このためA *は、ダイクストラ法よりも高速であり、あなたが良いヒューリスティックを持っている場合、良い結果が得られます。
ダイクストラのアルゴリズムを使用すると、常に最短経路を見つけることは間違いなく、完全かつ最適です。しかし、複数の目標ノードを検出するために主に使用されているので、時間がかかる傾向がある。
そのような目標に向かってマンハッタン距離など、あなたの目標に近いに到達するために定義することができヒューリスティック値、と一方の事項について A* search
。ヒューリスティックな要因に依存する最適なまたは完全のいずれかになります。あなたは、単一の目標ノードを持っている場合、それは間違いなく速くなります。
*では、各ノードのためにあなたは彼らのために発信接続を確認してください。
それぞれの新しいノードについて、あなたは前のノードに到達するために持っていたこのノードへの接続とコストの重みに応じて、最低のコスト、これまで(CSF)を計算する。
また、あなたは、ターゲット・ノードに新しいノードからコストを見積もり、CSFにこれを追加します。これで、推定総コスト(など)を持っています。 (ETC = CSF +標的とする推定距離)
次のあなたは
など最低で新しいノードからいずれかを選択
の新しいノードの1 はターゲットになりますまで、前と同じ操作を行います。
ダイクストラは、ほぼ同じように動作します。対象とする推定距離は常に0で、ターゲットがいないだけで、の新しいノードの、だけでなく、最低CSFと1のうちの1つである場合、アルゴリズムは、最初に停止します。
ということを除いて これは必ずしもそうではないでしょうが、A *は、dijstraよりも通常は高速です。 ビデオゲームでは、多くの場合、「ゲームのための十分を閉じる」アプローチをprefare。したがって*から「十分に近い」の最適経路は、通常は十分です。