אלגוריתם חיפוש A*

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש

אלגוריתם חיפוש *Aאנגלית: A* Search Algorithm) הוא אלגוריתם חיפוש מונחה היוריסטיקה על צמתי גרף, תוך חיפוש צומת המקיים תכונה מסוימת (צומת היעד). האלגוריתם תואר לראשונה ב-1968 על ידי פיטר הרט, נילס נילסון וברטהם רפאל ממרכז המחקר של אוניברסיטת סטנפורד.

אלגוריתם A* נפוץ ביותר ונעשה בו שימוש נרחב לבעיות הדורשות מציאת מסלולים בגרפים.

כמו אלגוריתם חיפוש לרוחב A* הוא שלם, כלומר הרצת האלגוריתם החיפוש מבטיחה מציאת מסלול בין צומת המקור לצומת היעד אם קיים מסלול כזה. הפונקציה ההיוריסטית צריכה להיות קבילה.

תיאור[עריכת קוד מקור | עריכה]

האלגוריתם הוא מסוג best-first search ומוצא את המסלול הזול ביותר מצומת המקור לאחד מצמתי היעד. כאשר A* עובר על הגרף הוא מנסה לפתח בכל פעם את המסלול שנראה הזול ביותר תוך כדי שימוש בתור עדיפויות ממוין. האלגוריתם משתמש בפונקציית עלות f(x) המשלבת היוריסטיקה (h(x)) בצירוף מידע ידוע (g(x)) כדי לבחור איזה צומת לפתח. פונקציית העלות היא הסכום של שתי הפונקציות:

  • g(x) שהיא המרחק הידוע בין צומת ההתחלה לצומת הנוכחי x.
  • h(x) שהיא הערכה למרחק בין x לבין צומת היעד.

כדי שהאלגוריתם יחזיר פתרון אופטימלי, פונקציית ההיוריסטיקה, h(x), צריכה להיות אדמיסיבלית (קבילה), כלומר לא יותר יקרה מהמרחק האמיתי לצומת היעד. בניתוב היא יכולה להיות מרחק אווירי, מכיוון שהוא מהווה את המרחק המינימלי בין כל שני צמתים. בנוסף אם ההיוריסטיקה מונוטונית (קונסיסטנטיות), כלומר מקיימת את התנאי h(x) \le d(x,y) + h(y) לכל קשת (x,y) בגרף (d מסמן את אורך הקשת), האלגוריתם ירוץ מהר יותר מכיוון שאין צורך לבדוק בשנית צמתים בהם האלגוריתם כבר עבר.)

אפשר להסתכל על האלגוריתם כהרחבה של אלגוריתם דייקסטרה עם היוריסטיקה (בדייקסטרה הפונקציה ההיוריסטית תהיה תמיד שווה ל-0).

פסאודו-קוד[עריכת קוד מקור | עריכה]

להלן פסאודו-קוד של האלגוריתם:

 1 function A*(start,goal)
 2  closedset := the empty set // The set of nodes already evaluated.
 3  openset := {start} // The set of tentative nodes to be evaluated, initially containing the start node
 4  came_from := the empty map // The map of navigated nodes.
 5 
 6  g_score[start] := 0 // Cost from start along best known path.
 7  // Estimated total cost from start to goal through y.
 8  f_score[start] := g_score[start] + heuristic_cost_estimate(start, goal)
 9  
10  while openset is not empty
11    current := the node in openset having the lowest f_score[] value
12    if current = goal
13      return reconstruct_path(came_from, goal)
14  
15    remove current from openset
16    add current to closedset
17    for each neighbor in neighbor_nodes(current)
18      tentative_g_score := g_score[current] + dist_between(current,neighbor)
19      if neighbor in closedset or tentative_g_score >= g_score[neighbor]
20        continue
21      if neighbor not in openset or tentative_g_score < g_score[neighbor] 
22        came_from[neighbor] := current
23        g_score[neighbor] := tentative_g_score
24        f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)
25        if neighbor not in openset
26          add neighbor to openset
27 
28  return failure
29 
30  function reconstruct_path(came_from, current_node)
31    if current_node in came_from
32      p := reconstruct_path(came_from, came_from[current_node])
33      return (p + current_node)
34    else
35      return current_node

סיבוכיות[עריכת קוד מקור | עריכה]

סיבוכיות הזמן של A* תלויה בהיורסטיקה, במקרה הגרוע ביותר, מספר הצמתים שיפותחו יהיה מעריכי ביחס לאורך הפתרון (המסלול הקצר ביותר). הסיבוכיות תהיה פולינמית אם מתקיימים התנאים הבאים: מרחב המצבים הוא עץ, קיים מצב מטרה יחיד והפונקציה ההיוריסטית h מקיימת:

|h(x) - h^*(x)| = O(\log h^*(x))

כאשר h* היא ההירוסטיקה האופטימלית, כלומר העלות המדויקת בין x למטרה.