الگوریتم دکسترا

در نظریه گراف، الگوریتم دیکسترا یکی از الگوریتم‌های پیمایش گراف است که توسط دانشمند هلندی علوم رایانه، ادسخر دیکسترا در سال ۱۹۵۹ ارائه شد.
این الگوریتم یکی از الگوریتم‌های پیمایش گراف است که مسئله کوتاه‌ترین مسیر از مبدا واحد را برای گراف‌های وزن‌داری که یال با وزن منفی ندارند، حل می‌کند و در نهایت با ایجاد درخت کوتاه‌ترین مسیر، کوتاه‌ترین مسیر از مبدا به همه راس‌های گراف را به دست می‌دهد. همچنین می‌توان از این الگوریتم برای پیدا کردن کوتاه‌ترین مسیر از مبدا تا راس مقصد به این ترتیب بهره جست که در حین اجرای الگوریتم به محض پیداشدن کوتاه‌ترین مسیر از مبدا به مقصد، الگوریتم را متوقف کرد.
الگوریتم دیکسترا یکی از الگوریتم‌های مورد استفاده برای محاسبه کوتاه‌ترین مسیر تک منبع (single-source shortest path) است و مشابه الگوریتم پریم می‌باشد در صورتی که گراف یال با وزن منفی داشته باشد، این الگوریتم درست کار نمی‌کند و می‌بایست از الگوریتم‌های دیگر نظیر الگوریتم بلمن-فورد که پیچیدگی زمانی آن‌ها بیشتر است استفاده کنیم.
خط مشی الگوریتم دیکسترا، مشابه با روش حریصانه استفاده شده در الگوریتم پریم برای پیدا کردن زیر درخت فراگیر بهینه است.
نام‌گذاری
نام این الگوریتم بر اساس نام ارائه‌دهنده هلندی آن، یعنی ادسخر دایکسترا انتخاب شده‌است. در منابع فارسی آن را به شکل‌های دیکسترا، دکسترا، دایکسترا، دایجسترا، دیجسترا، دایجکسترا و دیجکسترا هم نوشته شده است، ولی جیم آن در تلفظ هلندی آن تلفظ نمی‌شود، لذا دو مورد اول صحیح هستند.
روند
روند الگوریتم دایکسترا مطابق زیر می‌باشد:
۱- انتخاب راس مبدا
۲- مجموعه S، شامل رئوس گراف، معین می‌شود. در شروع، این مجموعه تهی بوده و با پیشرفت الگوریتم، این مجموعه رئوسی که کوتاه‌ترین مسیر به آن‌ها یافت شده‌است را در بر می‌گیرد.
۳- راس مبدا با اندیس صفر را در داخل S قرار می‌دهد.
۴- برای رئوس خارج از S، اندیسی معادل، طول یال + اندیس راس قبلی، در نظر می‌گیرد. اگر راس خارج از مجموعه دارای اندیس باشد، اندیس جدید کمترین مقدار از بین اندیس قبلی و طول یال + اندیس راس قبل، می‌باشد.
۵- از رئوس خارج مجموعه، راسی با کمترین اندیس انتخاب شده و به مجموعه S اضافه می‌گردد.
۶- این کار را دوباره از مرحله ۴ ادامه داده تا راس مقصد وارد مجموعه S شود.
در پایان اگر راس مقصد دارای اندیس باشد، اندیس آن نشان دهنده مسافت بین مبدا و مقصد می‌باشد. در غیر این صورت هیچ مسیری بین مبدا و مقصد موجود نمی‌باشد.
همچنین برای پیدا کردن مسیر می‌توان اندیس دیگری برای هر راس در نظر گرفت که نشان دهنده راس قبلی در مسیر طی شده باشد. بدین ترتیب پس از پایان اجرای الگوریتم، با دنبال کردن رئوس قبلی از مقصد به مبدا، کوتاه‌ترین مسیر بین دو نقطه نیز یافت می‌شود.
این الگوریتم چگونه کار می‌کند؟
در حین اجرای الگوریتم دو چیز به‌طور ضمنی نگهداری می‌شود. یکی مجموعه از راس‌هایی که وزن کوتاه‌ترین مسیر از مبدا تا آن‌ها مشخص شده و دیگری دنباله که برای هر راس ، مقدار برابر وزن کوتاه‌ترین مسیر از مبدا تا است به شرطی که تمام راس‌های این مسیر به جز از رئوس داخل باشند. در ابتدا تهی و مقادیر برای همه رئوس به غیر از مبدا بی‌نهایت است و مقدار آن برای مبدا صفر گذاشته می‌شود. الگوریتم در هر مرحله راسی خارج را که برای آن کمترین است انتخاب و به مجموعه اضافه می‌کند و سپس مقادیر را برای رئوس همسایه آن راس به‌روز می‌نماید. در صورتی که نیاز به تشکیل درخت کوتاه‌ترین مسیر باشد، الگوریتم می‌بایست دنباله را که پدر راس در درخت کوتاه‌ترین مسیر است، به همراه دنباله به‌روز کند.
الگوریتم
در پیاده‌سازی، برای اینکه مشخص کنیم چه رئوسی در مجموعه هستند، در هر مرحله راس وارد شده به را برچسب می‌زنیم.
پیاده‌سازی
یک پیاده‌سازی نوعی به این شرح است:
1 Algorithm Dijkstra(G,s)
2 Input : G=(V,E), s(the source vertex)
3 Output : two sequence d and
4 begin
5 for all vertices w do
6 =
7 = NULL
8 = ۰
9 while there exists an unmarked vertex do
10 let w be an unmarked vertex such that is minimum
11 mark w
12 for all edge (w,z) such that z is unmarked do
13 if then
14 =
15 = w
16 end
پیچیدگی زمانی
در ساده‌ترین پیاده‌سازی الگوریتم دایکسترا، داده‌ها در آرایه یا لیست پیوندی ذخیره می‌شوند که بدین ترتیب مینیمم مقدار برای رئوس خارج با الگوریتمی خطی یافت می‌شود. در این حالت پیچیدگی زمانی خواهد بود، چراکه در گراف بدون جهت هر یال دقیقا دوبار و در گراف جهت‌دار هر یال دقیقا یک بار پیمایش می‌شود و هم‌چنین پیدا کردن مینیمم، زمان می‌خواهد که این مینیمم پیدا کردن بار تکرار خواهد شد.
الگوریتم دایکسترا با نگهداری گراف در فهرست مجاورت و استفاده از هرم دودویی یا درخت جستجوی دودویی خود-متوازن (برای پیدا کردن مینیمم) با پیچیدگی زمانی پیاده‌سازی می‌شود. در صورت استفاده از هیپ فیبوناتچی به جای صف اولویت‌دار، پیچیدگی زمانی با آنالیز استهلاکی ( ) به بهبود می‌یابد.
کاربردها
از جمله مهمترین کاربردهای این روش می‌توان به محاسبه کوتاه‌ترین فاصله دو نقطه در یک شهر از طریق راه‌های زمینی اشاره نمود.
برای محاسبه کوتاه‌ترین مسیر بین دو نقطه باید نقاط مورد نظر در یک نقشه را علامت‌گذاری کرد و با استفاده از مشخصات نقاط (طول، عرض و ارتفاع) فاصله دو نقطه را در هر بار عملیات محاسبه نمود. توجه داریم که در ترافیک سرعت خودروها به شدت پایین آمده و این امر می‌تواند در انتخاب کوتاه‌ترین مسیر تاثیرگذار باشد چرا که ممکن است بین دو نقطه a,b راه‌های ۱و۲ موجود باشد که راه ۱ اتوبان و از خارج شهر و راه ۲ از داخل شهر عبور می‌کند.
فرض کنید فاصله a,b از طریق راه ۱ حدود ۱۰ کیلومتر و از طریق راه ۲ حدود ۷ کیلومتر باشد ولی راه ۲ علی رقم فاصله کمتر دارای ترافیک سنگین است در نتیجه می‌توان انتظار داشت که در ساعات شلوغی استفاده از راه ۱ بهتر باشد. از آن جا که اساس محاسبات در این روش بر پایه فاصله بین دو نقطه است می‌توان کاهش سرعت را با افزایش فواصل هم ارز نمود چرا که اگر رابطه سرعت و فاصله را خطی در نظر بگیریم (D=V.T)تاثیر کاهش سرعت و افزایش مسافت یکسان است. از این رو لازم است تا ضرایب تعدیلی در فواصل بین نقاط ضرب شده و این مسائل را در محاسبات لحاظ کرد.
از جمله مهم‌ترین این ضرایب می‌توان به ۳ مورد زیر اشاره نمود:
۱-ضریب ترافیک و شلوغی
۲-ضریب عرض معبر
۳-ضریب شیب که نشانگر افت سرعت در سر بالایی هااست.
گرچه تعیین این ضرایب برای نقاط مختلف شهر نیازمند کارشناسان متخصص ترافیک و بررسی‌های آماری دقیق می‌باشد ولی می‌توان انتظار داشت که در اکثر موارد این ضرایب بین مقادیر ۱ تا ۲ بسته به شرایط تغییر کنند.
مسیریابی (Routing)