منبع اصلی نوشتار زیر در این لینک قرار دارد

پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف – بازگشتی (Shortest path)

shortest distance4 پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)

پیدا کردن کوتاه ترین مسیر بین دو نقطه در یک گراف اهمیت خیلی زیادی در علوم مختلف مانند الگوریتم  ٫ ریاضی ٫ حمل و نقل ٫تجارت و …. دارد .

ده ها است که روی این مسیله کار شده است و  الگوریتم های متفاوت و با هزینه های مختلفی از آن ساخته شده است.

برای پیدا کردن کوتاه ترین مسیر بین دو نقطه الگوریتم های بسیار زیادی وجود دارد ولی سه الگوریتم با سه روش مختلف وجود دارند که بسیار معروف هستند :

۱- الگوریتم به روش بازگشتی (Recursion)

۲-  الگوریتم به روش برنامه نویسی پویا (Dynamic programming ) : معروف به فلوید

۳- الگوریتم به روش حریصانه  (Greedy ) :معروف به دایکسترا

ما در این پست الگوریتم بازگشتی را بررسی می کنیم و دو الگوریتم دیگر را در پست هایی جداگانه بررسی خواهیم کرد.

فرض کنید گراف زیر را دارید و می خواهید کوتاه ترین فاصله بین دو نقطه دلخواه را پیدا کنید ، ما حل سوال را با این مثال ادامه می دهیم:

graph پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path) همین طور که در بالا می بینید گراف دارای راس های v0 – v1- v2-v3-v4  است و راه های موجود بین راس ها با یال های که از آن راس خارج شده و به راس دیگر وارد شده است مشخص شده است و فاصله بین دو نقطه برابر با  عددی است که روی یال نوشته شده است.

ما برای پیدا کردن کوتاه ترین مسیر ها باید گراف را پردازش کنیم برای این کار گراف را به صورت ماتریس مجاورت در می آوریم ، ماتریس مجاورت گراف بالا به صورت زیر است :
فشذمث پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)در گراف قبل از راس سه به یک راهی وجود نداشت به همین خاطر در ماتریس بالا جاهایی که یالی وجود ندارد مقدار بینهایت (Infinity) گذاشتم .

فرض کنید می خواهیم کوتاه ترین مسیر از گره شماره ۲ را به گره شماره یک پیدا کنیم ، ابتدا گره ی مقصد  را که همان گره ی شماره یک است را در نظر می گیریم و شروع به عقب آمدن می کنیم تا به مبدا حرکت برسیم که اینجا گره شماره دو است  و از میان تمام راه های ممکن کوتاه ترین راه را  انتخاب می کنیم.

به ستون  زیر گره ی شماره یک نگاه کنید که  پنج خانه در زیرش قرار دارد که می گویند :

خانه اول : اگر از نود صفر به یک برویم طول مسیر برابر یک است

خانه دوم : اگر از نود یک به به نود یک برویم طول مسیر برابر صفر است

خانه سوم : اگر از نود دو به نود یک برویم طول مسیر بی نهایت است یعنی در واقع مسیری وجود ندارد

خانه چهارم : اگر از نود سوم به نود یک برویم هزینه بی نهایت است

خانه پنجم : اگر از نود چهار به نود یک برویم هزینه بی نهایت است

پس خانه های زیر نود  یک ، مسیر های منتهی به نود یک را نشان می دهد ، از میان مسیر هایی که به نود یک منتهی می شود فقط مسیر صفر به یک مورد قبول است .

حالا صورت سوال را تغییر می دهیم:

   کوتاه ترین مسیر از نود دو به یک  = کوتاه ترین مسیر از نود دو به نود صفر + فاصله نود صفر تا نود یک

 که حالا همین کار را برای کوتاه ترین مسیر از نود دو به نود صفر می کنیم، همین طور که می بینید دو مسیر داریم که به نود صفر منتهی می شود یکی نود یک به نود صفر که طولی برابر نه دارد و دیگری مسیر نود چهار به نور صفر که طولی برابر سه دارد پس کوتاه تریم مسیر از نود دو به نود صفر اینگونه محاسبه می شود

