חזור לתיקייה: 02340218 - מבני נתונים 1

1 - סיבוכיות של חישובים

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה
  • כללי
  • ההגדרות הבסיסיות
  • סיבוכיות זמן

1 - סיבוכיות של חישובים

02340218

מבני נתונים 1

רשימות הרצאה לקריאה בשבת

סיבוכיות של חישובים

הופק מתוך תקיית התואר של שקד

uni-folder.vercel.app

הגדרה 1 (זמן ריצה של אלגוריתם)

יהי אלגוריתם AAA וקלט xxx. נאמר כי זמן הריצה של AAA על xxx הוא מספר פקודות המכונה שהאלגוריתם מבצע על הקלט xxx. נסמנו ב-timeA(x)time_{\small A}(x)timeA​(x).

הערה

  • מתעלמים מהבדלי המהירות בין פקודות שונות.
  • מתעלמים מהבדלי מהירות והבדלי פקודות בין מכונה למכונה.
  • עושים את זה ככה על מנת להימנע מעומס פרטים וכדי שנוכל לעבוד באופן יעיל.
הגדרה (סימון)

האורך של הקלט xxx יסומן כמובן ב-∣x∣|x|∣x∣.

דוגמה

בתוכנית המסכמת איברי מערך xxx, אורך הקלט הוא מספר איברי המערך.

הגדרה 2 (זמן הריצה במקרה הגרוע)

יהי אלגוריתם AAA ויהי n∈R+∪{0}n \in \mathbb{R}^+ \cup \left\{ 0 \right\}n∈R+∪{0}.
נאמר כי זמן הריצה הגרוע ביותר של AAA עבור קלט שגודלו nnn מוגדר ע"י:

tA(n)=max⁡{timeA(x)∣∣x∣=n}t_{\tiny A}(n)=\max\left\{ time_{\tiny A}(x) \mid |x|=n\right\}tA​(n)=max{timeA​(x)∣∣x∣=n}
דוגמה

עבור קלט שהוא מערך aaa בגודל nnn נסכם את איברי המערך:

sum = 0;
for (i = 0; i < n; i++)
	sum = sum + a[i];

זמן הריצה הגרוע ביותר של אלגוריתם זה מקיים:

n+1≤tA(n)≤c1⋅n+c2n+1\leq t_{\small A}(n)\leq c_{1}\cdot n +c_{2}n+1≤tA​(n)≤c1​⋅n+c2​

כאשר c1c_{1}c1​ הוא מספר הפעולות בכל איטרציה של הלולאה ו-c2c_{2}c2​ הוא מספר הפעולות מחוץ ללולאה.

דוגמה

נבדוק האם מספר מסויים numnumnum הוא ראשוני ע"י חלוקה בכל האיברים עד אליו:

for (i = 2; i < num; i++)
	if (num % i == 0) return false;
return true;

למספר זוגי תתבצע איטרציה אחת בלבד ולכן time(9998)=c1+c2time(9998)=c_{1}+c_{2}time(9998)=c1​+c2​.
עבור מספר ראשוני יהיו מלאאא איטרציות time(9973)=9971⋅c1+c2time(9973)=9971\cdot c_{1}+c_{2}time(9973)=9971⋅c1​+c2​.
⟸ זמן הריצה הגרוע ביותר לקלט באורך 444 ספרות יהיה t(4)=9971⋅c1+c2t(4)=9971\cdot c_{1}+c_{2}t(4)=9971⋅c1​+c2​.
⟸ באופן כללי יותר לקלט באורך nnn ספרות מתקיים t(n)<10nc1+c2t(n)<10^nc_{1}+c_{2}t(n)<10nc1​+c2​.

ההגדרות הבסיסיות

הגדרה 3 (הקבוצה OOO)

