سورس کد پیاده‌سازی الگوریتم A* در سی‌شارپ: شرحی کامل و جامع


الگوریتم A* (ای‌ستار) یکی از قدرتمندترین و پرکاربردترین الگوریتم‌های مسیریابی در حوزه‌های مختلف، از جمله بازی‌های رایانه‌ای، رباتیک، و سیستم‌های ناوبری است. این الگوریتم، با ترکیب بین جستجوی گرایش‌مند و بهینه‌سازی، توانسته است در حل مسائل پیچیده، مسیرهای کوتاه و بهینه را پیدا کند. در ادامه، به تفصیل درباره پیاده‌سازی این الگوریتم در زبان برنامه‌نویسی سی‌شارپ، نکات مهم، ساختارهای داده‌ای مورد نیاز، و نحوه عملکرد آن صحبت خواهیم کرد.

مفهوم کلی الگوریتم A*




در اصل، A* بر پایه نظریه گراف و جستجوهای مبتنی بر بهترین مسیر بنا شده است. هدف اصلی، یافتن کوتاه‌ترین مسیر بین دو نقطه است، به گونه‌ای که هزینه کلی کمینه شود. این الگوریتم، با استفاده از یک تابع هزینه، که ترکیبی از هزینه مسیرهای پیموده شده و برآورد هزینه باقی‌مانده است، در هر مرحله تصمیم می‌گیرد که کدام مسیر را ادامه دهد. این تابع، معمولاً به صورت:
`f(n) = g(n) + h(n)`
تعریف می‌شود، که در آن:
- `g(n)` هزینه مسیر از نقطه مبدا تا نود `n` است.
- `h(n)` برآورد هزینه کمینه از نود `n` تا مقصد است، که معمولاً بر اساس تابع heuristic (پیشنهادگر) تعیین می‌شود.
در واقع، این ترکیب، باعث می‌شود الگوریتم نه تنها به دنبال مسیرهای کوتاه باشد، بلکه در مسیرهای احتمالی، به سمت مسیرهای بهینه‌تر هدایت شود.

ساختارهای داده‌ای مورد نیاز در پیاده‌سازی A*




در پیاده‌سازی این الگوریتم، استفاده از ساختارهای داده‌ای مناسب، اهمیت ویژه‌ای دارد. معمولاً، موارد زیر برای نگهداری و مدیریت مسیرها و نودها مورد نیاز است:
- لیست باز (Open List): شامل نودهایی است که هنوز بررسی نشده‌اند، اما در آینده باید ارزیابی شوند. این لیست باید به گونه‌ای باشد که بتوان سریع‌ترین نود بر اساس مقدار `f(n)` را پیدا کرد، بنابراین، معمولاً از ساختارهای داده‌ای مانند PriorityQueue یا Heap استفاده می‌شود.
- لیست بسته (Closed List): شامل نودهایی است که قبلاً بررسی شده و مسیرهای بهینه‌شان مشخص شده است. این لیست برای جلوگیری از تکرار و حلقه‌های بی‌نهایت بسیار مهم است.
- نود (Node): هر نود باید شامل اطلاعاتی مانند مختصات، هزینه مسیر (`g(n)`)، برآورد هزینه باقی‌مانده (`h(n)`)، و اشاره‌گر به نود پدر باشد، تا پس از پیدا کردن مسیر، بتوان مسیر نهایی را ترسیم کرد.

پیاده‌سازی گام‌به‌گام الگوریتم A* در سی‌شارپ




در ادامه، به شرح مراحل پیاده‌سازی می‌پردازیم:

  1. تعریف کلاس Node




ابتدا، باید یک کلاس تعریف کنیم که ویژگی‌های هر نود را نگهداری کند. در این کلاس، مواردی مانند مختصات، هزینه‌ها، و ارجاعات به نود والد قرار می‌گیرد. مثلاً:
csharp  

public class Node

{

public int X { get; set; }

public int Y { get; set; }

public float G { get; set; } // هزینه پیموده شده

public float H { get; set; } // برآورد هزینه باقی‌مانده

public float F => G + H; // مجموع هزینه‌ها

public Node Parent { get; set; }

public bool IsWalkable { get; set; }

}


  1. تعریف تابع heuristic (پیشنهادگر)




برای برآورد هزینه باقی‌مانده، معمولا از تابع Manhattan، Euclidean، یا Octile استفاده می‌شود. برای مثال، در فضای مربعی، تابع Manhattan مناسب است:
csharp  

private float CalculateHeuristic(Node currentNode, Node goalNode)

{

return Math.Abs(currentNode.X - goalNode.X) + Math.Abs(currentNode.Y - goalNode.Y);

}
... ← ادامه مطلب در magicfile.ir