Download presentation
Presentation is loading. Please wait.
1
ניתוח זמן ריצה (על קצה המזלג)
קרן כליף
2
ביחידה זו נלמד: מהו ניתוח זמן ריצה ניתוחי זמן ריצה בסיסיים מוטיבציה
הגדרה ניתוחי זמן ריצה בסיסיים קבוע לינארי ריבועי לוגריתמי 2 © Keren Kalif
3
משפחות של פונקציות 3 © Keren Kalif
4
ניתוח זמן ריצה - מוטיבציה
כאשר אנחנו מריצים את התוכניות שלנו, נראה לנו שהן רצות מהר מאוד, ואנחנו לא עוצרים לחשוב כמה עבודה באמת מבוצעת ע"י המחשב ב"עולם האמיתי" לעיתים יש חשיבות לכל מיקרו שנייה שהתוכנית רצה נרצה לדעת להעריך האם התוכנית שכתבנו יעילה, כלומר כמה פעולות המחשב בערך מבצע נרצה לבחון האם יש דרך לכתוב את התוכנית בצורה יעילה יותר 4 © Keren Kalif
5
זמן ריצה - הגדרה זמן ריצה של תוכנית הוא סדר גודל של מספר הפעולות שהתוכנית מבצעת ביחס לגודל הקלט סדר גודל אינו מספר מדויק אלא הערכה של מספר הפעולות המבוצעות בתוכנית 5 © Keren Kalif
6
ניתוח זמן ריצה – זמן ריצה קבוע לעומת זמן ריצה תלוי משתנה
ניתוח זמן ריצה – זמן ריצה קבוע לעומת זמן ריצה תלוי משתנה כמה זמן לוקח למחשב לחשב את: x = x + y; התשובה תלויה במהירות המחשב, אך הנחה סבירה היא שפעולה זו על אותו מחשב בזמנים שונים תיקח זמן זהה for (i=1 ; i <= n ; i++) x += i; במקרה זה זמן הריצה תלוי בערכו של n שאינו ידוע מראש, ולכן צריך לקחתו בחשבון בזמן הניתוח התיאורטי, שכן יהיה הבדל משמעותי אם n=10 או n=100,000,000... 6 © Keren Kalif
7
ניתוח זמן ריצה – זמן ריצה קבוע O(1)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int num; System.out.println(“Please enter a number: “); num = s.nextInt(); System.out.println(“The number is ” + num); } בתוכנית זו מספר הפעולות תמיד יהיה זהה, לא משנה מה ערכו של num 7 © Keren Kalif
8
ניתוח זמן ריצה – זמן ריצה קבוע O(1)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int num1, num2, small, big; System.out.print(“Please enter 2 numbers: “); num1 = s.nextInt(); num2 = s.nextInt(); small = num1; big = num2; if (small > big) { small = num2; big = num1; } עדיין במקרה זה מספר הפעולות קבוע בכל הרצה, אפילו אם ערכם של num1 ו- num2 מאוד גדול, ולכן זמן הריצה של תוכנית זו הוא O(1) מציאת הערך הגדול והערך הקטן: בעת חישוב ניתוח זמן ריצה נסתכל תמיד על המקרה הגרוע ביותר, כלומר המקרה בו יבוצעו הכי הרבה פעולות ולכן בדוגמא זו נניח כי ה- if מבוצע 8 © Keren Kalif
9
ניתוח זמן ריצה – תלות בגודל הקלט (לינארי)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int i, num, fact=1; System.out.print("Enter a number: “); num = s.nextInt(); for (i=1 ; i <= num ; i++) fact *= i; System.out.printf(“%d != %d \n”, num, fact); } בתוכנית זו יש מספר פעולות קבועות שיסומנו ב- O(1), ולולאה שרצה num פעמים ומבצעת מספר פעולות קבוע בכל איטרציה: O(main) = O(1) + num*O(1) כאשר num מאוד גדול זמן הריצה הקבוע זניח ולכן נאמר כי: O(main) = O(1) + O(num) = O(num) חישוב עצרת: מספר הפעולות בתוכנית זו תלוי בערכו של num: התוכנית תבצע תמיד את הפעולות הקבועות של קבלת הקלט והדפסת התוצאה, אבל מספר הפעמים שהלולאה תתבצע תלוי בקלט. = O(1) + O(num*1) = O(1) + O(num) 9 © Keren Kalif
10
ניתוח זמן ריצה – תלות בגודל הקלט (לינארי) (2)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int num, i; System.out.print("Please enter a number: “); num = s.nextInt(); System.out.println("All even numbers from 1 to “ + num + “:”); for (i=0 ; i < num ; i+=2 ) System.out.print(i + “ “); System.out.println(); } בתוכנית זו יש מספר פעולות קבועות שיסומנו ב- O(1), ולולאה שרצה num/2 פעמים ומבצעת מספר פעולות קבוע בכל איטרציה : O(main) = O(1) + (num/2)*O(1) כאשר num מאוד גדול זמן הריצה הקבוע זניח ולכן נאמר כי: O(main) = O(num/2) = O(num) הדפסת המספרים הזוגיים עד מספר מסוים: = O(1) + O((num/2)*1) = O(1) + O(num/2) =O (num/2) 10 © Keren Kalif
11
ניתוח זמן ריצה – תלות בגודל הקלט (ריבועי)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int width, height; System.out.print("Enter a rectangle's width and height: “); width = s.nextInt(); height = s.nextInt(); for (int i=1 ; i <= height ; i++) { for (int j=1 ; j <= width ; j++) System.out.print(“*”); System.out.println(); } סה"כ זמן הריצה של התוכנית: O(height *width) הדפסת מלבן: O(1) heigth*O(width) = O(height*width) width*O(1) = O(width) אם width == height == n סדר גודל זמן הריצה היה O(n2) 11 © Keren Kalif
12
ניתוח זמן ריצה – תלות בגודל הקלט (ריבועי)
public static void main(String[] args) { Scanner s = new Scanner(System.in); int num; System.out.print(“Please enter the base of the triangle: “); num = s.nextInt(); for (int i=1 ; i <= num ; i++) { for (int j=1 ; j <= i ; j++) System.out.print(“*”); System.out.println(); } סדר גודל זמן הריצה של התוכנית הוא מספר הפעולות בסה"כ של הלולאה הראשית: 1+2+…+num, וזוהי סדרה חשבונית שסכומה: O(main) = O(num*(num+1)/2) הדפסת משולש: בדוגמא זו מספר הפעולות בלולאה הפנימית שונה בכל איטרציה, ולכן נבדוק ביתר קפידה כמה פעולות באמת מתבצעות: באיטרציה הראשונה של הלולאה הראשית הלולאה הפנימית תרוץ פעם אחת באיטרציה השניה של הלולאה הראשית הלולאה הפנימית תרוץ פעמים וכו' = O((num2+num)/2) = O(num2 + num) = O(num2) 12 © Keren Kalif
13
ניתוח זמן ריצה – תלות בגודל הקלט (לוגריתמי)
הדפסת חזקה: public static void main(String[] args) { Scanner s = new Scanner(System.in); int num, i; System.out.print("Please enter a number: “); num = s.nextInt(); System.out.println("All 2 powers till “ + num + “:”); for (int i=1 ; i <= num ; i*=2) System.out.print(i + “ “); System.out.println(); { מספר הפעולות בתוכנית זו הוא O(1) עבור הפעולות הקבועות ועוד O(1) פעולות בכל איטרציה של הלולאה, אך מהו מספר האיטרציות של הלולאה? 13 © Keren Kalif
14
ניתוח זמן ריצה – תלות בגודל הקלט (לוגריתמי)
למשל עבור n=128: מספר האיטרציות היא כמספר הפעמים שנכפיל ב- 2 עד שנגיע ל- n: 1248163264128 אפשר לשאול כמה פעמים הכפלנו את 2 בעצמו עד קבלת 128: 2? = 128 וזוהי בדיוק פעולת ה- log: log2128 מספר הפעולות עבור לולאה שקצב ההתקדמות שלה הוא כפל/חילוק הוא log בבסיס ערך הכפל/חילוק 14 © Keren Kalif
15
ניתוח זמן ריצה לוגריתמי
ככל שבסיס הלוג יותר גדול מספר הפעולות קטן (יותר יעיל) for (int i=1 ; i <= 240 ; i*=2) ….. מספר האיטרציות: 1 248163264128256 log2256 = 8 for (int i=1 ; i <= 240 ; i*=3) מספר האיטרציות: 13981243 log3243 = 5 15 © Keren Kalif
16
מאחר ולא ידוע לנו היחס בין n ל-m, נאמר שסדר הגודל הוא O(n+m)
חיבור סדרי גודל public static void main(String[] args) { Scanner s = new Scanner(System.in); int i, j, n, m; System.out.print(“Enter 2 numbers: ”); n = s.nextInt(); m = nextInt(); for (int i=1 ; i <= n ; i++) System.out.print(i + “ “); System.out.println(); for (int i=1 ; i <= m ; i++) } מאחר ולא ידוע לנו היחס בין n ל-m, נאמר שסדר הגודל הוא O(n+m) 16 © Keren Kalif
17
השוואת סדרי גודל כאשר כותבים תוכנית נשאף שזמן הריצה יהיה נמוך ככל שניתן נזכור כי: O(1) < O(log3n) < O(log2n) < O(n) < O(n2) < O(n3) 17 © Keren Kalif
18
ביחידה זו למדנו: מהו ניתוח זמן ריצה ניתוחי זמן ריצה בסיסיים מוטיבציה
הגדרה ניתוחי זמן ריצה בסיסיים קבוע לינארי ריבועי לוגריתמי 18 © Keren Kalif
19
תרגיל 1: מהו זמן הריצה של התוכניות הבאות?
for (int i=0 ; i <= n ; i+=2) System.out.print(i + " "); public static void main() { Scanner s = new Scanner(System.in); int n; System.out.print("Enter a number: “); n = s.nextInt(); System.out.println("All even from 0 till " + n); } O(n) … for (int i=0 ; i <= n ; i++){ if (i%2 == 0) System.out.print(i + " "); } O(n) ובכל זאת, למרות שהיעילות זהה, נעדיף את הפתרון העליון 19 © Keren Kalif
20
תרגיל 2: מהו זמן הריצה של התוכניות הבאות?
for (int i=1 ; i <= n ; i*=2) System.out.print(i + " "); public static void main() { Scanner s = new Scanner(System.in); int n; System.out.print("Enter a number: “); n = s.nextInt(); System.out.println("All 2 powers from 1 till " + n); } O(log2(n)) … for (int i=1 ; i <= n ; i++) { // check if i is a 2 power int j; for (j=1 ; j < i ; j*=2); if (j == i) System.out.print(i + " "); } O(n*log2(n)) 20 © Keren Kalif
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.