יהיו f,g:N→R+f,g:\mathbb{N}\to \mathbb{R}^+f,g:N→R+.
נאמר שהפונקציה f(n)f(n)f(n) נמצאת בקבוצת הפונקציות O(g(n))\textbf{O(g(n))}O(g(n)) אם קיימים קבועים c,n0>0c,n_{0}>0c,n0​>0 כך שלכל n≥n0n\geq n_{0}n≥n0​ מתקיים: f(n)≤c⋅g(n)f(n)\leq c\cdot g(n)f(n)≤c⋅g(n).
כמו כן, נאמר ש-g(n)g(n)g(n) מהווה חסם עליון אסימפטוטי לפונקציה f(n)f(n)f(n) ונסמן זאת ע"י f(n)=O(g(n))f(n)=O(g(n))f(n)=O(g(n)). (במקום הסימון הקבוצתי f(n)∈O(g(n))f(n)\in O(g(n))f(n)∈O(g(n)))

דוגמה (מעבר בסיס בלוגריתמים)

לכל a,b>1a,b>1a,b>1 קבועים מתקיים: f(n)=log⁡an=O(log⁡bn)f(n)=\log _an=O(\log_{b}n)f(n)=loga​n=O(logb​n) משום ש:

log⁡an=log⁡ab⋅log⁡bn\log_{a}n=\log_{a}b\cdot \log_{b}nloga​n=loga​b⋅logb​n

ומכיוון ש-c=log⁡abc=\log_{a}bc=loga​b הוא קבוע שאינו תלוי ב-nnn נקבל ישירות כי log⁡an≤c⋅log⁡bn\log_{a}n\leq c\cdot \log_{b}nloga​n≤c⋅logb​n לכל n∈Nn \in \mathbb{N}n∈N.

טענה

לכל k∈Nk \in \mathbb{N}k∈N מתקיים:

f(n)=a0a1n+a2n2+⋯+aknk=O(nk)f(n)=a_{0}a_{1}n+a_{2}n^2+\dots+a_{k}n^k=O(n^k)f(n)=a0​a1​n+a2​n2+⋯+ak​nk=O(nk)

הוכחה:
יהי amax⁡=max⁡{1,a0,…,ak}a_{\max}=\max\left\{ 1,a_{0},\dots,a_{k} \right\}amax​=max{1,a0​,…,ak​} אזי:

f(n)≤amax⁡(1+n+n2+⋯+nk)=amax⁡⋅(nk+1−1)n−1≤↓n≥2נכון לכל:amax⁡nk+1n2=2amax⁡nkf(n)\leq a_{\max}(1+n+n^2+\dots+n^k)=\frac{a_{\max}\cdot(n^{k+1}-1)}{n-1}\underset{\begin{matrix} \downarrow \\ n\geq 2\R{\text{נכון לכל:}} \end{matrix}}{\leq} \frac{a_{\max}n^{k+1}}{\frac{n}{2}}=2a_{\max}n^kf(n)≤amax​(1+n+n2+⋯+nk)=n−1amax​⋅(nk+1−1)​↓n≥2נכון לכל:​≤​2n​amax​nk+1​=2amax​nk

לפיכך נבחר n0=2n_{0}=2n0​=2 ו-c=2amax⁡c=2a_{\max}c=2amax​ ואז לפי הגדרה f(n)=O(nk)f(n)=O(n^k)f(n)=O(nk).
∎

דוגמה

נאמר כי לכל ε>0\epsilon>0ε>0 חיובי מתקיים: f(n)=log⁡an=O(nε)f(n)=\log_{a}n=O(n^\epsilon)f(n)=loga​n=O(nε) וזאת כך:

log⁡an=↓חוקי לוגריתמים1εlog⁡2alog⁡2(nε)≤↓log⁡2n<nc⋅nε\log_{a}n \underset{\begin{matrix} \downarrow \\ \R{\text{חוקי לוגריתמים}} \end{matrix}}{=}\frac{1}{\epsilon \log_{2}a}\log_{2}(n^\epsilon)\underset{\begin{matrix} \downarrow \\ \log_{2}n<n \end{matrix}}{\leq} c\cdot n^\epsilonloga​n↓חוקי לוגריתמים​=​εlog2​a1​log2​(nε)↓log2​n<n​≤​c⋅nε
הערה

כל פונקציה לוגריתמית גדלה לאט יותר מכל חזקה חיובית של nnn. (אפילו n0.00000000001n^{0.00000000001}n0.00000000001)

דוגמה

