1 / 55

Algorithmic Complexity

Algorithmic Complexity. Algorithmic Complexity: Two Key Metrics. پيچيدگي مکاني: حداکثر مقدار حافظه مورد نياز براي انجام محاسبات مورد نظر و ارتباط آن با اندازه ورودي. پيچيدگي زماني: حداکثر تعداد محاسبات مورد نياز براي انجام محاسبات مورد نظر و ارتباط آن با اندازه ورودي.

Download Presentation

Algorithmic Complexity

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Algorithmic Complexity

  2. Algorithmic Complexity:Two Key Metrics • پيچيدگي مکاني: • حداکثر مقدار حافظه مورد نياز براي انجام محاسبات مورد نظر و ارتباط آن با اندازه ورودي. • پيچيدگي زماني: • حداکثر تعداد محاسبات مورد نياز براي انجام محاسبات مورد نظر و ارتباط آن با اندازه ورودي. • ما ابتدا اين پارامترها را در مورد بازگشت بررسي مي کنيم.

  3. Determining Time Efficiency • راه حلها: • تجربي: اضافه کردن شمارنده ها جهت اندازه گيري تعداد عمليات انجام شده • تئوري: استفاده از مدل رياضي براي مدل کردن توابع محاسباتي مورد نياز • بازگشت؟ بعضي مسائل از روابط رياضي مناسب بهره مي برند – لذا از اين مسائل شروع مي کنيم.

  4. Recursion Time Efficiency: Recurrence Relations • محاسبات مورد نياز: سه موضوع • مقدار کار مورد نياز در تکرار فعلي • هزينه مورد نياز براي آماده کردن داده ها قبل از استفاده از بازگشت و بعد از آن • تعداد زير مسائل بازگشتي • بازگشت خطي يا بازگشت درختي • اندازه ورودي زير مسائل بازگشتي • زير مسئله بازگشتي چقدر کوچکتر است.

  5. Recursive Binary Search • محاسبات مورد نياز در جستجوي بازگشتي • مقدار کار مورد نياز در تکرار فعلي • 1 مقايسه (مقايسه ورودي با عنصر وسطي) • 1 تنظيم ( تغيير پارامترهاي چپ يا راست) • تعداد زير مسائل بازگشتي • 1 زير مسئله (سمت چپ يا راست آرايه) • اندازه ورودي زير مسائل بازگشتي • سايز زير مسئله نصف مسئله اصلي است.

  6. Recurrence Relation • رابطه بازگشتي عمومي: T(n) = aT(n/b) + cnk a = تعداد زير مسائل b = 1/اندازه زير مسائل f(n) = کار تکرار فعلي = constant * nk

  7. Recurrence: Master Theorem T(n) = aT(n/b) + f (n) where f (n) ≈nk • a < bk T(n) ~ nk • a = bk T(n) ~ nk lg n • a > bk T(n) ~ nlog b a

  8. Recurrence: Master Theorem T1(n) = 7 T1(n/7)+n a = 7, b = 7, k = 1 a ? bk 7 == 7 • nklgn=> n lgn T2(n) = 7 T2(n/2)+n2 a = 7, b = 2, k = 2 a ? bk 7 > 22 => nlogba => nlog27 => n2.81 T3(n) = 7 T3(n/3)+n2 a = 7, b = 3, k = 2 a ? bk 7 < 32 => nk => n2

  9. Recursive Binary Search T(n) = aT(n/b) + f(n) a = number of sub problems = 1 b = 1/size of subproblems = 1/(1/2) => 2 f(n) = current iteration work = 2n0 so k = 0 Compare a to bk:1 vs 2^0 = 1 vs 1 If they are equal, computational cost is: nk log n = 1 * log n => log n [Formula can be looked up for >, <, and ==]

  10. Space Complexity • چرا ما به پيچيدگي مکاني علاقه منديم؟ • اکثر مردم نگران پيچيدگي زماني هستند. • به طور عمومي، مسائلي که داراي پيچيدگي زماني زيادي هستند را مي شود با صبر کردن بيشتر حل نمود. ( اگر چه ممکن است به عمر ما کفاف ندهد!) • اما ممکن است نتوانيم مسائلي که داراي پيچيدگي مکاني زيادي هستند را اجرا کنيم. در اينجا، محدوديت ما کمبود حافظه است و محدوديت حافظه از محدوديت زماني مشهود تر است.

  11. Space Complexity • به طور کلي داراي دو جزء است: • جزء ثابت: C • مقدار کد برنامه • ثابتها • متغيير هاي ساده • جزء موردي: Sp • متغيير هايي که سايز آنها به مسئله ربط دارد. • فضاي پشته مورد نياز • S(P) = C + Sp • معمولا از C در مقابل Spصرفنظر مي کنيم.

  12. Space Complexity float abc(float a, float b, float c) { return a + b + b*c + (a+b-c) / (a+b) + 4.0; } • فرض کنيد فضاي مورد نياز براي هر float برابر 1 کلمه باشد. • بدون توجه به مقادير a، b و c فضاي مورد نياز براي اجراي اين برنامه ثابت است. • لذا پيچيدگي مکاني اين تابع مستقل از ورودي است يا Sabc = 0

  13. Space Complexity float sum(float *a, const int n) { float s = 0; for (int i =0; i < n; i++) s += a[i]; return s; } • اين مسئله عناصر يک آرايه را با هم جمع مي کند. • سايز ورودي برابر با سايز آرايه است. • به 4 کلمه براي a, n, s, i نياز داريم. • دوباره فضاي مورد نياز براي اجراي اين برنامه مستقل از ورودي و ثابت است. لذا Ssum = 0

  14. Space Complexity float rsum(float *a, const int n) { if (n <= 0) return 0; else return (rsum(a, n-1) + a[n-1]); } • اين مسئله عناصر يک آرايه را با هم جمع مي کند. • سايز ورودي برابر با سايز آرايه است. • به 4 کلمه براي a, n, a[n-1] و آدرس بازگشت نياز داريم. • هر بار اجراي بازگشت به چهار کلمه نياز دارد. • عمق بازگشت برابر n+1 است. • فضاي مورد نياز براي اجراي اين برنامه وابسته به ورودي است و Srsum = 4(n+1)

  15. Time Complexity • زمان کامپايل + زمان اجرا T(P)= • زمان کامپايل : • وابسته به ورودي نيست. • در مقايسه با زمان اجرا قابل صرفنظر کردن است. • زمان اجرا: • به دقت قابل اندازه گيري نيست. • وابسته به سخت افزار، سيستم عامل ، بار کامپيوتر و ... است. • به صورت قدمهاي اجرايي مورد نياز تخمين زده مي شود.

  16. Time Complexity in C++ Context • توضيحات: • اجرا نمي شوند. • Step count = 0 • اعلانها (int b; ): • يا اجرا نمي شوند • يا در قسمت سربار صدا زدن توابع مورد ملاحظه قرار مي گيرند. • Step count = 0

  17. C++ Time Complexity • عبارات (for example: a == true) : • معمولا step count = 1 • اگر عبارت شامل صدا زدن يک تابع باشد. هزينه صدا زدن تابع نيز بايد لحاظ گردد. • انتساب : <variable> = <expression> • معمولا تعداد قدمها معادل عبارت سمت راست است. • اما اگر سايز متغيير سمت راست وابسته به ورودي (يا متغيير) باشد: • step count = size of variable + expression step count • مثال:در a = (2+b); اگر a و b هر دو ليست باشند: • هزینه = هز ینه ی ارزیابی عبارت (2+b) به علاوه ی هزینه ی کپی کردن لیست b در لیست a.

  18. C++ Time Complexity • تکرار: • مي خواهيم عناصر کنترلي خود حلقه را بررسي کنيم نه دستورات درون حلقه را • While <expr> do • Do… while <expr> • For (<init_stmt>; <expr1>; <expr2>) • در while, doهر تکرار به اندازه <expr>هزينه دارد. • در for • اگر دستورات <init_stmt>, <expr1>, <expr2> به سايز ورودي وابسته نباشند هزينه هر تکرار را برابر 1 در نظر مي گيريم. • لذا کل هزينه for برابر تعداد تکرارها بعلاوه 1 (براي آخرين چک کردن ناموفق حلقه) است. • در غير اين صورت: • اولین اجرای حلقه: <init_stmt> steps + <expr1> steps • بقیه ی اجراهای حلقه: <expr1> steps + <expr2> steps

  19. C++ Time Complexity • دستور switch : • switch <expr> { case cond1: <statement1> case cond2: <statement2> default: <statement>} • عبارت مورد ارزیابی: : <expr> steps • شرایط:هزينه چک کردن شرط فعلي بعلاوه تمام شروط قبلي • دستورIf/else : • If (<expr>) <statements1>; else <statements2> • <expr> = true: <expr> +<statements1> cost • <expr> = false: <expr>+ <statements2> cost

  20. C++ Time Complexity • صدا زدن توابع: • معمولا step count = 1 • فرستادن آرگومانها با مقدار: اگر سايز متغيير وابسته به ورودي باشد هزينه کپي کردن آرگومانها را لحاظ کنيد. • اگر از روش بازگشتي استفاده مي کنيد، تمام متغييرهاي محلي وابسته به سايز را شناسايي و هزينه آنها را در نظر بگيريد زيرا بايد هنگام صدا زدن بازگشت توليد گردند.

  21. C++ Time Complexity • مديريت حافظه: new/delete • معمولا step count = 1 • اگر شي ايجاد شده جزء سازنده و مخرب داشته باشد، هزينه اين جزء ها بايد همانند توابع حساب شود. • دستورات شرطي:continue/ break/ goto/ return / return<expr> : • براي continue/break/goto/return برابر 1 • براي return <expr> برابر هزينه <expr>

  22. Measuring Complexity • راه حل اول: • برنامه را طوري تعيير دهيد که شامل عبارات مربوط step count گردد. • يک متغيير عمومي به اسم countتعريف کنيد. • هرجايي که يک عبارت اجرا مي شود، count را به طور مناسب افزايش دهيد.

  23. Measuring Complexity float sum(float *a, const int n) { float s = 0; for (int i =0; i < n; i++) s += a[i]; return s; } float sum(float *a, const int n) { float s = 0; count++; // assignment for (int i =0; i < n; i++) { count++; s += a[i]; count++;} // 1 for for , 1 for += count ++; // last time checking for return s; count ++; // return statement }

  24. Measuring Complexity • هر چيزي غير از عبارات مربوط به count را حذف کنيد. float sum(float *a, const int n) { count++; // assignment for (int i =0; i < n; i++) { count = count + 2;} // 1 for for, 1 for += // last time checking for and return statement count = count + 2; }

  25. Measuring Complexity: • عبارات مربوط به count را با هم جمع کنيد. 1 at beginning + (N iterations of loop) * (2 within a loop) + 2 at end => 2N + 3

  26. Measuring Complexity float rsum(float *a, int n) { if (n <= 0) return 0; else return (rsum(a, n-1) + a[n-1]); } float rsum(float *a, int n) { count ++; // if conditional if (n <= 0) { count++; return 0;} // return else { count++; return (rsum(a,n-1) + a[n-1]); // return statement } با بازگشت چکار کنيم؟

  27. Measuring Complexity: Recursion float rsum(float *a, cont int n) { count ++; // if conditional if (n <= 0) { count++;} // return else { count++; return (rsum(a,n-1) + a[n-1]); } If (n <= 0) count = 2 Otherwise count = 2 + count(n-1)

  28. Measuring Complexity: Recursion • 2 + count(n-1) رابطه بازگشتي => 2+ count(n-1) = 2 + 2 + count(n-2) = 2 + 2 + 2 + count(n – 3) … = 2 * n + count(0) => 2n + 2

  29. Time Complexity • جمع تکراري: 2n + 3 • جمع بازگشتي: 2n + 2 • آيا جمع بازگشتي از جمع تکراري سريع تر است؟ • ضرورتا نه – هر قدم جمع بازگشتي ممکن است خيلي از قدمهاي جمع تکراري هزينه بر تر باشد. • اما ايرادي ندارد – چون ما به تعداد قدمها در مقايسه با سايز ورودي علاقه داريم که در اين مورد مثل هم هستند.

  30. Time Complexity • 2n + 2 زمان اجرا خطي است • يعني اگر ورودي 10 برابر شود، زمان اجرا نيز 10 برابر مي شود. • اگر ورودي 10000 برابر شود، زمان اجرا نيز 10000 برابر خواهد شد. • در رابطه Xn + C هميشه Xn قسمت ثابت را تحت تاثير قرار مي دهد و ما از C صرفنظر مي کنيم.

  31. Time Complexity • جمع ماتريسها: void add(matrix a, matrix b, matrix c, int m, int n) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { c[i][j] = a[i][j] + b[i][j] } } }

  32. Time Complexity void add(matrix a, matrix b, matrix c, int m, int n) { for (int i = 0; i < m; i++) { count++; // for loop for (int j = 0; j < n; j++) { count++; // for loop c[i][j] = a[i][j] + b[i][j] count++; // assignment } count ++; // last time through for loop on j } count++; // last time through for loop on i }

  33. Time Complexity void add(matrix a, matrix b, matrix c, int m, int n) { for (int i = 0; i < m; i++) { count = count + 2; // for loop start, last time on j [case 1] for (int j = 0; j < n; j++) { count = count + 2; } // for loop start, assignment [case 2] } } count++; // last time through for loop on i [case 3] } => 2m [case 1]+ 2mn [case 2] + 1 [case 3]

  34. Time Complexity جمع ماتريسها: 2mn + 2m + 1 عبارت فوق چه چيزي را به ما ياد مي دهد؟ اگر m>>n است جاي حلقه ها را عوض کنيد. تا بجاي 2m از 2n عمل استفاده کنيد.

  35. Measuring Complexity • راه حل اول: جمع count ها • راه حل دوم: متد جدولي • قدمهاي مورد نياز براي اجراي هر دستور • فرکانس دستور

  36. Tabular Method for Complexity float sum(float *a, const int n) 1 { 2 float s = 0; • for (int i =0; i < n; i++) • s += a[i]; 5 return s; 6} • Line S/E Freq Total • 0 1 0 • 1 1 1 • 1 n+1 n+1 • 4 1 n n • 5 1 1 1 • 6 0 1 0 • Total: 2n+3

  37. Tabular Method for complexity float rsum(float *a, const int n) 1 { 2 if (n <= 0) return 0; 3 else return (rsum(a, n-1) + a[n-1]); 4} • Line S/E Freq Total • =0 >0 =0 >0 • 0 1 1 0 0 • 1 1 1 1 1 • 2b 1 1 0 1 0 • 3 1 + tn-1 0 1 0 1+tn-1 • 4 0 1 1 0 0 • Total: n = 0 => 2 • n > 0 => 2+ tn-1

  38. Tabular Method for Complexity void add(matrix a, matrix b, matrix c, int m, int n) { 1 for (int i = 0; i < m; i++) { 2 for (int j = 0; j < n; j++) { 3 c[i][j] = a[i][j] + b[i][j] } } } • Line S/E Freq Total • 1 m+1 m+1 • 1 m(n+1) mn+m • 1 mn mn • Total: 2mn + 2m + 1

  39. Time Complexity • بهترين حالت: کمترين تعداد قدمهاي اجرايي مورد نياز براي پارامترهاي داده شده • بدترين حالت:بيشترين تعداد قدمهاي اجرايي مورد نياز براي پارامترهاي داده شده • حالت ميانگين: تعداد متوسط قدمهاي اجرايي مورد نياز براي پارامترهاي داده شده

  40. Time Complexity T(A) = c1n2 + c2n T(B) = c3n فرض کنيد: c1 = 5, c2 = 3, c3 = 100 چه موقع هزينه الگوريتم A< هزينه الگوريتم B 5n2 + 3n > 100n => 5n2 > 97n => 5n > 97 => n > 19.4 19.4 is the breakpoint

  41. Big “Oh” Notation • روابط بين توابع را تعريف مي کنيم. • مي گوييم F(n) از درجه O(g(n)) است اگر: • وجود داشته باشد c و n0 > 0 بطوري که f(n) <= cg(n) براي تمام n >= n0 • 3n + 2 از درجه O(n)است زيرا: 3n+2 <= 4n براي تمام n >= 2 (c = 4, n0 = 2)

  42. Big “Oh” notation • 10n2 + 4n + 2 از درجه O(n2)استزيرا : 10n2 + 4n + 2 < 11n2 براي تمام n >= 5 (c = 11, n0 = 5) • 10n2 + 4n + 2 از درجه O(n) نيست زيرا: وجود ندارد c و n0 که: 10n2 + 4n + 2 is < cn براي همه n >= n0

  43. Big “Oh” notation C = 100? 10n2+4n+2 < 100n 10n2 < 96n – 2 ~ 10n2 < 95n = 10n < 95 => n < 9.5 فقط براي n هاي بين 1 و 10 برقرار است. • C = 1000? 10n2+4n+2 < 1000n 10n2 < 996n – 2 ~ 10n2 < 995n = 10n < 995 => n < 99.5 فقط براي n هاي بين 1 و 100 برقرار است. نمي توانيم n0 پيدا کنيم که رابطه n >= n0هميشه برقرار باشد.

  44. Big “Oh” Notation • رابطه f(n) = O(g(n)) يک حد بالا روي مقدار f(n) قرار مي دهد که لزوما بهترين حد بالا نيست. • ما دنبال کوچکترين حد بالا هستيم. F(n) = 4n + 2 از درجه O(n) و O(n2) و O(n3).. است اما ازO(n) استفاده مي کنيم.

  45. Big “Oh” notation • O(1) = ثابت • O(n) = خطي • O(n2) = مربعي • O(n3) = مکعبي • O(log n) = لگاريتمي • O(2n) = نمايي • الگوريتمهاي با درجه پيچيدگي O(n log n)نيز مرسوم هستند.

  46. Big “Oh” Notation • اگر تابعي داراي چند جمله باشد جمله بزرگتر لحاظ مي گردد. • f(n) = 4n5 + 6n3 + 2n2 + n + 8 => O(n5)

  47. Omega Notation • f(n) = Ω(g(n)) اگر: • وجود داشته باشد c و n0 > 0 بطوري که f(n) >= cg(n) براي تمام n >= n0 • 3n + 2 = Ω(n) چون: 3n + 2 >= 3n براي n >= 1 (c = 3, n = 1) • 10n2 + 4n + 2 = Ω(n2) چون: 10n2 + 4n + 2 >= n2براي n >= 1 (c = 1, n = 1) همچنين Ω(n)و Ω(1) نيز هست.

  48. Omega Notation • رابطه f(n) = Ω(g(n)) يک حد پايين روي مقدار f(n) قرار مي دهد که لزوما بهترين حد پايين ممکن نيست. • ما دنبال بزرگترين حد پايين هستيم.

  49. Theta Notation • f(n) = Θ(g(n)) اگر: • وجود داشته باشد c1، c2و n0 > 0 بطوري که c1g(n) <= f(n) <= c2g(n) براي تمام n >= n0 • 3n + 2 از مرتبه Θ(n) است زيرا: 3n + 2 <= 4n براي تمام n >= 2 O(n) 3n + 2 >= 3n براي تمام n >= 2 Ω(n) • Θ(g(n)) يک حد بالا و پايين سفت وسخت روي f(n)مي گذارد.

  50. cg(n) f(n) is O(g(n)) f(n) is (g(n)) f(n) f(n) cg(n) N N c1g(n) f(n) is (g(n)) f(n) c2g(n) N Graphs • دقت کنيد که: • در شروع (n < N) هر اتفاقي که مي افتد مهم نيست. • در شکل سوم، c1g(n) و c2g(n) مثل هم هستند. (چرا؟) http://www.cis.upenn.edu/~matuszek/cit594-2004/Lectures/49-analysis-2.ppt

More Related