تکنیکهای طراحی الگوریتم - روش تقسیم و تسخیر
تقسیم و تسخیر <span dir=ltr>(Divide-and-Conquer)</span>
طراحی الگوریتم در این روش بدین صورت حاصل میشود که:
مورد اصلی مسئلهی داده شده برای حل را به چندین مورد کوچکتر (از همان نوع مورد اصلی) تقسیم میکنیم٬ سپس موارد کوچکتر را بطور مجزا حل و نتیجه حاصل از هر زیر مورد را با هم ترکیب کرده تا نتیجه مورد اصلی مسئله را بیابیم.
اگر تاکنون از روتینهای بازگشتی (Recursive Procedures) برای حل مسائل استفاده کرده باشید با روش کار تقسیم و تسخیر از پیش آشنایی دارید.
الگوریتمهایی که با این روش طراحی میشوند از دید من بسیار زیبا٬ ساده و خوانا هستند. اما این نکته منفی را هم نباید از قلم انداخت که اگر تعداد موارد منقسم شده از مورد اصلی زیاد باشد٬ ممکن است بازده الگوریتم حاصل از روش تقسیم و تسخیر افت کند.
مثال 1: جستجوی دودویی (Binary Search)
در نظر بگیرید که فهرستی از اسامی و آدرسهای مرتبط به هر اسم داشته باشیم و این فهرست دارای N جفت اسم و آدرس باشد که به ترتیب حروف الفبا بر اساس اسم مرتب شده و در دو آرایه نگهداری شوند:
Names(1..N)
Numbers(1..N)
میخواهیم با دادن هر اسم٬ آدرس مربوط به اسم را بیابیم. در این مثال فرض میکنیم که هر اسم مورد پرسش حتما در آرایه وجود دارد تا الگوریتم و شرح آن را سادهتر کرده باشیم.
الگوریتم تقسیم و تسخیری که این مسئله را حل میکند٬ سادهترین الگوریتم در این مدل الگوریتمی است که حاصل نگرشی بگونه زیر است:
اسم داده شده
یا
درست در وسط فهرست قرار دارد
یا
در نیمه بالایی فهرست (بالا)
یا
در نیمه پایینی فهرست (پایین)
چون فهرست مرتب شده است٬ پس شرط بالا در صورتی درست است که اسم داده شده کوچکتر از اسم قرارگرفته در قسمت میانی باشد. و شرط پایین در صورتی درست است که اسم داده شده بزرگتر از اسم قرارگرفته در قسمت میانی باشد.
این دید به مسئله٬ الگوریتم زیر را در پی خواهد داشت:
function Search(X: name; Start, Finish: integer) return address
Middle: integer
begin
Middle <- (Start + Finish) / 2
if X = Names(Middle) then
return Numbers(Middle)
elseif X < Names(Middle) then
return Search(X, Start, Middle - 1)
else -- X > Names(Middle)
return Search(X, Middle + 1, Finish)
endif
end
الگوریتم بالا رو چگونه باید اصلاح کرد تا جوابگوی حالتی باشد که اسم وارد شده در فهرست موجود نیست؟ یا با عبارت متداول برای الگوریتمهای تقسیم و تسخیر، در چه مرحلهای این اصلاح صورت گرفته شود؟
مثال 2: بدست آوردن همه ترکیبهای مجموعهای از عناصر (Permutations)
با چیدن اعداد 4 و 5 و 8 چه اعدادی میتوان بدست آورد؟ با چیدن حروف الف و میم و لام در کنار هم چه واژههای میتوان ساخت؟ شرح و الگوریتم حل این مسئله با روش تقسیم و تسخیر را قبلا در جواب پرسش یکی از دوستان در پست دیگری نوشته ام. لطفا به لینک زیر رجوع کنید:
http://www.barnamenevis.org/vi...?p=13185#13185
----------------------------------------------------------------------------------------------------------
تکنیکهای طراحی الگوریتم - مقدمه
نقل قول: تکنیکهای طراحی الگوریتم - روش تقسیم و تسخیر
سلام من سه تا سوال دارم اگه کسی جواب شو میدونه لطف کنه بگه عجله دارم
1-چرا در جستجوی باینری آرایه رو به دو قسمت تقسیم میکنه در هر مرحله.چرا به سه قسمت تقسیم نمیکنه؟؟
2-چرا جستجوی باینری روی لیست نیمه مرتب هم جواب می دهد؟؟
3-چرا برای به دست آوردن خانه وسط آرایه وقتی شماره خانه ابتدا و انتها جمع میشود و بر 2 تقسیم میشود حد بالای عدد به دست آمده را در نظر گرفته و خانه وسط را پیدا میکنیم مثلا آرایه 5 عنصری
2.5= 2/(1+5)
و خانه 3 میشود خانه وسط چرا حد پایین را نمیگیریم یعنی 2 ؟؟؟
نقل قول: تکنیکهای طراحی الگوریتم - روش تقسیم و تسخیر
1.برای اینکه دیگه اسمش باینری نمیشه.برای ۳ قسمت جست و جو کنید ternary search
2.جواب نمیده.
۳.چون اونطوری خانه وسط از قلم میافته.