f(n)=nk+an=O(an)f(n)=an=O(bn),a<bf(n)=n^k+a^n=O(a^n) \qquad \qquad \qquad \qquad \quad f(n)=a^n=O(b^n), \quad a<bf(n)=nk+an=O(an)f(n)=an=O(bn),a<b nk+an=aklog⁡an+an<c⋅an∀n∈N,a≤b:  an≤bnn^k+a^n=a^{k\log_{a}n}+a^n<c\cdot a^n \qquad \qquad \qquad \quad \forall n \in \mathbb{N}, a\leq b:\; a^n\leq b^nnk+an=akloga​n+an<c⋅an∀n∈N,a≤b:an≤bn
דוגמה

נראה כעת למה 3n≠O(2n)3^n\neq O(2^n)3n=O(2n):
נניח בשלילה שקיימים קבועים n0,c>0n_{0},c>0n0​,c>0 כך שלכל n≥n0n\geq n_{0}n≥n0​ מתקיים: 3n≤c⋅2n3^n\leq c\cdot 2^n3n≤c⋅2n.
נחלק ב-2n2^n2n ונקבל: (32)n≤c\left( \frac{3}{2} \right)^n\leq c(23​)n≤c ונוציא לוגריתם בבסיס 32\frac{3}{2}23​ משני האגפים: n≤log⁡32cn\leq \log_{\frac{3}{2}}cn≤log23​​c.
סתירה לכך שלכל n>log⁡32cn> \log_{\frac{3}{2}}cn>log23​​c אי השוויון לא נכון. לכן, 3n≠O(2n)3^n\neq O(2^n)3n=O(2n).

דוגמה

האם f(n)=en=O(nk)f(n)=e^n=O(n^k)f(n)=en=O(nk) עבור kkk קבוע? לא, בכלל לא.
על מנת להוכיח זאת נחשב את הגבול:

lim⁡x→∞xkex=lim⁡x→∞kxk−1ex=⋯=lim⁡x→∞k!ex=0\lim_{ x \to \infty } \frac{x^k}{e^x}=\lim_{ x \to \infty } \frac{kx^{k-1}}{e^x}=\dots=\lim_{ x \to \infty } \frac{k!}{e^x}=0x→∞lim​exxk​=x→∞lim​exkxk−1​=⋯=x→∞lim​exk!​=0

נקבל אם כן את השלבים הבאים:

∀ε∈R+,∃x0,∀x>x0:  ∣xkex∣<ε  ⟹  ∀ε∈R+,∃x0,∀x>x0:  xk<ε⋅ex\forall \epsilon \in \mathbb{R}^+, \exists x_{0}, \forall x>x_{0}:\; \left| \frac{x^k}{e^x} \right|<\epsilon \implies \forall \epsilon \in \mathbb{R}^+,\exists x_{0},\forall x>x_{0}:\;x^k<\epsilon\cdot e^x∀ε∈R+,∃x0​,∀x>x0​:​exxk​​<ε⟹∀ε∈R+,∃x0​,∀x>x0​:xk<ε⋅ex

נעבור לשלילה ונחליף את ε\epsilonε ב-ccc ואת xxx ב-nnn ואז נקבל כי:

∄c,n0,∀n>n0:  en<c⋅nk\not \exists c,n_{0}, \forall n>n_{0}:\; e^n<c\cdot n^k∃c,n0​,∀n>n0​:en<c⋅nk
מסקנה

התשובה שלילית. ene^nen אינו חסום ע"י שום פולינום nkn^knk. כלומר en≠O(nk)e^n\neq O(n^k)en=O(nk).

מסקנה (היררכית קצב הגידול של משפחות הפונקציות)

1log⁡(log⁡n)log⁡n…nnlog⁡nn2…2n1 \quad \log(\log n) \qquad \log n \qquad \dots \qquad n \qquad n\log n \qquad n^2 \qquad \dots \qquad 2^n1log(logn)logn…nnlognn2…2n

סיבוכיות זמן

דוגמה (כפל מטריצות בגודל m×mm\times mm×m)

גודל הקלט שלנו הוא: n=2m2n=2m^2n=2m2.
מחשבים m2m^2m2 איברים במטריצת התוצאה, כאשר כל איבר מחושב לפי ההגדרה:

Ci,j=∑k=1mAi,kBk,jC_{i,j}=\sum_{k=1}^m A_{i,k}B_{k,j}Ci,j​=k=1∑m​Ai,k​Bk,j​

