دانشکده ی علوم ریاضی ساختمان داده ها ۶ مهر ۲ جلسه ی ۵: حل روابط بازگشتی مدر س: دکتر شهرام خزاي ی نگارنده: ا رمیتا ثابتی اشرف و علی رضا علی ا بادیان ۱ مقدمه پیدا کردن کران مجانبی توابع معمولا با پیچیدگی همراه است و راه حل ا سانی ندارد هنگامی که روابط بازگشتی داشته باشیم این کار سخت تر هم می شود برای محسابه ی زمان اجرای الگوریتم های تقسیم و حل لازم است که کران مجانبی روابط بازگشتی ا ن ها رو پیدا کنیم در این بخش تکنیک هایی برای پیدا کردن کران های روابط بازگشتی معرفی می کنیم و در انتها قضیه ی اصلی عنوان می شود که در پیدا کردن کران مجانبی طیف وسیعی از توابع کاربرد دارد در زیر نمونه های ساده ای از روابط بازگشتی به همراه جواب ا ن ها مشاهده می شوند: ۱ n = ۱ n T (n ۱) + ۱ n ۲ ۱ n = ۱ ۲T ( n ۲ ) + n n ۲ n log n + n ۰ n = ۲ T ( n) + ۱ n log log n ۱ n = ۱ T ( n ) + T ( ۲n Θ(n log n) ) + n n ۲ یکی از روش هایی که می توانیم برای حل این روابط استفاده کنیم این است که ابتدا فرم کلی جواب را حدس بزنیم سپس با کمک استقرا مقادیر ثابت را پیدا کنیم و نشان دهیم که جوابمان درست است این روش روش خوبی برای حل روابط بازگشتی است ولی باید بتوانیم در ابتدا فرم جواب را حدس بزنیم نکته ۱ وقتی ما مساله ای را به صورت مجانبی حل می کنیم دیگر برایمان مقدار اولیه مهم نیست البته اگر موقع اثبات استقرایی به مقدار ثابتی جز مقدار ثابت اولیه (فرض شده) برسیم اثباتمان غلط است نکته ۲ روشی کلی برای این که حدس خوبی در مورد جواب رابطه ی بازگشتی بزنیم وجود ندارد ولی اگر رابطه ای شبیه به رابطه ای که قبلا دیده ایم باشد بهتر است که حدس ما شبیه به جواب رابطه ی قبلی باشد مثال ۱ کران بالای مجانبی تابع ۴T ( n ) + n چیست ۴ به اشتباه حدس می زنیم که کران بالای مجانبی O(n) باشد بنابراین فرض ناصحیح استقرا به صورت زیر است: ضریب ثابت c وجود دارد به طوریکه برای n های به اندازه کافی بزرگ داریم T (n) cn حال ببینیم چه مشکلی در روند اثبات گذار استقرا پیش میا ید پایه: با توجه به این که (۱)O T (۱) = نیازی به چک کردن پایه استقرا نیست ۵-۱
گام : فرض کنید به ازای همه ی n هایی که n < n از جمله n = n ۴ فرض استقرا برقرار باشد حال داریم: T (n ) cn = T ( n ۴ ) c n ۴ = T (n) ۴(c n ) + n = cn + n = (c + ۱)n ۴ چون به فرض استقرا نرسیدیم استدلال غلط است پس نمی توانیم ادعا کنیم O(n) است ۲T ( n ۲ چیست مثال ۲ کران دوطرفه مجانبی تابع Θ(n) + ) حدس می زنیم که کران دوطرفه مجانبی (n Θ(n log باشد برای اثبات باید نشان دهیم: I) O(n log n) II) Ω(n log n) T (n) ۲T ( n ۲ برای ابتدا (I) را اثبات می کنیم فرض کنید c ضریب ثابتی باشد که به ازای ا ن رابطه ی + cn ) n های به اندازه ی کافی بزرگ برقرار است فرض استقرا را به صورت زیر در نظر می گیریم: ضریب ثابت d وجود دارد به طوری که برای n های به اندازه کافی بزرگ T (n) dn log n است T ( n ۲ ) d n ۲ log n ۲ T (n) ۲T ( n ۲ ) + cn ۲(d n ۲ log n ۲ ) + cn = dn log n dn + cn رابطه ی فوق نشان می دهد که اگر d c انتخاب شود فرض T (n) dn log n صحیح است بنابراین (I) برقرار T (n) ۲T ( n ۲ حال (II) را اثبات می کنیم فرض کنید c ضریب ثابتی باشد که به ازای ا ن رابطه ی + cn ) برای n های به اندازه ی کافی بزرگ برقرار است فرض استقرا را به صورت زیر در نظر می گیریم: ضریب ثابت d وجود دارد به طوری که برای n های به اندازه کافی بزرگ T (n) dn log n T ( n ۲ ) d n ۲ log n ۲ T (n) ۲T ( n ۲ ) + cn ۲(d n ۲ log n ۲ ) + cn = dn log n dn + cn رابطه ی فوق نشان می دهد که اگر d c انتخاب شود فرض T (n) dn log n صحیح است بنابراین (II) هم برقرار است ۲T ( n ۲ صدق می کند n) Θ(n log است در نتیجه کران دوطرفه مجانبی تابع (n) T که در رابطه Θ(n) + ) مثال کران بالای مجانبی تابع ) Θ(n۲ ۸T ( n ۲ ) + چیست حدس می زنیم که کران بالای مجانبی ) O(n باشد فرض کنید c ضریب ثابتی باشد که به ازای ا ن رابطه ی T (n) ۸T ( n ۲ ) + cn۲ برای n های به اندازه ی کافی بزرگ برقرار است فرض استقرا را به صورت زیر در نظر می گیریم: ضریب ثابت d وجود دارد به طوری که برای n های به اندازه کافی بزرگ T (n) dn با توجه به این که رفتار مجانبی تابع تغییر نمی کند می توانیم برای راحتی در اثبات فرض استقرا را به صورت زیر اصلاح نماییم: ضرایب ثابت d و d وجود دارند به طوری که برای n های به اندازه کافی بزرگ T (n) dn d n ۲ حال با دنبال کردن اثبات گذار استقرا شرایط لازم برای وجود چنین d و dای را تعیین می کنیم: ۵-۲
T (n) ۸T ( n ۲ ) + cn۲ ۸(d( n ۲ ) d ( n ۲ )۲ ) + cn ۲ = dn d n ۲ + cn ۲ رابطه ی فوق نشان می دهد که اگر d d c انتخاب شود فرض T (n) dn d n ۲ صحیح است در نتیجه کران بالای مجانبی تابع (n) T که در رابطه ) Θ(n۲ ۸T ( n ۲ ) + صدق می کند ) O(n است ۲ درخت بازگشت در این جا استفاده از درخت بازگشت (درخت محاسبه) را به عنوان یک روش کارا مد برای حدس زدن جواب روابط بازگشتی معرفی می کنیم ساختار این درخت بدین شکل است که هر گره نماینده ی یک زیر مساله از مسي له ی اصلی است و فرزندانش نشان دهنده ی این امرند که به صورت بازگشتی مسي له به زیر مسي له هایی با چه اندازه ای می شکند برای یافتن هزینه ی حل بازگشتی مسي له در درخت پایین می رویم تا به زیر مسي له ای برسیم که هزینه ا ن را می دانیم و پس از ا ن هزینه هر گره مجموع هزینه های فرزندانش به علاوه ی هزینه شکستن ا ن به زیر مساي ل (که اغلب ثابت است) می شود با استفاده از درخت بازگشت می توان اغلب حدس های متناسب تری زد است T ( n ) + T ( ۲n چیست مثال ۴ کران دوطرفه مجانبی تابع Θ(n) + ) با استفاده از درخت بازگشت سعی می کنیم حدس مناسبی برای کران دوطرفه مجانبی تابع (n) T بزنیم فرض کنید c T (n) T ( n ) + T ( ۲n برقرار باشد درخت زیر را ضریب ثابتی باشد که برای nهای به اندازه کافی بزرگ رابطه + cn ) در نظر بگیرید که در ا ن برگ ها به مقدار (۱)O ختم می شوند عددی که در کنار هر سطح درخت نوشته شده حداکثر هزینه ای است که برای تقسیم و ترکیب زیرمسا له ها نیاز است این عدد برای همه سطح ها یسکسان و حداکثر برابر cn n cn n ۲n c( n + ۲n ) = cn n ۲n ۲n ۴n c( n + ۲n + ۲n + ۴n ) = cn مجموع( n O(n lg طولانی ترین مسیر از ریشه به یک برگ مسیر زیر است: n ( ۲ )n ( ۲ )۲ n ۱ ۵-
( ۲ ۲ است پس ارتفاع درخت برابر با n) h = O(log n) = O(lg اگر ارتفاع درخت را با h نشان دهیم چون (۱)O h( n = خواهد بود ما انتظار داریم که جواب رابطه بازگشتی حداکثر برابر با تعداد مرحله ها ضرب در هزینه ی هر مرحله یا n) O(cn log n) = O(n lg باشد پس حدس می زنیم که کران دوطرفه مجانبی n) Θ(n log باشد ۲ برای اثبات دقیق ادعای فوق باید نشان دهیم: I) O(n log n) II) Ω(n log n) T (n) T ( n )+T ( ۲n ابتدا (I) را اثبات می کنیم فرض کنید c ضریب ثابتی باشد که به ازای ا ن رابطه ی )+cn برای n های به اندازه ی کافی بزرگ برقرار است فرض استقرا را به صورت زیر در نظر می گیریم: ضریب ثابت d وجود دارد به طوری که برای n های به اندازه کافی بزرگ T (n) dn log n T (n) dn log n T (n) T ( n ) + T ( ۲n ) + cn d n log n + d ۲n log ۲n + cn = d n log n d n log + d ۲n log n d ۲n = dn log n dn log + cn log + cn رابطه ی فوق نشان می دهد که اگر c d log انتخاب شود فرض T (n) dn log n صحیح است بنابراین (I) برقرار است T (n) T ( n )+T ( ۲n حال (II) را اثبات می کنیم فرض کنید c ضریب ثابتی باشد که به ازای ا ن رابطه ی )+cn برای n های به اندازه ی کافی بزرگ برقرار است فرض استقرا را به صورت زیر در نظر می گیریم: ضریب ثابت d وجود دارد به طوری که برای n های به اندازه کافی بزرگ T (n) dn log n T (n) dn log n T (n) T ( n ) + T ( ۲n ) + cn d n log n + d ۲n log ۲n + cn = d n log n d n log + d ۲n log n d ۲n = dn log n dn log + cn log + cn رابطه ی فوق نشان می دهد که اگر c d log انتخاب شود فرض T (n) dn log n صحیح است بنابراین (II) هم برقرار است Θ(n log n) صدق می کند T ( n ) + T ( ۲n در نتیجه کران دوطرفه مجانبی تابع (n) T که در رابطه Θ(n) + ) است قضیه اصلی برای حل روابط بازگشتی at ( n b است که در ا ن ۱ a و > ۱ b اعداد قضیه اصلی روشی برای حل روابط بازگشتی به فرم f(n) + ) ثابت هستند و f(n) یک تابع مثبت دارای مجانب است رابطه فوق زمان اجرای یک الگوریتم با اندازه n را که به a زیر مسي له با اندازه n/b تقسیم شده است نشان می دهد در این رابطه a زیر مسي له به طور بازگشتی حل می شوند و f(n) نیز زمان لازم را برای تقسیم و ادغام مسي له نشان می دهد ۵-۴
at ( n b تعریف شده است که در ا ن f(n) تابعی قضیه ۱ (قضیه اصلی) رابطه بازگشتی (n) T بصورت )+f(n) مثبت می باشد و اعداد ۱ a و > ۱ b ثابت هستند: اگر برای > ۰ ϵ ثابت f(n) از ) a ϵ O(n log b باشد ا نگاه (n) T از ) a Θ(n log b خواهدبود اگر ) a f(n) = Θ(n log b باشد ا نگاه n) Θ(n log b a log خواهد بود اگر برای > ۰ ϵ ثابت ) a+ϵ f(n) = Ω(n log b باشد و همچنین اگر برای n های به اندازه کافی بزرگ و < ۱ c ثابت رابطه cf(n) af(n/b) < برقرار باشد (که شرط انتظام ۱ نامیده می شود) ا نگاه Θ(f(n)) خواهد بود در هر کدام از این سه حالت ما تابع f(n) را با n log b a مقایسه می کنیم و تابع بزرگ تر جواب رابطه ی بازگشتی را مشخص می کند البته برای حالت تساوی باید ضریب log n را لحاظ کرد برای استفاده از قضیه ی اصلی کافیست مشخص کنیم که رابطه ی داده شده کدام یکی از حالت قضیه است سپس جواب را محاسبه نماییم T ( n بنویسیم رفتار مجانبی b ( T و یا ) n b نکته ممکن است n/b یک عدد اعشاری باشد اگر به جای (n/b) T ) رابطه بازگشتی تغییر نمی کند ولی برای راحتی در رابطه های بازگشتی الگوریتم های تقسیم و حل از نوشتن کف و سقف صرف نظر می شود مثال ۵ یک حالت خاص و کاربردی قضیه ی اصلی برای حل معادله بازگشتی at ( n b ) + nd است در این صورت سح حالت مذکور به صورت زیر است: ۱) d < log b a a > b d Θ(n log b a ) ۲) d = log b a a = b d Θ(n log b a log n) ) d > log b a a < b d Θ(n d ) مثال ۶ با استفاده از قضیه ی اصلی کران مجانبی توابع زیر را محاسبه کنید ۵T ( n ۲ ) + Θ(n۲ ) ۱ حالت > ۲ ۲ ۱ ۵ Θ(n log ۲ ۵ ) ۲۷T ( n ) + Θ(n ) ۲ حالت = ۲ ۲۷ Θ(n log n) ۵T ( n ۲ ) + Θ(n ) حالت < ۲ ۵ Θ(n ) نکته ۴ ممکن است بعضی از روابط بازگشتی باشند که در شرایط این قضیه صدق نکنند و برای محاسبه ی ا ن ها مجبور باشیم از روش های دیگر استفاده کنیم ۱ رابطه ۲T (۲/n) + n log n را در نظر بگیرید با توجه به نماد گذاری های قضیه اصلی بوضوح برای هر > ۰ ϵ دلخواه ) ϵ ۱ f(n) O(n و Θ(n) f(n) است بنابراین به اشتباه ممکن است رابطه بازگشتی به عنوان حالت سوم قضیه اصلی در نظر گرفته شود ولی دقت کنید که برای هیچ > ۰ ϵ تساوی ) ϵ log n = Ω(n برقرار نیست ۱ regularity condition ۵-۵
۲۷T ( n n نیز قضیه اصلی کاربردی ندارد زیرا باید n log ۲۷ را با ) + Θ( log n ۲ برای رابطه بازگشتی ) f(n) = Θ( n نیز از log n ) نیست تابع O(log (n از nϵ مثبتی ϵ مقایسه کرد از ا نجایی که برای هیچ )Ω n log n ) ) ϵ O(n نخواهد بود در مورد رابطه بازگشتی (n T (۲/n) + ۲)n cos هم نمی توان قضیه اصلی را به کار برد زیرا با ا نکه برای هر ۱ ϵ تابع ) ϵ+۰ f(n) = Ω(n است ولی شرط انتظام برای f(n) برقرار نیست ۴ دنباله بازگشتی و محاسبه بازگشتی در الگوریتم های بازگشتی و به خصوص هنگام محاسبه ی حاصل یک عبارت به صورت بازگشتی (مانند سری فیبوناچی) معمولا پیچیدگی راه حل مستقیم و بازگشتی باهم متفاوت است الگوریتم های بازگشتی علی رغم اینکه گاهی راحت تر پیاده سازی می شوند اغلب کندترند زیرا در ا ن ها الگوریتم به ازای یک مقدار بعضا چندبار تکرار می شود مثلا در محاسبه ی عدد پنجم فیبوناچی به روش بازگشتی بار عدد دوم فیبوناچی و ۲ بار عدد سوم این سری محاسبه می گردند ولی در راه حل مستقیم ا ن هر اندیس این سری یک بار حساب می شود ۱۴ راه حل بازگشتی سری فیبوناچی Algorithm 1 Algorithm: RecursiveFibonacci function Fib(n) [assumes n 1] if n 3 then x Fib(n 1) y Fib(n 2) return x + y else return 1 +۱ ۵ ))Θ است زیرا حالات تکراری در ا ن محسابه می شوند به همین دلیل باید کد ۲ پیچیدگی زمانی این روش ) n ) این برنامه را به طور مستقیم پیاده سازی کنیم و از روش بازگشتی استفاده نکنیم ۲۴ راه حل مستقیم سری فیبوناچی Algorithm 2 Algorithm: Fibonacci function Fib(n) F [0] = F [1] = 1 for i = 2 to n do F [i] = F [i 1] + F [i 2] return F [n] ۵-۶
پیچیدگی زمانی این روش Θ(n) است زیرا برای محاسبه ی nامین عدد فیبوناچی اعداد قبل از ا ن فقط یک بار محاسبه می شوند و کاری تکراری انجام نمی دهیم ۵-۷