140 likes | 345 Views
מבוא למחשב בשפת Matlab. הרצאה 14 : חזרה הרצאה 12:. נכתב על-ידי שלמה מורן. שאלות חזרה. שאלה 1 (25 נק '): 1. (5 נק ') תת מטריצה רציפה של מטריצה M היא תת מטריצה המורכבת מרצף של שורות ועמודות של M . כתבו פונקציה g המקבלת כפרמטרים מטריצה M וארבעה אינדקסים:
E N D
מבוא למחשב בשפת Matlab הרצאה 14: חזרה הרצאה 12: נכתב על-ידי שלמה מורן
שאלות חזרה שאלה 1 (25 נק'): 1. (5 נק') תת מטריצה רציפה של מטריצה M היא תת מטריצה המורכבת מרצף של שורות ועמודות של M. כתבו פונקציה g המקבלת כפרמטרים מטריצה M וארבעה אינדקסים: fromRow, toRow, fromColumn, toColumn. על הפונקציה להחזיר תת-מטריצה רציפה של M התחומה ע"י אותם אינדקסים. לדוגמא, עבור המטריצה להלן, הקריאה g(M,1,3,2,3) תחזיר את תת-המטריצה (הרציפה) המסומנת במסגרת העבה. function N = g(M, fromRow, toRow, fromColumn, toColumn) N = M(fromRow:toRow,fromColumn:toColumn) תשובה: הרצאה 14
ב. (10 נק') להלן קוד חלקי של פונקציה רקורסיבית f המקבלת כפרמטר מטריצת מספרים, ומחזירה את סכום תת-המטריצה הרציפה המקסימלי האפשרי, כמו בדוגמה להלן. לצורך זה, סכום של תת מטריצה ריקה הוא 0. על הפונקציה f להשתמש בפונקציה g מהסעיף הקודם. עליכם להשלים את הקוד שלהלן. function maxVal = f(M) if isempty(M) ; else [r,c] = size(M); maxVal = max([,, ,, ]); end הרצאה 14
function maxVal = f(M) if isempty(M) maxVal=0 ; else [r,c] = size(M); maxVal = max( [ sum(sum(M)), f(g(M,2,r,1,c)) , f(g(M,1,r,2,c)) , f(g(M,1,r-1,1,c)), f(g(M,1,r,1,c-1))] ); end הרצאה 14
ג. (8 נק') מהו מספר הקריאות הרקורסיביות שהפונקציה תבצע: 1. על מטריצת קלט עם שורה אחת ועמודה אחת? 2. על מטריצת קלט עם שתי שורות ועמודה אחת? הסבירו כיצד הגעתם לתשובתכם. תשובה: • ראשית נשים לב שעל מטריצה ריקה לא מתבצעת אף קריאה רקורסיבית. על מטריצה בגודל 1x1 יתבצעו 4 קריאות רקורסיביות,שכל אחת מהן על מטריצה ריקה. סה"כ 4 קריאות. • על מטריצה בגודל 2x1 יתבצעו 4 קריאות רקורסיביות, מהן 2 על מטריצה בגודל 1x1 ושתיים על מטריצות ריקות. סה"כ 4 + 2*4 + 2*0 = 12 function maxVal = f(M) if isempty(M) maxVal=0 ; else [r,c] = size(M); maxVal = max( [ sum(sum(M)), f(g(M,2,r,1,c)) , f(g(M,1,r,2,c)) , f(g(M,1,r-1,1,c)), f(g(M,1,r,1,c-1))] ); end הרצאה 14
ד. (8 נק'): יהי T(n,m) מספר הקריאות הרקורסיביות שהפונקציה תבצע עבור קלט עם n שורות ו m עמודות: • מהו בסיס הרקורסיה בו מספר הקריאות מחושב באופן ישיר, ומהו מספר זה. תשובה: בסיס הרקורסיה הוא כאשר המערך ריק, כלומר n=0 או m=0. T(0,m) = T(n,0) = 0 2. עבור המקרים האחרים, בטאו את הערך של T(n,m) באמצעות ערכי T(i,j) כך ש i+j < m+n. תשובה: כאשר גם m וגם n גדולים מ0, יש ארבע קריאות רקורסיביות: בשתיים מהן "מוחקים" שורה ובשתיים מהן "מוחקים" עמודה. מתקבל T(n,m) = 4+ 2*T(n-1,m) + 2*T(n,m-1) function maxVal = f(M) if isempty(M) maxVal=0 ; else [r,c] = size(M); maxVal = max( [ sum(sum(M)), f(g(M,2,r,1,c)) , f(g(M,1,r,2,c)) , f(g(M,1,r-1,1,c)), f(g(M,1,r,1,c-1))] ); end הרצאה 14
תשובות לשאלות מתרגיל בית 5 משימה 1(calculate.m) : כתבו פונקציה function r = calculate(n, d, k) n הוא מספר שלם חיובי או 0. d הוא ספרה בודדת השונה מ - 0. k הוא מספר שלם חיובי גדול או שווה 1. הפונקציה מחזירה כתוצאה מספר שלם חיובי אשר מתקבל כאשר מוסיפים ל – n את הספרה d במקום ה – k-י מימין. אם k יותר גדול ממספר הספרות ב – n, אזי יתווספו אפסים בין הספרה השמאלית של n לבין k. דוגמה 1 : עבור calculate ( 4354, 6, 3) נקבל כתוצאה 43654 function r = calculate(n,d,k) %%r is the number esulted by inserting digit d at the k-th location from %%the right in n eg calculate(3245, 9,4) = 39245. right_side = rem(n,10^(k-1)); left_side = floor(n/10^(k-1))*10^k; r = right_side+d*10^(k-1)+left_side; הרצאה 14
משימה 2(sum_zero.m) : כתבו פונקציה function r = sum_zero(a) aהוא מערך שורה ממוין בסדר עולה של מספרים שלמים (משמאל לימין, מהקטן לגדול). הפונקציה בודקת האם במערך ישנם שני איברים שסכומם אפס. אם כן הפונקציה תחזיר 1 לוגי (true). אם לא הפונקציה תחזיר 0 לוגי (false). דוגמה : עבור המערך -34 -15 -15 -2 1 3 9 15 33 37 37 39 42 42 43 התוצאה היא 1 כיוון שקיימים 15, -15 אשר סכומם הוא אפס. דרישות : אסור לשנות את תוכן המערך (גם לא באופן זמני). אסור להשתמש בפונקציות של מטלאב על מערכים, ובפרט לא ב – find ולא ב – repmat או reshape. מותר להשתמש ב – length. מותר להשתמש בלולאה אחת בלבד לכל היותר. function r = sum_zero(a) %%a is a sorted array. r is true iff it contains two elements which sum to %%0. at most one loop n=length(a); r=0; fori=1:n-1 b=[a(i+1:end),a(1:i)]; ifany(a+b==0) r=1;return end end הרצאה 14
משימה 3 : חלק א (check_line.m) : כתבו פונקציה function r = check_line(line) lineהוא מערך שורה לא ריק של מספרים שלמים. הפונקציה בודקת האם ב – line מופיעים כל המספרים השלמים בתחום 1 עד n כאשר n הוא האורך של line . בהתאם מוחזר 1 (true) או 0 (false). function r = check_line(line) %%%%%check if all numbers from 1 to n appear r = true; fori=1:length(line) if ~any(line==i) r=false; return end end הרצאה 14
חלק ב (check_square.m) : כתבו פונקציה function r = check_square(square) squareהוא מערך דו מימדי ריבועי לא ריק של מספרים שלמים. הפונקציה בודקת האם ב – square מופיעים כל המספרים השלמים בתחום 1 עד n כאשר n הוא מספר האיברים ב - square . בהתאם מוחזר 1 (true) או 0 (false). דרישה : הקפידו על תכנות מודולרי. השתמשו בצורה מושכלת בחלק א. function r = check_square(square) %%%%%check if all numbers from 1 to n appear r = check_line(square(:)); הרצאה 14
חלק ג (check_soduko.m) : כתבו פונקציה function r = check_soduko(table, n) table הוא מערך דו מימדי ריבועי לא ריק של מספרים שלמים. הפונקציה בודקת האם table הוא לוח חוקי של משחק n-soduko. בהתאם מוחזר 1 (true) או 0 (false). התנאים הבאים צריכים להתקיים עבור לוח כזה : גודלו של הלוח - n2 x n2 בכל שורה מופיעים כל המספרים בתחום 1 עד n2 (כולל). בכל עמודה מופיעים כל המספרים בתחום 1 עד n2(כולל). בכל תת ריבוע מתאים מופיעים כל המספרים בתחום 1 עד n2(כולל). כאשר : הלוח מחולק לתת ריבועים באופן כזה שגודלו של כל תת ריבוע הוא n x n וכל תת הריבועים צמודים זה לזה ומכסים את כל הלוח. סך הכל יש n2 תת ריבועים כאלה. הרצאה 14
functionr = check_soduku(table,n) %%%%%check if table is legal soduku of order n^2 by n^2 r=1; if size(table)~=[n^2,n^2],r=0; return,end fori=1:n^2 %check rows if ~check_line(table(i,:)) r=0; return end end fori=1:n^2 %check columns if ~check_line(table(:,i)) r=0; return end end fori=1:n:n^2% check squares for j=1:n:n^2 if ~check_square(table(i:i+n-1,j:j+n-1)) r=0; return end end end הרצאה 14
שאלה 6 תרגיל בית 5 להלן האלגוריתם הרקורסיבי השני לחישוב מספרי פיבונאצ'י שהוצג בהרצאה: • function [f1, f0] = myfib_fast_rec(n) • if ( n <= 2) • f0 = 1; • f1 = 1; • else • [f1, f0] = myfib_fast_rec(n - 1); % f0=fibonacci(n-2), f(1)=fibonnaci(n-1) • [f1, f0] = deal(f1 + f0, f1); % f0 = fibonacci(n-1), f(1)=fibonnaci(n) • end נגדיר H(n) כמספר הקריאות לפונקציה myfib_fast_rec המתבצעות במהלך ביצוע הפונקציה עבור קלט n 1. הסבירו, על סמך הקוד, מדוע H(1) = H(2) =0 . 2. הוכיחו באינדוקציה כי עבור n>1 מתקיים: H(n) = n-2. הרצאה 14
הסבירו, על סמך הקוד, מדוע H(1) = H(2) =0 . • הוכיחו באינדוקציה כי עבור n>1 מתקיים: H(n) = n-2. תשובה • כאשר n=1 לא מתבצעת קריאה רקורסיבית ולכן לא מתקיימת אף קריאה. אותו כנ"ל כאשר n=2. 2. הוכחה באינדוקציה: בסיס: עבור n=2 נובע מסעיף 1.שלב מעבר: נניח ש n>2, נניח נכונות עבור n-1, נוכיח עבור n. נכונות עבור n-1 פרושה: H(n-1) = (n-1)-2 = n-3 עבור n>2 תנאי העצירה לא מתקיים, ולכן מתבצעת בשורה 6 קריאה רקורסיבית אחת לפונקציה עם פרמטר n-1. בנוסף לכך מתבצעות H(n-1) קריאות במהלך ביצוע הקריאה הרקורסיבית. כלומרH(n) = H(n-1)+1 ומכאן ההוכחה: H(n) = H(n-1)+1 =( n-3)+1 = n-2 • function [f1, f0] = myfib_fast_rec(n) • if ( n <= 2) • f0 = 1; • f1 = 1; • else • [f1, f0] = myfib_fast_rec(n - 1); % f0=fibonacci(n-2), f(1)=fibonnaci(n-1) • [f1, f0] = deal(f1 + f0, f1); % f0 = fibonacci(n-1), f(1)=fibonnaci(n) • end הרצאה 14