برنامهنویسان قدیمی دنیای فناوری اطلاعات در ایران و خارج از ایران به این نکته اذعان دارند که یک برنامهنویس خوب فردی است که آشنایی کامل با مباحث فلوچارتسازی و الگوریتمنویسی دارد. اگر سابقه کار چند ساله در این زمینه دارید، به خوبی میدانید که فلوچارتها روند ساخت الگوریتمها را تسهیل میکنند و الگوریتمها روند کدنویسی را ساده میکنند. بزرگترین مزیت فلوچارتها و الگوریتمها مستقل بودن آنها است. شما میتوانید الگوریتمهایی بنویسید که امکان پیادهسازی آنها در زبانهای مختلف وجود داشته باشد، زیرا قرار نیست در الگوریتمها از کدهای یک زبان خاص استفاده کنید، بلکه هدف نشان دادن مراحل انجام یک کار است.
خوشبختانه مبحث، الگوریتمنویسی در بیشتر سرفصلهای رشتههای علوم کامپیوتر مثل کارشناسی ارشد هوش مصنوعی در دانشگاههای ایران مورد توجه قرار میگیرد، اما در بخش خصوصی تنها تعداد کمی از آموزشگاهها این مبحث را به طور جدی دنبال میکنند. اگر دوست دارید به عنوان یک توسعهدهنده نرمافزار شغل پردرآمدی پیدا کنید یا متخصص فناوری اطلاعاتی هستید که دوست دارد روند انجام برخی کارهای تکراری را خودکارسازی کند، در هر دو حالت باید با اصول کدنویسی درست آشنا باشید. در این مقاله به این پرسش پاسخ خواهیم داد که الگوریتم چیست و چه نقشی در دنیای برنامهنویسی دارند.
الگوریتم به چه معنا است؟
در سادهترین تعریف، الگوریتم (Algorithm) یک فرآیند گام به گام برای حل یک مسئله محاسباتی است. ما همیشه باید فرض کنیم کامپیوترها و تجهیزات الکترونیکی دارای حافظه، دوستانی با ضریب هوشی کم هستند که برای انجام درست وظایف به توجه بیشتری نیاز دارند. در هنگام کدنویسی، اگر قواعد و اصول کدنویسی را رعایت نکنید، مفسر یا کامپایلر با نمایش پیغام خطایی این مورد را به شما گوشزد میکند. به طور کلی، الگوریتم به مجموعه دستوراتی اشاره دارد که برای انجام محاسبات یا انجام عملیات خاصی باید توسط برنامه کاربردی دنبال شود.
با این توصیف، الگوریتم را باید مجموعه محدودی از دستورالعملها توصیف کنیم که ترتیب خاصی دارند و قرار است کار خاصی انجام دهند. الگوریتم به عنوان یک توصیف غیررسمی در قالب یک نمودار جریانی یا شبه کد ارائه میشود. در اینجا چند اصطلاح مهم مرتبط با الگوریتمها وجود دارد که باید به آنها دقت کنید.
- مسئله: یک مسئله را میتوان به عنوان یک مشکل در دنیای واقعی در نظر گرفت که برای آن باید یک برنامه یا مجموعهای از دستورالعملها نوشته شود. در نتیجه الگوریتم مجموعهای از دستورالعملها است.
- الگوریتم: الگوریتم به عنوان یک فرآیند گام به گام تعریف میشود که برای یک مسئله طراحی میشود.
- ورودی: پس از طراحی یک الگوریتم، ورودیهای لازم و مورد نظر به الگوریتم داده میشود.
- واحد پردازش: ورودی به واحد پردازش ارسال میشود تا خروجی مطابق با انتظار را تولید کند.
- خروجی: به نتیجه اجرای یک برنامه، خروجی گفته میشود.
نکتهای که باید در این زمینه به آن دقت کنید این است که کدنویسی یک فرآیند مهندسی گام به گام و مرحله به مرحله است. فرآیندی که در نهایت به این پرسش بنیادین میرسد که یک برنامه چیست؟ برنامه یک روش گام به گام برای حل یک مشکل است. شاید در نگاه اول، همه چیز سخت یا پیچیده به نظر برسد، اما هنگامی که به وارد برنامهنویسی شوید مشاهده خواهید کرد که همه چیز مفرح و جذاب است. اما قبل از پرداختن به این موضوع اجازه دهید به تفاوتهای میان یک برنامه کاربردی و الگوریتم نگاهی داشته باشیم.
تفاوتهای میان یک برنامه کاربردی و الگوریتم
1. الگوریتمها در مرحله طراحی نوشته می شوند: در فرآیند توسعه نرمافزار مرحله مهمی به نام طراحی و پیادهسازی وجود دارد. در مرحله طراحی، ما مشکل تجاری را به بخشهای کوچکی تقسیم میکنیم و برای هر یک از آنها الگوریتمهایی مینویسیم. اینکار با هدف درک بهتر منطق تجاری انجام میشود و به ما در انجام کارهایی که قرار است انجام دهیم کمک میکند.
برنامه ها در مرحله اجرا نوشته می شوند: هنگامیکه شناخت درستی از مشکل تجاری به دست آوردیم و آن را به الگوریتم تبدیل کردیم، این توانایی را داریم تا فرآیند کدنویسی بر مبنای الگوریتم را آغاز کنیم و الگوریتم را به یک برنامه کاربردی تبدیل کنیم.
2. الگوریتمها مستقل از سینتکس (Syntax) زبان برنامه نویسی هدف هستند: هنگام الگوریتمنویسی، ضرورتی ندارد از ویژگیهای زبان برنامهنویسی انتخابی استفاده کنیم، مهم این است که ترکیبی ساده از نمادهای ریاضی و انگلیسی (یا فارسی) را برای تشریح مشکل انتخاب کنیم.
برنامهها بر مبنای سینتکس زبان برنامه نویسی هدف نوشته میشوند: هنگامی که قصد ساخت برنامههای کاربردی با استفاده از یک زبان برنامهنویسی را داریم، باید حتما اصول زبان برنامهنویسی هدف را رعایت کنیم تا کامپایلر یا مفسر پیغام خطایی صادر نکند. به این اصول برنامهنویسی سینتکس گفته میشود. هر زبان برنامهنویسی قواعد مخصوص خود را دارد که به عنوان گرامر آن زبان شناخته میشود. اگر هنگام تعامل با مفسر و کامپایلر قواعد گرامری را زیرپا بگذارید، پیغام خطایی دریافت میکنید، زیرا کامپایلر شناختی از شما و کاری که انجام میدهید در اختیار ندارد.
3. الگوریتمها مستقل از سختافزار هستند: ما میتوانیم الگوریتمها را در هر مکانی روی یک تخته سفید یا در محیط ورد بنویسیم. برنامهنویسانی که تجربه مصاحبه برای ورود به تیمهای بزرگ را دارند، به خوبی میدانند در بیشتر موارد وایتبردی برای سنجش اطلاعات تخصصی داوطلبان در اتاق مصاحبه قرار دارد و از داوطلب خواسته میشود، برای مسئلهای که در اختیارش قرار میگیرد، الگوریتمی بنویسد. در نقطه مقابل، برنامهها با استفاده از محیطهای توسعه یکپارچه (IDE) نوشته میشوند.
برنامه ها به سختافزار وابسته هستند: هنگامی که در مرحله پیادهسازی هستیم، باید توانایی تعامل با سیستم را داشته باشیم تا بتوانیم برنامه کاربردی را به درستی توسعه داده و مشکل را از طریق خودکارسازی فرآیند تجاری حل کنیم. از هر 10 مشکل تجاری، ما قادر به حل 9 مورد از آنها هستیم. بهترین مثال در این زمینه یک سیستم توصیهگر (recommender system) است که نزدیک به چند دهه است توسط فروشگاههای آنلاین یا استریمهای پخش فیلم توصیههایی به کاربران ارائه میکنند. به طور کلی، باید به این نکته اشاره کنیم که یک سیستم توصیهگر بر مبنای زبان پردازش طبیعی (NLP) که یکی از زیرشاخههای هوش مصنوعی است، بر مبنای تاریخچه بازدیدها یا خریدهای کاربران اقلامی که تصور میکند ممکن است به آنها علاقه داشته باشند را پیشنهاد میکند.
آمارها نشان میدهند، ماشینها در این زمینه عملکردی بهتر از ما دارند، زیرا مدام در حال یادگیری هستند و بر مبنای الگوریتمهای یادگیری ماشین (Machine Learning) و کلان دادهها (Big Data) دانش خود را ارتقا میدهند و از تجربیات قبلی برای انجام بهتر کارهای آتی استفاده میکنند. البته انسانها نیز مستقیم یا غیر مستقیم در حال یادگیری هستند، هنگامی که خواب هستید، مغزتان موضوعاتی که در طول روز در حال یادگیری آنها بودهاید را مرور میکند، هنگامی که سرگرم تماشای یک برنامه سرگرمکننده هستید ناخودآگاه در حال یادگیری نکاتی هستید، هنگامی که کار سرگرمکنندهای انجام میدهید، بازهم در حال یادگیری هستید. در حالت کلی، ماشینها در انجام برخی کارها بهتر از ما عمل میکنند، به ویژه هنگامی که صحبت از انجام کارهای تکراری یا یکنواخت به میان میآید.
4. الگوریتمها تجزیه و تحلیل میشوند: در علوم کامپیوتر و به ویژه درس ساختمان دادهها، مبحث مهمی به نام پیچیدگی مکانی و زمانی داریم که اشاره به محاسبات ریاضی دارد که نشان میدهند بازدهی یک الگوریتم به چه صورتی است. این تحلیلها به ما اعلام میدارند، الگوریتم به چه میزان حافظه اصلی و چه مدت زمانی برای حل یک مسئله نیاز دارد.
برنامهها تجزیه و تحلیل نمیشوند: در مرحله پیادهسازی و استقرار تنها برنامه را آزمایش کنیم، زیرا فرآیند تجزیه و تحلیل هنگام الگوریتمنویسی انجام شده است. لازم به توضیح است، هنگامی که برنامهای در محیط تولیدی مستقر میشود از طریق آزمایشهای آلفا و بتا تنها قادر به شناسایی باگهایی هستیم که بهنام خطاهای منطقی شناخته میشوند.
ویژگیهای یک الگوریتم
هر الگوریتم به دلیل مشخصی نوشته میشود و به دنبال حل یک مشکل به روشی بهینه و مقرون به صرفه است، اما در حالت کلی، الگوریتمها یکسری ویژگیهای مشترک دارند که به شرح زیر است:
اکثر الگوریتمها یک خروجی تولید میکنند.
به طور کلی، در مبحث الگوریتمنویسی و توسعه برنامههای کاربردی موضوعی به نام فرمولهسازی مسئله داریم. فرمولهسازی به مجموعه فعالیتها و حالتهایی اشاره دارد که با استفاده از آنها به هدفی میرسیم. به بیان ساده، فرمولهسازی با هدف درک یک مسئله انجام میشود. فرض کنید قصد نوشتن الگوریتمی داریم که باید یک رشته را به عنوان ورودی دریافت کند، آنرا معکوس کند و در نهایت همه حروف آنرا کوچک کند. بهطور مثال، رشتهای مثل "Thenjiwe" داریم که باید به "Ewijneht" تبدیل شود و در ادامه همه حروف آن کوچک شوند. در اینجا رشته ewijneht خروجی است که انتظار داریم الگوریتم در اختیار ما قرار دهد.
الگوریتمها باید واضح باشند.
ما در ابتدای کار باید درک کنیم که قصد حل چه مشکل یا مشکلاتی را داریم. آیا باید کاراکترهایی را معکوس کنیم، کاراکترهای تکراری را بررسی میکنیم، کوتاهترین مسیر را برای یک مکان پیدا میکنیم و غیره؟
الگوریتمها باید در نقطهای به پایان برسند.
الگوریتمها باید نقطه شروع و پایان داشته باشند. به طوری که با یک دستورالعمل خاص شروع شوند و با یک دستورالعمل خاص خاتمه پیدا کنند. علاوه بر این مدت زمان یک الگوریتم باید محدود باشد. یکی از بزرگترین مشکلاتی که برنامهنویسان تازهکار هنگام نوشتن الگوریتمها با آن روبرو هستند، مشکل حلقه بی پایان یا عدم وجود شرطی است که حلقه را پایان دهد.
الگوریتمها باید موثر باشند.
الگوریتمی که مینویسید باید به تشریح مراحل قابل اجرا در برنامهنویسی اشاره داشته باشد. به بیان دقیقتر، لزومی ندارد، مقابل هر یک از خطوط الگوریتم توضیحات اضافی درج کنید که سودی ندارند. الگوریتم باید کوتاهترین راهکار برای کدنویسی را ارائه کند تا برنامهای که نوشته میشود به شکل بهینه از منابع سیستمی استفاده کند.
یک الگوریتم چه ویژگیهای شاخصی دارد؟
درست به همان ترتیبی که برای طبخ غذا تنها به دستورالعمل استاندارد استناد میکنید، اما گاهی اوقات برای طعمدهی بهتر از چاشنیهای خاصی استفاده میکنید، همین قاعده در الگوریتمنویسی و برنامهنویسی صادق است. به طور مشابه، دستورالعملهایی برای ساخت یک برنامه کاربردی در الگوریتمها شرح داده میشوند، اما قرار نیست برنامهنویس بدون هیچگونه تغییری از آنها استفاده کند. گاهی اوقات، شرایط ایجاد میکند، تغییراتی اعمال شوند تا برنامه عملکرد بهتری داشته باشد. برای این که دستورالعملهای مندرج در الگوریتم قابلیت اجرایی داشته باشند، باید ویژگیهای زیر را داشته باشند:
- واضح و بدون ابهام باشند: الگوریتم باید واضح و بدون ابهام باشد. هر یک از مراحل آن باید از همه جهات روشن باشد و فقط به یک معنا منتهی شود.
- ورودیها به درستی تعریف شده باشند: اگر الگوریتمی میگوید ورودیها را بگیرید، باید ورودیها به وضوح تعریف شده باشند.
- خروجیهای خوب تعریف شده داشته باشد: الگوریتم باید به وضوح مشخص کند، خروجی چیست و باید خروجی درستی ارائه کند که مبهم نباشد. یک مثال رایج در این زمینه وجود مقادیر اعشاری در برنامههای مالی است که الگوریتم باید نحوه گرد کردن اعداد اعشاری را مشخص کند.
- محدود باشند: الگوریتم باید متناهی باشد، یعنی نباید به حلقههای نامحدود یا مشابه ختم شود.
- امکانپذیر باشند: الگوریتم باید ساده، عمومی و کاربردی باشد، به طوری که بتوان آنرا با منابع موجود پیادهسازی کرد. نباید اشاره به فناوریهای آینده یا خاصی داشته باشد که تنها روی برخی سامانهها وجود دارد.
- مستقل از زبان باشند: الگوریتم طراحیشده باید مستقل از زبان باشد، یعنی باید دستورالعملهای سادهای داشته باشد که قابلیت اجرا در هر زبان برنامهنویسی را داشته باشند و در عین حال خروجی مطابق با انتظار را ارائه کند.
الگوریتمنویسی چه مزایایی دارد؟
شاید بتوان ادعا کرد که الگوریتم تنها مفهوم دنیای برنامهنویسی یا در مقیاس کلان نرمافزار است که سرشار از مزایا است. در شرایطی که برخی برنامهنویسان، مدت زمانی که صرف نوشتن یک الگوریتم میشود و نمایش عبارات انشعابی و حلقهها در الگوریتم را از معایب این مفهوم میدانند، اما اگر نگاه عمیقی داشته باشیم، مشاهده میکنیم، مدت زمانی که صرف نوشتن الگوریتم میشود در مقایسه با مدت زمانی که صرف ویرایش ماژولهایی میشود که باید کدهای آنها بازنویسی مجدد شود کمتر است. از مهمترین مزایای الگوریتمها به موارد زیر باید اشاره کرد:
- درک آنها ساده است.
- الگوریتم به شکل دقیق تمامی مراحلی که برای حل یک مشکل باید طی شود را شرح میدهد. به بیان دقیقتر گام به گام است.
- در الگوریتم مسئله به قطعات یا مراحل کوچکتر تقسیم میشود، از اینرو، برای برنامهنویس آسانتر است که آنرا به یک برنامه واقعی تبدیل کند.
جمع بندی
در این مقاله سعی کردیم، به تشریح این مسئله بپردازیم که الگوریتم چیست و چه ویژگیهایی دارد. در ادامه به این نکته اشاره کردیم که چرا به الگوریتمها نیاز داریم، الگوریتم و برنامه چه تفاوتهایی دارند و الگوریتمنویسی چه مزایایی دارد. البته مباحث مهم دیگری در ارتباط با الگوریتمها وجود دارد که تنها اشاره کوتاهی به آنها در این مقاله داشتیم. یکی از مهمترین مباحث پیرامون الگوریتمها، پیچیدگی زمانی و تنوع آنها است.