الگوریتم ابزاری است که از آن برای حل‌مسئله استفاده می‌شود. گاهی‌اوقات بیش از یک الگوریتم برای حل یک مسئله وجود دارد؛ بنابراین بهینه بودن ابزارها حایز اهمیت است. مهم‌ترین پارامترهای بهینگی یک الگوریتم، میزان حافظه و زمانی است که برای اجرا مصرف می‌کند و این دو پارامتر، معیارهایی برای سنجش کارایی الگوریتم هستند. در این مقاله به تحلیل‌زمانی الگوریتم‌ها می‌پردازیم. یکی از روش‌های تحلیل‌زمانی الگوریتم بررسی زمان اجرا در بدترین‌حالت و حالت‌میانگین
می‌باشد. توجه کنید که بهترین زمان اجرای الگوریتم اهمیت چندانی ندارد، چرا که این حالت معمولاً برای ورودی با تعداد کم و در شرایط خاص اتفاق می‌افتد و زمان اجرا هم اغلب آنقدر کوتاه است که مهم نیست از چه الگوریتمی استفاده می‌شود.
بعضی مواقع پیچیدگی (منظور از پیچیدگی، تابعی است برحسب اندازه ورودی که زمان اجرای الگوریتم را بیان می‌کند. در ادامه بحث به چگونگی محاسبهٔ آن خواهیم‌پرداخت)
حالت‌میانگین و بدترین‌حالت با یکدیگر تفاوت چندانی نمی‌کند اما معمولاً پیچیدگی الگوریتم در حالت‌میانگین بهتر از پیچیدگی آن در بدترین‌حالت است؛ چراکه اغلب بدترین‌حالت الگوریتم به‌ندرت اتفاق می‌افتد. از این رو پیچیدگی حالت‌میانگین الگوریتم‌ها همان رفتار مورد انتظار ماست.
با استفاده از پیچیدگی الگوریتم‌ها، می‌توانیم آن‌ها را از نظر میزان کارایی با یکدیگر مقایسه کنیم. برای مثال، زمان اجرای الگوریتم‌های مرتب‌سازی ادغامی و مرتب‌سازی درجی
را مقایسه می‌کنیم. می‌دانیم الگوریتم مرتب‌سازی ادغامی از مرتبه‌ی(O(log n
و الگوریتم مرتب‌سازی درجی از مرتبهn^2
می‌باشد. همان‌طور که مشاهده می‌شود، برای مقادیر کوچک مانند ۱ یا ۲ الگوریتم مرتب‌سازی درجی سریع‌تر از الگوریتم مرتب‌سازی ادغامی عمل می‌کند اما هرچه مقدار n افزایش می‌یابد، الگوریتم مرتب‌سازی ادغامی بسیار سریع‌تر از الگوریتم مرتب‌سازی درجی عمل می‌کند؛ بنابراین از آنجا که اغلب برای ورودی‌های خیلی بزرگ از الگوریتم‌ها استفاده می‌کنیم، به تحلیل الگوریتم‌ها برای nهای بزرگ می‌پردازیم.
در این مقاله سعی شده تا روش‌هایی برای مقایسه زمان اجرای الگوریتم‌ها بیان کنیم تا به درک روشنی از میزان بهینه بودن آن‌ها برسیم. در ابتدا به معرفی علایم قراردادی پرداخته سپس مفاهیم، تعاریف و مثال‌هایی از آن‌ها بیان می‌کنیم.

علایمی که ما از آن‌ها برای نشان دادن کران‌های مجانبی استفاده می‌کنیم، معرف توابعی هستند که به آنها توابع رشدمی‌گوییم و دامنه آن‌ها مجموعه‌ای از اعداد طبیعی است.
این علایم عبارت‌اند از:

{\displaystyle \mathrm {O} } : کران بالای مجانبی

{\displaystyle {\Omega }} : کران پایین مجانبی

{\displaystyle {\theta }} : کران دوطرف مجانبی

نماد {\displaystyle \mathrm {O} }
تعریف ریاضیاتی این نماد به شکل زیر می‌باشد:

{\displaystyle \mathrm {O} (g(n))=f(n):\exists \;c,n\_{0}>0:0<f(n)<cg(n),\forall \;n>n\_{0}}

یعنی آهنگ رشد تابع (g(n برای مقادیر بزرگ n، بیشتر یا مساوی آهنگ رشد تابع (f(nاست. در این‌صورت می‌گوییم(g(n کران بالای مجانبی برای (f(nاست.

به‌طور مثال:

{\displaystyle n^{2}=\mathrm {O} (n^{2})}

{\displaystyle n\log {n}=\mathrm {O} (n^{2})}
{\displaystyle nlogn=O(n^{2})}

نکته: منظور از{\displaystyle f=\mathrm {O} (g(n))} در واقع
{\displaystyle f\in \mathrm {O} (g(n))}
است.

نماد {\displaystyle {\Omega }}
تعریف ریاضیاتی این علامت به شکل زیر می‌باشد که در آن تابع(g(nکران پایین مجانبی برای تابع (f(nاست.

{\displaystyle {\Omega }(g(n))=f(n):\exists \;c,n\_{0}>0:0<cg(n)<f(n),\ \forall \;n>n\_{0}}

به‌طور مثال:

{\displaystyle {\sqrt {n}}={\Omega }(logn)}

{\displaystyle n^{3}={\Omega }(n^{2})}

نماد {\displaystyle {\theta }}
بیانگر کران دوطرف مجانبی است که به صورت زیر تعریف می‌شود:

{\displaystyle {\theta }(g(n))=f(n):\exists \;c\_{1}\ ,c\_{2}\ ,\ n\_{0}>0:0<c\_{1}g(n)<f(n)<c\_{2}g(n),\ \forall \;n>n\_{0}}

این رابطه بدین معنی است که آهنگ رشدf و g برای مقادیر یزرگ n یکسان است و هیچ‌یک از این دو تابع از دیگری جلو نمی‌زنند.

به‌طور مثال زمان اجرای مرتب‌سازی درجی
{\displaystyle an^{2}+bn+c}
است؛ بنابراین،
{\displaystyle T(n)=\theta (n^{2})}،
زیرا می‌توان به‌سادگی مقادیر مثبتی برای
{\displaystyle c\_{1}}
و
{\displaystyle c\_{2}}
یافت که
{\displaystyle c\_{1}n^{2}<an^{2}+bn+c<c\_{2}n^{2}}.

مثال:
ثابت کنید که
{\displaystyle 100n^{2}+5n-4\neq \theta (n^{3})}

اثبات:
باید نشان داد که نمی‌توان مقادیر مثبتی برای
{\displaystyle c\_{1}}
،
{\displaystyle c\_{2}}
و
{\displaystyle n\_{0}}
یافت که رابطهٔ
{\displaystyle c\_{1}n^{3}<100n^{2}+5n-4<c\_{2}n^{3}}
برای همه مقادیر
{\displaystyle n>n\_{0}}
برقرار باشد. به‌وضوح به ازای هر مقدار
{\displaystyle c\_{1}>0}
و برای مقادیر بزرگ n
{\displaystyle c\_{1}n^{3}\nleq 100n^{2}+5n-4}.

لم:
یک تابع چندجمله‌ای، از مرتبهٔ دقیق جملهٔ با بزرگترین توانش است. یعنی با فرض k>0 و{\displaystyle a\_{k}>0} داریم:

{\displaystyle a\_{k}n^{k}+a\_{k-1}n^{k-1}+...={\theta }(n^{k})}

نکته:
طبق تعریف،
{\displaystyle {\theta }(g(n))\subseteq {\mathrm {O} }(g(n))}.

همچنین تابع{\displaystyle {\theta }} در واقع عطف O و{\displaystyle {\Omega }} است به عبارت دیگر،

قضیه:شرط لازم و کافی برای
{\displaystyle f(n)={\theta }(g(n))}
آن است که
{\displaystyle f(n)=\mathrm {O} (g(n))}
و
{\displaystyle f(n)={\Omega }(g(n))}.

خواص توابع رشد
--------------

### خاصیت تراگذاری

تابع‌های رشد تعریف شده خاصیت تراگذاری دارند.

از{\displaystyle f(n)={\theta }(g(n))} و{\displaystyle g(n)={\theta }(h(n))} نتیجه می‌شود{\displaystyle f(n)={\theta }(h(n))}.

از{\displaystyle f(n)=\mathrm {O} (g(n))} و{\displaystyle g(n)=\mathrm {O} (h(n))} نتیجه می‌شود{\displaystyle f(n)=\mathrm {O} (h(n))}.

از{\displaystyle f(n)=\Omega (g(n))} و{\displaystyle g(n)=\Omega (h(n))} نتیجه می‌شود{\displaystyle f(n)={\Omega }(h(n))}.

### خاصیت بازتابی

تابع‌های رشد تعریف شده خاصیت بازتابی دارند.

{\displaystyle f(n)={\theta }(f(n))}

{\displaystyle f(n)=\mathrm {O} (f(n))}

{\displaystyle f(n)={\Omega }(f(n))}

### خاصیت تقارنی

تابع رشد{\displaystyle {\theta }} خاصیت تقارنی دارد.

{\displaystyle f(n)={\theta }(g(n))}
اگر و تنها اگر
{\displaystyle g(n)={\theta }(f(n))}.

### خاصیت تقارنی ترانهاده

در تابع‌های رشد تعریف شده خاصیت تقارنی‌ترانهاده به‌صورت زیر وجود دارد:

شرط لازم و کافی برای
{\displaystyle f(n)=\mathrm {O} (g(n))}
آن است که
{\displaystyle g(n)={\Omega }(f(n))}.

منابع
-----

* Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,Clifford Stein، *(Introduction to Algorithms(3rd.Edition*نگهداری یادکرد:نام‌های متعدد:فهرست نویسندگان (رده)
* محمد قدسی، *داده ساختارها و مبانی الگوریتم‌ها*