از تکنیک عقبگرد برای حل مسائلی استفاده می شود که در آن ها دنباله ای از اشیاء از یک مجموعه مشخص انتخاب می شود، به طوری که این دنباله ، ملا کی را در بر می گیرد.
در نظریه گراف، الگوریتم کراسکال الگوریتمی برای یافتن یک زیرگراف فراگیر همبند با کمترین وزن در یک گراف وزندار است (در یک گراف وزن دار، به هر یال وزنی نسبت داده شدهاست). همچنین این الگوریتم برای یافتن کوچکترین درخت فراگیر در یک گراف وزن دار استفاده میشود.
به عنوان مثال فرض کنید یک شبکه راه آهن که تعدادی شهر را به یکدیگر متصل میکند در دست احداث است میخواهیم با داشتن هزینه مربوط به احداث خط مستقیم بین شهرهای
شبکه را طوری طراحی کنیم که مجموع هزینههای ساخت به کمترین مقدار خود
برسد. با در نظر گرفتن هر شهر به عنوان یک راس از گراف وزن دار با وزنهای
مسئله به یافتن یک زیر گراف فراگیر همبند با کمترین وزن در یک گراف منجر میشود.
فرض کنید وزنها نامنفی هستند بنابراین میتوانیم تصور کنیم که زیر گراف فراگیر با کمترین وزن یک درخت فراگیر از
است حال الگوریتم زیر را برای این کار ارائه میدهیم.
دانلود سورس از لینک زیر
http://www.programyar.com/?p=5183%7B%7Bسخ}}
نمونهای از خروجی برنامه:
ثابت میکنیم هر درخت فراگیر با یالهای
که با الگوریتم کراسکال ساخته شود یک درخت بهینهاست.
از طریق تناقض: به ازای هر درخت فراگیر از
به غیر از
کوچکترین مقدار
را به طوری که
در
نباشد با
نمایش میدهیم. اکنون فرض کنید که
یک درخت بهینه نباشد و
را به عنوان درخت بهینه در نظر بگیرید که در آن
دارای بزرگترین مقدار ممکن باشد. فرض کنید
این بدان معنی است که
هم در
و هم در
هستند؛ ولی
در
نیست پس شامل یک دور یکتای
میباشد. فرض کنید
یالی از
باشد که در
هست ولی در
نیست. پس
یال برشی ازT+
نیست؛ بنابراین
یک گراف همبند با
یال بوده در نتیجه درخت فراگیر دیگری برای
خواهد بود. روشن است که:
ولی در الگوریتم کراسکال به عنوان یالی با کمترین وزن طوری انتخاب شدهاست که زیرگراف
با یالهای
بدون دور باشد. چون زیرگراف
با یالهای
زیر گرافی از
است. بنابرین ان هم بدون دور است و نیتجه میگیریم که:
≥
پس
≤
پس هم یک درخت بهینه خواهد بود در صورتی که داریم:
که این با انتخاب در تناقض است. بنابرین
و در نتیجه
یک درخت بهینهاست.
مسئله:یک درخت پوشای می نیمم مشخص کنید.
ورودی:عدد صحیح n>=۲، عدد صحیح مثبت m و یک گراف بدون جهت و وزن دار و متصل شامل n گره و m لبه. گراف با یک مجموعه E که شامل لبههای گراف همراه با وزنهای آنها است نشان داده میشود
خروجی:مجموعهای از لبهها F در یک درخت پوشا مینیمم
* Void kruskal (int n , int m , * set _of_edges E, * set_of_edges & F) * { * index i, j; * Set_pointer p , q ; * edge e; * Sort the m edges in E by weight in nondecreasing order ; * F=∅; * initial(n); //زیر مجموعه غیر الحاقی n مقدار دهی * While(number of edges in F is less than n-1){ * e= edge with least weight not yet considered; * i, j = indices of vertices connected by e ; * p=find(i); * q=find(j); * if(!equal(p,q)){ * merge(p,q); * add e to F ; * } * } * }
هرگاه n-1 لبه در F وجود داشته باشد، از حلقه whileخارج میشویم؛ زیرا در اینصورت، n-1 لبه در یک درخت پوشا وجود خواهد داشت
void sort(struct krus ed[],int m) { struct krus temp; for (int i=۰;i<m;i++) for (int j=i+1;j<m;j++) if (ed[j].weight<ed[i].weight) { temp=ed[i]; ed[i]=ed[j]; ed[j]=temp; } }
الگوریتم پریم، الگوریتمی در نظریه گرافها است که زیردرخت پوشای کمینه را برای یک گراف همبند وزن دار پیدا میکند یعنی زیرمجموعهای از یالها را در آن گراف مییابد که درختی را تشکیل میدهند که همه رئوس را شامل میشود در حالیکه مجموع وزن همه آن یالها کمینه شدهاست. این الگوریتم در سال ۱۹۳۰ توسط ریاضیدانی به نام جارنیک داده شد وسپس در سال ۱۹۵۷ پریم، دانشمند علوم کامپیوتر آن را مستقل از جارنیک کشف کرد و در سال ۱۹۵۹ دایکسترا دوباره به آن دست یافت. ازاین رو این الگوریتم گاهی با نام الگوریتم DJP نیز شناخته میشود که برگرفته از اسامی دایکسترا، جارنیک و پریم است.
این الگوریتم مرتب سازی درخت را که از یک یال شروع شدهاست، افزایش میدهد تاجائی که همه رئوس وارد درخت شوند.
این الگوریتم را به طور خلاصه میتوان چنین شرح داد:
نکته: الگوریتم پریم را به این صورت نیزمی توان بیان کرد:ابتدا گره ای به دلخواه انتخاب شود و سپس از بین یالهای متصل به آن یالی با کمترین وزن انتخاب می شود به گونه ای که حلقه ایجاد نشود.در هر مرحله یالی انتخاب می شود که حتماً یکی از دو سرآن جزو مسیر جواب بوده و وزن حداقل داشته باشد.پس درالگوریتم پریم دو محدودیت در هر مرحله داریم یکی آن که جنگل ایجاد نشود و دوم آنکه حلقه پدید نیاید.
از آنجا که درالگوریتم پریم درهرمرحله فاصله هر گره با گره های قبلی مقایسه می شود پس بدیهی است که ازمرتبه (n2)Ѳ می باشدکه n تعداد رئوس گراف است.
یک پیاده سازی ساده، استفاده از نمایش گراف به صورت ماتریس مجاورت است که درآن به دنبال آرایهای از وزنها باشیم و یالهای با وزن کمینه را به مجموعه خود بیفزائیم. این روش (O(V۲ زمان میبرد. الگوریتم پریم بااستفاده از داده ساختار هیپ دودوئی ساده و نمایش فهرست مجاورت میتواند در زمان (O(E log V اجرا شود که در آن E تعداد یالها و V تعداد رئوس است. استفاده از مدل پیچیده تری به نام هیپ فیبوناچی باعث میشود این زمان تا حد (O(E + V log V کاهش یابد. سرعت این روش به خصوص زمانی آشکار میشود که در گراف رابطه (E = ω(V بین رئوس و یالها برقرار باشد.
مسئله:یافتن کوچکترین درخت پوشا.
ورودی: عدد صحیح n>=2و یک گراف بدون جهت و وزن دار و پیوسته شامل n گره . گراف توسط یک آرایه دو بعدی w که سطر ها و ستونهایش ار 1 تا n شاخص دهی شده اند نشان داده می شود که در ان [w[i][j معرف وزن لبه بین گره i ام و گره j ام است .
خروجی:مجموعه ای از لبه ها F در یک درخت پوشای مینیمم برای گراف.
* void prim( int n, * const number w[][], * set_of_edges & F) * { * index i, vnear; * number min ; * edge e; * index nearest[2..n]; * number distance[2..n]; * F = ∅ ; * for ( i = 2; i<=n;i++){ * nearest[i] = 1 ; * distance[i] = W[1][i]; * } * repeat (n-1 times ){ * min=∞; * for(i=2; i<=n; i++){ * if(0≤ distance[i] <min ){ * min = distance [i]; * vnear = I ; * } * e= edge connecting vertices indexed by vnear and nearest[vnear ]; * add e to F ; * distance[vnear]= -1 * for ( i=2 ; i<= n ;i++) * if(W[i][vnear] <distance[i]){ * distance[i] = w[i][vnear]; * nearest[i] = vnear; * } * } * }
اگر در لحظه شروع {y={v1 باشد،لذا [nearest[i با 1 و [distance[i با وزن لبه بین v1 و vi مقدار دهی اولیه میشود.همانطوری که گره ها به Y اضافه میشوند،این دو ارایه برای ارجاع گره جدید در Y به نزدیکترین گره خارج از Y ، بهنگام (update)میشوند.برای معین کردن گره ای که باید به Y اضافه شوند ،در هر تکرار ،شاخصی که مقدار distance[i]1 ان مینیمم است را محاسبه می کنیم. این شاخص را vnear می نامیم. با مقداردهی [distance[vnear به1- ، گره با شاخص vnear به Y اضافه می گردد . الگوریتم بالا این روال را پیاده سازی میکند
if (y!=0)
{
p+=e.weight; cout<<"("<<e.v1<<","<<e.v2<<") => W :"<<e.weight<<"\t"; set[e.v1]=0; set[e.v2]=0; fe++; } else break; } return p;
}
منبع: ویکی پدیا
(T (n) = 2 ( n – 1) ( n – 1) Є θ ( n²
از تکنیک عقبگرد برای حل مسائلی استفاده می شود که در آن ها دنباله ای از اشیاء از یک مجموعه مشخص انتخاب می شود، به طوری که این دنباله ، ملا کی را در بر می گیرد.
اندازه ورودی : n ، تعداد رئوس و m تعداد یال ها.
“من هیچ استعداد خاصی ندارم. فقط عاشق کنجکاوی هستم” ادامه مطلب ...
اگر شما عاشق کامپیوتر هستید، کمی استعداد طراحی و گرافیکی دارید و از انجام کارهای خلاقانه لذت می برید، این شغل مناسب شماست. طراح وب از خلاقیت و مهارت های فنی خود برای ایجاد و طراحی وب سایت ها استفاده می کند. ادامه مطلب ...