کوتاه ترین مسیر از نود شماره دو به نود صفر = min( کوتاه ترین مسیر از نود دو به نود یک به علاوه نه ، ک.تاه ترین مسیر از نود شماره دو به نود شماره چهار به علاوه سه)

و همین کار را تا آخر ادامه می دهیم .

فقط ممکن است تو مسیری دایره واز بیفتیم و هیچ وقت خارج نشویم برای حل این مشکل در کد چک می کنیم که اگر نود های نوجود در مسیر از تعداد کل نود های منهای یک بزرگ تر مساوی بود مسیر قابل قبول نیست زیرا طبق اصل لانه کبوتری نودی وجود دارد که حداقل دوبار از آن عبور شده است

کد زیر تابع مربوط به حل بازگشتی مساله است

  int ** table :  ماتریس مجاورت است که به صورت اشاره گر به تابع فرستاده می شود

n : تعداد راس های موجود در گراف است

p: راس مبدا  است

q: راس مقصد است

z: تعداد راس های موجود در مسیر طی شده است

// Short distance.cpp
//

#include "stdafx.h"
#include <iostream>

#define inf 2000000000 

using namespace std;

int short_distance(int **table, int n, int p,int q, int z)
{
	int min = inf;
	int *A;
	A = new int[n];
	
	if (p == q)
	{
		return 0;
	}
	if (z >= n-1 )
	{
		return inf;
	}
	
	for (int i = 0; i < n; i++)
	{
		if (table[i][q] != 0 && table[i][q] != inf)
		{
			A[i] = table[i][q] + short_distance(table, n, p, i, z + 1);
			if (min > A[i] && A[i] > 0)
			{
				min = A[i];
			}
		}
	}
	return min;
}

کد زیر یک مثال از کد بالاست که  دارای main  است و برای نمونه مثالی را که بررسی کردیم  را به تابع  فرستادم که مقدار یازده را به عنوان جواب بازگرداند:

// Short distance.cpp
//

#include "stdafx.h"
#include <iostream>

#define inf 2000000000 

using namespace std;

int short_distance(int **table, int n, int p,int q, int z)
{
	int min = inf;
	int *A;
	A = new int[n];
	
	if (p == q)
	{
		return 0;
	}
	if (z >= n-1 )
	{
		return inf;
	}
	
	for (int i = 0; i < n; i++)
	{
		if (table[i][q] != 0 && table[i][q] != inf)
		{
			A[i] = table[i][q] + short_distance(table, n, p, i, z + 1);
			if (min > A[i] && A[i] > 0)
			{
				min = A[i];
			}
		}
	}
	return min;
}

int main( )
{
	//define table
	int **table;
	table = new int *[5];
	for (int i = 0; i < 5; i++)
	{
		table[i] = new int[5];
	}

	table[0][0] = 0;
	table[0][1] = 1;
	table[0][2] = inf;
	table[0][3] = 1;
	table[0][4] = 5;

	table[1][0] = 9;
	table[1][1] = 0;
	table[1][2] = 3;
	table[1][3] = 2;
	table[1][4] = inf;

	table[2][0] = inf;
	table[2][1] = inf;
	table[2][2] = 0;
	table[2][3] = 4;
	table[2][4] = inf;

	table[3][0] = inf;
	table[3][1] = inf;
	table[3][2] = 2;
	table[3][3] = 0;
	table[3][4] = 3;
	
	table[4][0] = 3;
	table[4][1] = inf;
	table[4][2] = inf;
	table[4][3] = inf;
	table[4][4] = 0;
	//

	cout << "Short distance among 2 and 1 :=  " << short_distance(table, 5, 2, 1, 0) << endl << endl;

	return 0;
}

 

digg پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  reddit پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  stumbleupon پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  yahoo buzz پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  dzone پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  facebook پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  delicious پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  dotnetkicks پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  dotnetshoutout پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  linkedin پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  technorati پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  twitter پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  google buzz پیدا کردن کوتاه ترین مسیر بین دو نقطه در گراف   بازگشتی (Shortest path)  



برچسب ها : , , , ,