סיבוכיות הזמן כפונקציה של mmm היא T(m)=O(m3)T(m)=O\left( m^3 \right)T(m)=O(m3) (ביצוע של mmm פעולות כפל וחיבור עבור כל אחת מה-m2m^2m2 איברים)

m=n2  ⟹  T(n)=O(m3)=O(n32232)=O(n32)m=\sqrt{ \frac{n}{2} }\implies T(n)=O(m^3)=O\left( \frac{n^{\frac{3}{2}}}{2^{\frac{3}{2}}} \right)=O(n^{\frac{3}{2}})m=2n​​⟹T(n)=O(m3)=O(223​n23​​)=O(n23​)
דוגמה (חיפוש בינארי)

חיפוש בינארי המוכר יהיה בעל סיבוכיות זמן TTT המוגדרת בעזרת נוסחת הנסיגה הבאה:

T(n)=c+T(n2)T(n)=c+T\left( \frac{n}{2} \right)T(n)=c+T(2n​)

כאשר T(1)=cT(1)=cT(1)=c. נאמר אם כן כי:

T(n)=c+c+T(n4)=c+⋯+c⏞i+T(n2i)=clog⁡2n+T(1)=O(log⁡n)T(n)=c+c+T\left( \frac{n}{4} \right)=\overbrace{c+\dots+c}^i+T\left( \frac{n}{2^i} \right)=c\log_{2}n+T(1)=O(\log n)T(n)=c+c+T(4n​)=c+⋯+c​i​+T(2in​)=clog2​n+T(1)=O(logn)
דוגמה

עבור פיסת הקוד:

S = 0;
for (i = 1; i < n; i++)
	for (j = 0; j < n; j += i)
		S++;

באנליזה גסה היינו אומרים כי T(n)≤O(n2)T(n)\leq O(n^2)T(n)≤O(n2).
באנליזה עדינה יותר היינו מגלים כי:

  • עבור i=1i=1i=1 מתבצעות nnn פעולות.
  • עבור i=2i=2i=2 מתבצעות n2\frac{n}{2}2n​ פעולות.
  • עבור i=ki=ki=k מתבצעות nk\frac{n}{k}kn​ פעולות.
  • עד i=ni=ni=n עבורו מתבצעות nn\frac{n}{n}nn​ פעולות.

סה"כ פעולות:

T(n)≤n+n2+n3+⋯+nn=n(1+12+13+⋯+1n)=nHnT(n)\leq n+\frac{n}{2}+\frac{n}{3}+\dots+\frac{n}{n}=n\left( 1+\frac{1}{2}+\frac{1}{3}+\dots+\frac{1}{n} \right)=nH_{n}T(n)≤n+2n​+3n​+⋯+nn​=n(1+21​+31​+⋯+n1​)=nHn​

כאשר HnH_{n}Hn​ נקרא המספר ההרמוני ה-nnn.

טענה (חסם אינטגרלי לסכום ההרמוני)

ln⁡(n+1)=∫1n+11xdx≤1+12+13+⋯+1n≤1+∫1n1xdx=1+ln⁡(n)\ln(n+1)=\int_{1}^{n+1} \frac{1}{x}dx\leq 1+\frac{1}{2}+\frac{1}{3}+\dots+\frac{1}{n}\leq 1+\int_{1}^n \frac{1}{x}dx=1+\ln(n)ln(n+1)=1∫n+1​x1​dx≤1+21​+31​+⋯+n1​≤1+1∫n​x1​dx=1+ln(n)

מהטענה הנ"ל נקבל כי T(n)≤nHn≤n(1+ln⁡n)≤n⋅2ln⁡n=2nln⁡n=O(nlog⁡n)T(n)\leq nH_{n}\leq n(1+\ln n)\leq n\cdot 2\ln n=2n\ln n=O(n\log n)T(n)≤nHn​≤n(1+lnn)≤n⋅2lnn=2nlnn=O(nlogn).

הערה (חשובה מאוד)

ניתוח אסימפטוטי מתאר התנהגות עבור קלטים גדולים מאוד (n→∞n\to \inftyn→∞)
עבור גדלי קטל קטנים ומעשיים, הקבועים הכפליים עשויים להכריע!