الگوریتم
Algorithmالگوریتم دنبالهای متناهی از گامهای دقیق و بدون ابهام است که مسئلهای را حل میکند. الگوریتم مستقل از زبان برنامهنویسی است: یک الگوریتم واحد را میتوان در هر زبانی پیاده کرد، درست مثل دستور پختی که با هر اجاقی قابل اجراست.
ویژگیهای یک الگوریتم درست
هر دنبالهای از دستورها الگوریتم نیست. پنج شرط لازم است:
- ورودی مشخص. صفر یا چند ورودی معین دارد.
- خروجی مشخص. دستکم یک نتیجه تولید میکند.
- قطعیت. هر گام باید دقیق و بدون ابهام باشد. «کمی نمک اضافه کن» الگوریتم نیست؛ «۵ گرم نمک اضافه کن» هست.
- پایانپذیری. باید پس از تعداد متناهی گام تمام شود. برنامهای که در حلقهٔ بیپایان گیر میکند، الگوریتم معتبری را پیاده نکرده است.
- کارایی. باید با منابع معقول قابل اجرا باشد. راهحلی که هزار سال طول بکشد، از نظر عملی بیفایده است.
الگوریتم ایده و روش است؛ برنامه پیادهسازی آن در یک زبان مشخص. الگوریتم را میتوان روی کاغذ و با فارسی ساده نوشت. به همین دلیل در آموزش، ابتدا الگوریتم طراحی میشود و سپس کد نوشته میشود.
چطور نمایش داده میشود؟
سه روش متداول:
- زبان طبیعی. توصیف گامها به فارسی یا هر زبان دیگر. ساده اما مستعد ابهام.
- فلوچارت. نمایش تصویری با شکلهای استاندارد. برای دیدن مسیرهای مختلف اجرا عالی است.
- شبهکد. چیزی میان زبان طبیعی و کد واقعی؛ ساختار برنامهنویسی دارد اما به هیچ زبان خاصی وابسته نیست. رایجترین روش در متون تخصصی.
یک مثال ساده — یافتن بزرگترین عدد در فهرست:
- اولین عدد را بهعنوان «بزرگترین» در نظر بگیر.
- برای هر عدد بعدی در فهرست، آن را با «بزرگترین» مقایسه کن.
- اگر بزرگتر بود، آن را جایگزین «بزرگترین» کن.
- وقتی فهرست تمام شد، «بزرگترین» را برگردان.
این الگوریتم را میتوانید در هر زبانی پیاده کنید؛ منطقش تغییر نمیکند.
پیچیدگی: چرا بعضی راهحلها بهترند؟
برای یک مسئله معمولاً چند الگوریتم وجود دارد. معیار مقایسه، پیچیدگی است: اینکه با بزرگترشدن ورودی، زمان یا حافظهٔ لازم چقدر رشد میکند.
این رشد با نمادی به نام O بزرگ توصیف میشود:
| نماد | یعنی چه | نمونه |
|---|---|---|
| O(1) | زمان ثابت، مستقل از اندازهٔ ورودی | خواندن عنصر اول یک فهرست |
| O(log n) | رشد بسیار کند | جستوجوی دودویی در فهرست مرتب |
| O(n) | متناسب با اندازهٔ ورودی | بررسی تکتک عناصر |
| O(n²) | رشد سریع | مقایسهٔ هر عنصر با همهٔ عناصر دیگر |
| O(2ⁿ) | عملاً غیرقابل استفاده در مقیاس بزرگ | بررسی همهٔ ترکیبهای ممکن |
چرا این مهم است؟ با ده عنصر، تفاوت اینها ناچیز است. با یک میلیون عنصر، یکی در کسری از ثانیه تمام میشود و دیگری عملاً هرگز. طراحی الگوریتم درست، اغلب تفاوت میان «کار میکند» و «کار نمیکند» است — نه صرفاً یک بهینهسازی جزئی.
الگوریتم در زندگی روزمره
این مفهوم منحصر به کامپیوتر نیست:
- دستور پخت غذا
- راهنمای نصب یک وسیله
- روالی که برای مرتبکردن کشوی لباس دارید
- مسیری که هر روز برای رسیدن به محل کار انتخاب میکنید
همچنین الگوریتمهایی که بیآنکه بدانید بر زندگیتان اثر میگذارند: ترتیب محتوایی که در شبکههای اجتماعی میبینید، تصمیم بانک دربارهٔ وام شما، و مسیری که اپلیکیشن نقشه پیشنهاد میدهد.
الگوریتم بهخودیخود بیطرف است، اما انتخاب اینکه چه چیزی بهینه شود، یک تصمیم انسانی است. سامانهای که «زمان تماشا» را بیشینه میکند، رفتار متفاوتی از سامانهای دارد که «رضایت کاربر» را هدف گرفته است. برای الگوریتمهای یادگیرنده، این موضوع اهمیت دوچندان پیدا میکند.
پرسشهای متداول دربارهٔ الگوریتم
تفاوت الگوریتم و کد چیست؟
الگوریتم روش حل مسئله است و مستقل از زبان؛ کد پیادهسازی آن روش در یک زبان مشخص. یک الگوریتم واحد میتواند صدها پیادهسازی متفاوت داشته باشد که همه یک کار را میکنند.
آیا باید الگوریتمها را حفظ کنم؟
حفظکردن مفید نیست؛ فهمیدن منطق آنها مهم است. در عمل، بیشتر الگوریتمهای استاندارد در کتابخانههای زبانها پیاده شدهاند. آنچه ارزش دارد، توانایی تشخیص این است که کدام رویکرد برای مسئلهٔ شما مناسب است و چرا.
منظور از «الگوریتم اینستاگرام» چیست؟
سامانهٔ رتبهبندی محتوا که تعیین میکند چه چیزی و به چه ترتیبی به شما نشان داده شود. این در واقع مجموعهای از مدلهای یادگیری ماشین است، نه یک الگوریتم ساده. وقتی میگویند «الگوریتم تغییر کرد»، معمولاً یعنی معیار بهینهسازی یا وزن سیگنالها عوض شده است.
اصطلاحات همخانوادهٔ مفاهیم پایه برنامهنویسی
مشاهدهٔ همه ←- برنامهنویسیبرنامهنویسی یعنی تبدیل یک راهحل به دنبالهای از دستورهای دقیق که کامپیوتر بتواند اجرا کند. نکتهای که اغلب نادیده گرفته میشود: بخش سخت برنامهنویسی نوشتن کد نیست، بلکه فهمیدن دقیق مسئله و طراحی راهحل است.
- فلوچارتفلوچارت یا نمودار گردش کار، نمایش تصویری یک فرایند یا الگوریتم با شکلهای استاندارد است. هر شکل معنای مشخصی دارد و فلشها مسیر اجرا را نشان میدهند. کاربردش فراتر از برنامهنویسی است و در طراحی هر فرایندی به کار میآید.
- متغیرمتغیر نامی است که به یک مقدار در حافظه اشاره میکند. بهجای اینکه با آدرسهای عددی حافظه کار کنید، به مقدار نامی معنادار میدهید و از آن پس با همان نام به آن دسترسی دارید.
- تابعتابع بلوکی نامدار از کد است که یک کار مشخص انجام میدهد و میتوان آن را بارها فراخوانی کرد. تابع معمولاً ورودی میگیرد، پردازشی انجام میدهد و خروجی برمیگرداند — و مهمتر از همه، از تکرار کد جلوگیری میکند.
- کلاسکلاس نقشه یا قالبی است که تعیین میکند یک نوع شیء چه ویژگیهایی دارد و چه کارهایی میتواند انجام دهد. از روی یک کلاس میتوان بینهایت شیء ساخت که هر کدام دادههای خودشان را دارند اما رفتار مشترکی نشان میدهند.
- شیگرایی OOPشیگرایی سبکی از برنامهنویسی است که در آن برنامه از مجموعهای از اشیاء ساخته میشود؛ هر شیء دادههای خودش را نگه میدارد و رفتارهای مربوط به آن دادهها را انجام میدهد. هدف اصلیاش مدیریت پیچیدگی در نرمافزارهای بزرگ است.
برای درک کاملتر، اینها را هم بخوانید
- فلوچارتفلوچارت یا نمودار گردش کار، نمایش تصویری یک فرایند یا الگوریتم با شکلهای استاندارد است. هر شکل معنای مشخصی دارد و فلشها مسیر اجرا را نشان میدهند. کاربردش فراتر از برنامهنویسی است و در طراحی هر فرایندی به کار میآید.
- برنامهنویسیبرنامهنویسی یعنی تبدیل یک راهحل به دنبالهای از دستورهای دقیق که کامپیوتر بتواند اجرا کند. نکتهای که اغلب نادیده گرفته میشود: بخش سخت برنامهنویسی نوشتن کد نیست، بلکه فهمیدن دقیق مسئله و طراحی راهحل است.
- تابعتابع بلوکی نامدار از کد است که یک کار مشخص انجام میدهد و میتوان آن را بارها فراخوانی کرد. تابع معمولاً ورودی میگیرد، پردازشی انجام میدهد و خروجی برمیگرداند — و مهمتر از همه، از تکرار کد جلوگیری میکند.