نماد O بزرگ (به انگلیسی : Big O notation ) یک نماد ریاضیاتی ست که برای توصیف رفتار حدی یک تابع (وقتی آرگومانهای آن به بینهایت میل کند) به کار میرود.
این نماد (مخفف Order of growth (به فارسی : مرتبهٔ رشد)) اولین بار برای تحلیل سرعت الگوریتمهای رایانشی ابداع شد و بعدها به حسابان و نظریّهٔ اعداد گسترش یافت.
در علوم رایانه و نظریهٔ پیچیدگی محاسباتی ، این نماد برای تحلیل الگوریتمها و دستهبندی و مقایسهٔ الگوریتمهای متفاوتِ موجود برای حل یک مسئلهٔ خاص به کار میرود. پیچیدگی محاسباتی نشاندهندهٔ رابطهٔ میان «دادهها » با «مقدار زمان یا مقدار حافظهٔ مورد نیاز برای پیدا کردن جواب » است و برای توصیف آن از این نماد استفاده میشود.[ ۱]
در نظریهٔ تحلیلی اعداد ، این نماد برای توصیف میزان دقت یک تقریب به کار میرود. یکی از مثالهای معروف این موضوع در قضیهٔ اعداد اول است: اگر
π
(
x
)
{\displaystyle \pi (x)}
تعداد اعداد اول کمتر از
x
{\displaystyle x}
باشد، آنگاه
π
(
x
)
∼
x
ln
(
x
)
{\displaystyle \pi (x)\thicksim {x \over \ln(x)}}
.
در حسابان نیز این نماد در تحلیل مجانبی و سریهای تیلور کاربرد دارد.
به دلیل توصیف رفتار حدی ، نماد
O
{\displaystyle {\mathcal {O}}}
به ریاضیدانها اجازه میدهد که تابع را ساده کنند تا بر روی نرخ رشد آن متمرکز شود؛ بنابراین توابع مختلف با نرخ رشد یکسان میتوانند دارای یک نماد
O
{\displaystyle {\mathcal {O}}}
مشابه باشند و در نتیجه در یک دسته قرار بگیرند.
نماد
O
{\displaystyle {\mathcal {O}}}
معروفترین عضو از مجموعهای از نمادهای دیگری همچون
o
{\displaystyle o}
(کوچک) و ... است که ابداعات پاول باخمن (به آلمانی : Paul Bachmann )[ ۲] و ادموند لانداو (به آلمانی : Edmund Landau )[ ۳] بوده اند؛ به همین دلیل به اینها نمادهای باخمن-لانداو و یا نمادهای مجانبی (به انگلیسی : asymptotic notations ) گفته میشود.
فرض کنید که
f
(
n
)
{\displaystyle f(n)}
تابعی باشد که بخواهیم آن را توصیف کنیم و
g
(
n
)
{\displaystyle g(n)}
نیز یک تابع فرضی ست و همچنین
f
{\displaystyle f}
و
g
{\displaystyle g}
توابع مثبت هستند.
هر نماد دو تعریف معمول و تعریف حدی دارد (که طبق قضیههایی معادل یکدیگر هستند و به یک مفهوم اشاره دارند).
نمادهای
O
{\displaystyle {\mathcal {O}}}
و
Θ
{\displaystyle {\mathcal {\Theta }}}
پرکاربردترین اینها هستند.
f
∈
O
(
g
)
⟺
∃
c
,
n
0
:
∀
n
⩾
n
0
:
0
⩽
f
(
n
)
⩽
c
g
(
n
)
{\displaystyle f\in {\mathcal {O}}(g)\Longleftrightarrow \exists c,n_{0}:\forall n\geqslant n_{0}:0\leqslant f(n)\leqslant cg(n)}
[ ۱]
به این معنی که از یک مقدار
n
{\displaystyle n}
خاصی (
n
0
{\displaystyle n_{0}}
) بیشتر، تابع
f
{\displaystyle f}
از ضریبی از تابع
g
{\displaystyle g}
کمتر یا مساوی است.
به عنوان مثال،
n
∈
O
(
n
2
)
{\displaystyle n\in {\mathcal {O}}(n^{2})}
و میخوانیم «
n
{\displaystyle n}
از اردر
n
2
{\displaystyle n^{2}}
است» یا «
n
{\displaystyle n}
از اُو
n
2
{\displaystyle n^{2}}
است» یا «
n
2
{\displaystyle n^{2}}
کران بالای حدی
n
{\displaystyle n}
است».[ ۴]
به طور رایج، به جای علامت
∈
{\displaystyle \in }
از
=
{\displaystyle =}
استفاده میشود:
n
=
O
(
n
2
)
{\displaystyle n={\mathcal {O}}(n^{2})}
اما باید دقت کنید که این رابطه تساوی نیست. به عنوان مثال
n
=
O
(
n
2
)
{\displaystyle n={\mathcal {O}}(n^{2})}
و
2
n
=
O
(
n
2
)
{\displaystyle 2n={\mathcal {O}}(n^{2})}
ولی
n
≠
2
n
{\displaystyle n\neq 2n}
همچنین
O
(
n
)
=
O
(
n
2
)
{\displaystyle {\mathcal {O}}(n)={\mathcal {O}}(n^{2})}
ولی
O
(
n
2
)
≠
O
(
n
)
{\displaystyle {\mathcal {O}}(n^{2})\neq {\mathcal {O}}(n)}
میتوان
O
(
g
(
n
)
)
{\displaystyle {\mathcal {O}}(g(n))}
را به صورت مجموعهٔ تمام توابعی که از اردر
g
{\displaystyle g}
هستند تصور کرد.
همیشه سعی میشود که از سادهترین
g
{\displaystyle g}
ممکن استفاده شود. به عنوان مثال
n
=
O
(
n
2
)
{\displaystyle n={\mathcal {O}}(n^{2})}
و
n
=
O
(
3
n
2
+
2
n
+
1
)
{\displaystyle n={\mathcal {O}}(3n^{2}+2n+1)}
هر دو درست اند ولی اولی ترجیح داده میشود.[ ۱]
یک نماد قدیمی به صورت
f
≼
g
{\displaystyle f\preccurlyeq g}
است. به تفاوت بین علامت
≼
{\displaystyle \preccurlyeq }
و
⩽
{\displaystyle \leqslant }
توجه کنید.
تعریف حدی:
f
≼
g
⟺
lim
n
→
∞
f
g
<
∞
{\displaystyle f\preccurlyeq g\Longleftrightarrow \lim _{n\to \infty }{f \over g}<\infty }
[ ۵]
f
∈
o
(
g
)
⟺
∀
c
:
∃
n
0
:
∀
n
⩾
n
0
:
0
<
f
(
n
)
<
c
g
(
n
)
{\displaystyle f\in {\mathcal {o}}(g)\Longleftrightarrow \forall c:\exists n_{0}:\forall n\geqslant n_{0}:{0<f(n)<cg(n)}}
[ ۱]
به این معنی که از یک مقدار
n
{\displaystyle n}
خاصی (
n
0
{\displaystyle n_{0}}
) بیشتر، تابع
f
{\displaystyle f}
از تابع
g
{\displaystyle g}
و تمام مضارب آن اکیداً کمتر است.
به عنوان مثال،
n
=
o
(
n
2
)
{\displaystyle n={\mathcal {o}}(n^{2})}
و میخوانیم «نرخ رشد
n
{\displaystyle n}
از
n
2
{\displaystyle n^{2}}
کمتر است» یا «
n
{\displaystyle n}
به صورت حدی از
n
2
{\displaystyle n^{2}}
کوچکتر است».
n
2
≠
o
(
n
2
)
{\displaystyle n^{2}\neq {\mathcal {o}}(n^{2})}
ولی
n
2
=
O
(
n
2
)
{\displaystyle n^{2}={\mathcal {O}}(n^{2})}
.
تعریف حدّی:
f
≺
g
⟺
lim
n
→
∞
f
g
=
0
{\displaystyle f\prec g\Longleftrightarrow \lim _{n\to \infty }{f \over g}=0}
f
∈
Ω
(
g
)
⟺
∃
c
,
n
0
:
∀
n
⩾
n
0
:
f
(
n
)
⩾
c
g
(
n
)
⩾
0
{\displaystyle f\in {\mathcal {\Omega }}(g)\Longleftrightarrow \exists c,n_{0}:\forall n\geqslant n_{0}:f(n)\geqslant cg(n)\geqslant 0}
[ ۱]
به این معنی که از یک مقدار
n
{\displaystyle n}
خاصی (
n
0
{\displaystyle n_{0}}
) بیشتر، تابع
f
{\displaystyle f}
از ضریبی از تابع
g
{\displaystyle g}
بیشتر یا مساوی است.
به عنوان مثال،
n
2
=
Ω
(
n
)
{\displaystyle n^{2}={\mathcal {\Omega }}(n)}
و میخوانیم «
n
2
{\displaystyle n^{2}}
از امگا
n
{\displaystyle n}
است» یا «
n
2
{\displaystyle n^{2}}
کران بالای حدی
n
{\displaystyle n}
است».
تعریف حدی:
f
≽
g
⟺
lim
n
→
∞
f
g
>
0
{\displaystyle f\succcurlyeq g\Longleftrightarrow \lim _{n\to \infty }{f \over g}>0}
[ ۵]
f
∈
ω
(
g
)
⟺
∀
c
:
∃
n
0
:
∀
n
⩾
n
0
:
f
(
n
)
>
c
g
(
n
)
>
0
{\displaystyle f\in {\mathcal {\omega }}(g)\Longleftrightarrow \forall c:\exists n_{0}:\forall n\geqslant n_{0}:f(n)>cg(n)>0}
[ ۱]
به این معنی که از یک مقدار
n
{\displaystyle n}
خاصی (
n
0
{\displaystyle n_{0}}
) بیشتر، تابع
f
{\displaystyle f}
از تابع
g
{\displaystyle g}
و تمام مضارب آن اکیداً بیشتر است.
به عنوان مثال،
n
2
=
ω
(
n
)
{\displaystyle n^{2}={\mathcal {\omega }}(n)}
و میخوانیم «نرخ رشد
n
2
{\displaystyle n^{2}}
از
n
{\displaystyle n}
بیشتر است» یا «
n
2
{\displaystyle n^{2}}
به صورت حدی از
n
{\displaystyle n}
بزرگتر است».
n
2
≠
ω
(
n
2
)
{\displaystyle n^{2}\neq {\mathcal {\omega }}(n^{2})}
ولی
n
2
=
Ω
(
n
2
)
{\displaystyle n^{2}={\mathcal {\Omega }}(n^{2})}
.
تعریف حدی:
f
≻
g
⟺
lim
n
→
∞
f
g
=
∞
{\displaystyle f\succ g\Longleftrightarrow \lim _{n\to \infty }{f \over g}=\infty }
خاصیت تقارنی ترانهاده با O[ ویرایش ]
g
∈
Ω
(
f
)
⟺
g
≽
f
⟺
f
≼
g
⟺
f
∈
O
(
g
)
{\displaystyle g\in {\mathcal {\Omega }}(f)\Longleftrightarrow g\succcurlyeq f\Longleftrightarrow f\preccurlyeq g\Longleftrightarrow f\in {\mathcal {O}}(g)}
g
∈
ω
(
f
)
⟺
g
≻
f
⟺
f
≺
g
⟺
f
∈
o
(
g
)
{\displaystyle g\in {\mathcal {\omega }}(f)\Longleftrightarrow g\succ f\Longleftrightarrow f\prec g\Longleftrightarrow f\in {\mathcal {o}}(g)}
f
∈
Θ
(
g
)
⟺
g
∈
Θ
(
f
)
⟺
∃
c
1
,
c
2
,
n
0
:
∀
n
⩾
n
0
:
0
⩽
c
1
g
⩽
f
(
n
)
⩽
c
2
g
(
n
)
{\displaystyle f\in {\mathcal {\Theta }}(g)\Longleftrightarrow g\in {\mathcal {\Theta }}(f)\Longleftrightarrow \exists c_{1},c_{2},n_{0}:\forall n\geqslant n_{0}:0\leqslant c_{1}g\leqslant f(n)\leqslant c_{2}g(n)}
[ ۱]
به این معنی که از یک مقدار
n
{\displaystyle n}
خاصی (
n
0
{\displaystyle n_{0}}
) بیشتر، تابع
f
{\displaystyle f}
در بین ضریبهایی از
g
{\displaystyle g}
ساندویچ میشود.
به عنوان مثال،
2
n
=
Θ
(
n
)
{\displaystyle 2n={\mathcal {\Theta }}(n)}
و میخوانیم «
2
n
{\displaystyle 2n}
از تتا
n
{\displaystyle n}
است» یا «نرخ رشد
2
n
{\displaystyle 2n}
و
n
{\displaystyle n}
یکسان است» یا «
2
n
{\displaystyle 2n}
و
n
{\displaystyle n}
به صورت مجانبی برابر اند».
تعریف حدی:
f
∼
g
⟺
g
∼
f
⟺
lim
n
→
∞
f
g
=
c
>
0
{\displaystyle f\thicksim g\Longleftrightarrow g\thicksim f\Longleftrightarrow \lim _{n\to \infty }{f \over g}=c>0}
[ ۱]
با وجود این تعریف در علوم کامپیوتری، تعریف این نماد در ریاضیات کمی متفاوت است:
f
∼
g
⟺
g
∼
f
⟺
lim
n
→
∞
f
g
=
1
{\displaystyle f\thicksim g\Longleftrightarrow g\thicksim f\Longleftrightarrow \lim _{n\to \infty }{f \over g}=1}
این نماد در تحلیل مجانبی در ریاضیات پرکاربرد است.[ ۶]
f
∈
Θ
(
g
)
⟺
g
∈
Θ
(
f
)
⟺
f
∈
O
(
g
)
∧
g
∈
O
(
f
)
{\displaystyle f\in {\mathcal {\Theta }}(g)\Longleftrightarrow g\in {\mathcal {\Theta }}(f)\Longleftrightarrow f\in {\mathcal {O}}(g)\land g\in {\mathcal {O}}(f)}
[ ۱]
به این معنی که هم
f
{\displaystyle f}
از اردر
g
{\displaystyle g}
باشد و هم
g
{\displaystyle g}
از اردر
f
{\displaystyle f}
باشد. این قضیه ابداع دونالد کنوت بود و مزیت آن سادگی و قابلفهم کردن تعریف است.
به عبارت دیگر اگر نرخ رشد
f
{\displaystyle f}
از
g
{\displaystyle g}
هم بیشتر-مساوی باشد و هم کمتر-مساوی، پس نرخ رشدشان مساوی است.
f
∼
g
⟺
g
∼
f
⟺
f
≼
g
≼
f
{\displaystyle f\thicksim g\Longleftrightarrow g\thicksim f\Longleftrightarrow f\preccurlyeq g\preccurlyeq f}
کنوت با این تعریف، نماد O بزرگ را به علوم کامپیوتر معرفی و آن را محبوب کرد.[ ۵]
Θ
(
f
)
=
O
(
f
)
∩
Ω
(
f
)
{\displaystyle \Theta (f)={\mathcal {O}}(f)\cap \Omega (f)}
چهار تابع زیر را در نظر بگیرید:
f
(
n
)
=
1000
n
2
+
20
n
+
16
{\displaystyle f(n)=1000n^{2}+20n+16}
g
(
n
)
=
2
n
3
+
100
n
4
3
+
56
{\displaystyle g(n)=2n^{3}+100n^{\tfrac {4}{3}}+56}
h
(
n
)
=
n
3
−
1
2
n
2
+
1
3
n
{\displaystyle h(n)=n^{3}-{\frac {1}{2}}n^{2}+{\frac {1}{3}}n}
i
(
n
)
=
1
1000
n
4
{\displaystyle i(n)={\frac {1}{1000}}n^{4}}
رفتار این چهار تابع را طبق نمودارشان بررسی میکنیم. در ابتدا به نظر میرسد تابع
f
{\displaystyle f}
با توجه به ضریب بزرگتری که دارد مقدارهای بزرگتری نیز داشته باشد که برای
n
≤
100
{\displaystyle n\leq 100}
هم همین گونه است.
نمودار این ۴ تابع وقتی
n
≤
100
{\displaystyle n\leq 100}
اما با بزرگ شدن مقدار
n
{\displaystyle n}
رفتار تابعها نیز نسبت به هم متفاوت میشود. شکل زیر رفتار توابع را وقتی
n
≤
1000
{\displaystyle n\leq 1000}
است نشان میدهد. ملاحظه میشود که تابع
g
{\displaystyle g}
بهتدریج مقدارش از سایر توابع بیشتر میشود.
با بزرگتر شدن
n
{\displaystyle n}
وضعیت به این شکل در میآید: بهتدریج تابع
i
{\displaystyle i}
از بقیه توابع بیشتر میشود.
و برای مقدار بزرگ
n
{\displaystyle n}
داریم:
تابع
i
{\displaystyle i}
کاملاً از بقیه توابع بیشتر میشود.
همان طور که دیده شد، چون این تابع از سایر توابع مرتبهٔ بالاتری داشت در نهایت مقدارش از همهٔ آنها بیشتر شد.
طبق تعاریف بالا میتوان رابطهٔ این توابع را برحسب نمادگذاریهای گفته شده بیان کنیم:
f
(
n
)
=
O
(
g
(
n
)
)
{\displaystyle f(n)={\mathcal {O}}(g(n))}
یا
f
(
n
)
=
o
(
g
(
n
)
)
{\displaystyle f(n)=o(g(n))}
و
g
(
n
)
=
Ω
(
f
(
n
)
)
{\displaystyle g(n)=\Omega (f(n))}
یا
g
(
n
)
=
ω
(
f
(
n
)
)
{\displaystyle g(n)=\omega (f(n))}
g
(
n
)
=
Θ
(
h
(
n
)
)
{\displaystyle g(n)=\Theta (h(n))}
زیرا تابع
g
{\displaystyle g}
همواره حدوداً دوبرابر تابع
h
{\displaystyle h}
است و مرتبهٔ یکسانی دارند.
h
(
n
)
=
O
(
i
(
n
)
)
{\displaystyle h(n)={\mathcal {O}}(i(n))}
یا
h
(
n
)
=
o
(
i
(
n
)
)
{\displaystyle h(n)=o(i(n))}
علامت O بزرگ اولین بار توسط متخصص اعداد Paul Bachmann در سال ۱۸۹۴، در جلد دوم کتاب Analytische Zahlentheorie معرفی شد (که جلد اولش در سال ۱۸۹۲ چاپ شده و شامل این علامت نبود). این علامت در کارهای نظریه اعداد توسط ادموند لانداو متداول شد و به همین خاطر گاهی از آن به نام Landau symbol یاد میشود.
این علامت در علوم کامپیوتر توسط دانلد کنوت (که علامتهای مربوطه امگا و تتا را نیز برای اولین بار معرفی کرد) مشهور شد. او هم چنین متذکر شد که علامت امگا توسط Hardy و Littlewood تحت معنی اندکی متفاوت قبلاً تعریف شده بودهاست.
↑ ۱٫۰ ۱٫۱ ۱٫۲ ۱٫۳ ۱٫۴ ۱٫۵ ۱٫۶ ۱٫۷ ۱٫۸ Introduction to Algorithms (CLRS) (3rd edition) . به کوشش Thomas H. Cormen, Charles E. Leiserson, Ronald Rivest, Clifford Stein.
↑ Bachmann, Paul (1894). Analytische Zahlentheorie [Analytic Number Theory ] (به آلمانی). Vol. 2. Leipzig: Teubner.
↑ Landau, Edmund (1909). Handbuch der Lehre von der Verteilung der Primzahlen [Handbook on the theory of the distribution of the primes ] (به آلمانی). Leipzig: B. G. Teubner. p. 883.
↑ مقدمهای بر الگوریتمها (ویراست سوم) . به کوشش توماس کورمن، چارلز لیزرسون، رونالد ریوست و کلیفورد استین. ترجمه مهندس دهقان طرزه.
↑ ۵٫۰ ۵٫۱ ۵٫۲ Knuth, Donald (April–June 1976). "Big Omicron and big Omega and big Theta" (PDF) . SIGACT News . 8 (2): 18–24. doi :10.1145/1008328.1008329 . S2CID 5230246 . Archived from the original (PDF) on 30 November 2021. Retrieved 28 September 2021 .
↑ Calculus Vol. 1 (2nd ed.) . به کوشش Tom M. Apostol.
تئوری گونههای تعویضی گونههای انتخابی گونههای درجی گونههای ادغامی گونههای توزیعی گونههای همرو گونههای دوگانه گونههای دیگر