وقتی كه با مسئلهای روبهرو میشویم، شاید راه حلهای زیادی برای حل آن مسئله موجود باشد. اما نكته اینجاست كه باید تصمیم بگیریم چه راهحلی روش بهینه حل مسئله را فراهم میكند. به این راهحل الگوریتم میگویند. طراحی و نوشتن الگوریتم یکی از تواناییهای کلیدی در حوزه مهندسی است. فرایند نوشتن الگوریتم را میتوان برای حل دامنه وسیعی از مسائل استفاده كرد، حتی مسائلی که هیچ ربطی به كامپیوتر ندارند. كامپیوترها هم همین طور هستند. باید به كامپیوترها نیز به چشم ابزاری برای حل مسئله نگاه كرد. در این مطلب از مجله فرادرس، به آموزش اصول پایهای برای توسعه راهحل به منظور حل مسائل یا به عبارت سادهتر به آموزش نوشتن الگوریتم میپردازیم.
موضوعاتی كه در این مطلب آورده شده فقط مختص استفاده از كامپیوترها برای حل مسئله نیستند. كامپیوتر ابزاری است كه نقشه طراحی شدهمان را برای حل مسئله پیادهسازی میكند. برنامههای كامپیوتری درواقع مجموعهای از دستورالعملها هستند كه به كامپیوتر ارسال میكنیم. این دستورالعملها مراحلی را توضیح میدهند كه كامپیوتر برای پیادهسازی برنامه باید قدم به قدم طی كند. الگوریتم ها نیز همچنین، برنامهای برای حل مسائل ارائه میدهند. الگوریتمها را انسانها طراحی و سپس به برنامههای كامپیوتری ترجمه میكنند. پردازش پایه بسیار مهم است زیرا این پردازش برای حل طیف گستردهای از مسائل قابل استفاده است. از روی این اصول پایه پردازشی میتوان الگوریتم نوشته شده را در زبان های برنامه نویسی مختلف پیادهسازی كرد.
دلیل نوشتن الگوریتم چیست؟
استفاده از الگوریتمها به دلایل مختلفی ضروری است. در این بخش سه مورد از مهمترین این دلایل را فهرست کردهایم.
- افزایش «پویایی و کارایی» (Automation and Efficiency): الگوریتمها فرایندهای کاری را خودکار و ساده میکنند. پایداری و سرعت عملیاتها را ارتقا میبخشند و باعث سادگی اجرای کار میشوند.
- انجام وظایف پیچیده: الگوریتمها برای مدیریت وظایف غیرعملی یا انجام کارهایی که انسان نمیتواند به صورت دستی انجام دهد کامپیوترها را تقویت میکنند.
- «انجام عملیات چندرشتهای» (Cross-Disciplinary Applications): الگوریتمها کاربردهای خاص خود را در رشتههای مختلفی مانند ریاضیات، مهندسی، علوم کامپیوتر، بازارهای مالی و غیره پیدا کردهاند. الگوریتمها مسئولیتهایی مانند بهینهسازی پردازشها، تجزیه و تحلیل دادهها، پیشبینی بعضی از رخدادها و پیشنهاد راهحلهای مختلف برای حل مسئله را برعهده میگیرند.
عناصر کلیدی نوشتن الگوریتم
در این بخش عناصر کلیدی که در هر نوع ممکن از فرایند نوشتن الگوریتم باید در نظر داشت را فهرست کردهایم.
- ورودی: الگوریتمها به طور معمول با دادههای ورودی شروع میکنند. دادههای ورودی، اطلاعاتی هستند که الگوریتم آنها را پردازش میکند و بر اساس آنها کار انجام میدهد.
- پردازش: این قسمت قلب الگوریتم است. در این بخش توالی از مراحل که به خوبی طراحی شدهاند برای گرفتن نتیجه مطلوب از دادههای ورودی بهکار برده میشوند. با طی کردن این توالی عملیات در نهایت مسئله حل میشود.
- خروجی: نتیجه نهایی یا خروجی الگوریتم برپایه دادههای ورودی و مراحل پردازشی تولید شده است.
تسلط به مبحث طراحی الگوریتم با فرادرس
طراحی الگوریتم یکی از مباحث بسیار پایه علوم کامپیوتری است. البته که این شاخه از دانش، کاربردهای بسیار گستردهتری نسبت به علوم کامپیوتری دارد. اما فرادرس با تاکید بر بخش کامپیوتری این علم به تولید فیلمهای آموزشی مناسب کار مهندسین کامپیوتر و حتی آمادگی جهت شرکت در آزمونهای دانشگاهی پرداخته است. این شاخه از علم در علوم کامپیوتر رابطه نزدیک و تنگاتنگی با برنامهنویسی و ساختمان داده دارد. به همین منظور در فرادرس با نگرش برنامه نویسی به تهیه فیلمهای آموزشی طراحی الگوریتمها و ساختمان داده پرداختهایم.
در این بخش چند فیلم آموزشی در ارتباط با طراحی الگوریتم و ساختمان داده را معرفی کردهایم. تسلط به این مبحث یکی از تخصصهای حرفهای برنامهنویسان و مهندسین نرم افزار است. در صورت نیاز با کلیک بر روی تصویر بالا میتوانید وارد صفحه اصلی این مجموعه آموزش شده و از فیلمهای آموزشی بیشتری استفاده کنید.
فرایند نوشتن الگوریتم چیست؟
راه حل همه مسائل با نقشه اولیهای شروع میشود. به این نقشه اولیه، الگوریتم میگویند. در واقع الگوریتم نقشهای است كه برای حل كردن مسئله خاصی طرح ریزی شده است.
روشهای بسیار زیادی برای نوشتن الگوریتم وجود دارند. بعضی از این روشها بسیار غیرعادی هستند و بعضیها كاملا رسمی و ریاضیاند و حتی بعضی از روشها كاملا بصری هستند. دستورالعملهای اتصال دستگاه بخش DVD به تلویزیون هم نوعی الگوریتم هستند. فرمول ریاضی مانند هم مورد خاصی از الگوریتمها است. چهارچوب فرم انجام کار چندان مهم نیست مگر اینكه روش خوبی برای توضیح و بررسی منطق برنامه فراهم كند.
طراحی و توسعه الگوریتم مرحله كلیدی در حل مسئله است. همین كافی است كه الگوریتمی داشته باشیم. میتوانیم آن را به زبانهای برنامهنویسی مختلف در كامپیوتر ترجمه كنیم. فرایند توسعه الگوریتمی که در ادامه بیان خواهیم کرد، شامل پنج قدم اصلی زیر میشود.
- بدست آوردن توصیف روشنی از مسئله
- تجزیه و تحلیل کردن مسئله
- توسعه دادن الگوریتم سطح بالا برای حل مسئله
- بهینهسازی الگوریتم با اضافه کردن جزییات بیشتر
- بازبینی کردن الگوریتم و کارایی آن
در ادامه همه مراحل بالا را به طور کامل و شفاف توضیح دادهایم.
مرحله اول بدست آوردن توصیف روشنی از مسئله
این مرحله بسیار مشکلتر از آن است که نشان میدهد. در مطلب پیش رو کلمه client
اشاره به شخصی دارد که برای مسئلهای به دنبال پیداکردن راهحل میگردد و کلمه developer
اشاره به شخصی دارد که روشی را برای حل کردن مسئله پیدا میکند. در این بخش developer
باید الگوریتمی برای حل کردن مسئله مطرح شده توسط client
پیدا کند.
شخص client
مسئول تهیه توضیح مفصل و روشنی برای مسئله است. اما این بخش معمولا ضعیفترین بخش فرایند است. کاملا رایج است که در توضیح یا شرح مسئله از جهت یک یا چند مورد از نقایص زیر به مشکل بربخوریم.
- توصیف مسئله بر پایه فرضیات مبهم و غیر شفافی بنیان شده است.
- خود توصیف مسئله به صورت دو پهلو و گنگی ارائه شده است.
- شرح مسئله کامل نیست.
- شرح مسئله دارای تناتقضات درونی است.
این مشکلات خیلی بهندرت به بیتوجهی client
مربوط میشود. در عوض، بیشتر به خاطر این حقیقت که زبانهای طبیعی مانند انگلیسی، فرانسه، فارسی و غیره نسبتا غیر شفاف هستند، چنین مشکلاتی بوجود میآیند. قسمتی از مسئولیت توسعهدهندگان این است که این نواقص را در شرح مسئله شناسایی کرده و در همکاری با client
برای بر طرف کردن این نواقص چارهای بیاندیشند.
مرحله دوم تجزیه و تحلیل کردن مسئله
هدف اصلی از این مرحله تعیین نقاط شروع و پایانی فرایند حل مسئله است. این فرایند شبیه به رفتار ریاضیدانی است که تعیین میکند چه چیزی داده شده و چه چیزی باید اثبات شود. داشتن توصیف خوبی از مسئله در مرحله قبل، اجرای فرایند این مرحله را سادهتر میکند.
در زمان تعیین نقطه شروع برای حل مسئله باید با پیدا کردن جواب برای سوالات زیر کار را شروع کنیم.
- چه دادههایی در دسترس هستند؟
- این دادههای در کجا قرار دارند؟
- چه فرمولهایی به مسئله مربوط میشوند؟
- برای کار با دادهها چه قوانینی وجود دارد؟
- چه رابطهای بین مقادیر دادهها وجود دارد؟
در زمان تعیین نقطه پایانی مسئله باید ویژگیهای راهحل را مشخص کنیم. به عبارت دیگر، از کجا باید بفهمیم که کارمان چه وقتی به اتمام میرسد؟ پرسیدن سوالات زیر و تلاش برای پیدا کردن جواب مناسب برای هر کدام به پیدا کردن نقطه پایانی مسئله کمک میکند.
- به چه حقایق جدیدی دست خواهیم یافت؟
- چه آیتمهایی تغییر خواهند کرد؟
- چه تغییراتی بر روی آن آیتمها انجام خواهد شد؟
- چه چیزهایی دیگر وجود نخواهند داشت؟
مرحله سوم نوشتن الگوریتم سطح بالا برای حل مسئله
الگوریتمها نقشههایی هستند که برای حل کردن مسائل طراحی میکنیم. اما نقشهها معمولا در چند سطح مختلف از جزییات ارائه میشوند. معمولا بهتر است که با الگوریتمی سطح بالا شروع کنیم. این الگوریتم باید شامل بخشهای مهم راهحل شود و جزییات را برای بررسی بیشتر به زمان دیگری موکول کند. برای نشان دادن راهحلها و الگوریتمهای سطح بالا میتوانیم از مثالهای روزانه استفاده کنیم.
برای مثال، فرض کنیم که چنین مسئلهای برایمان مطرح شده است.
- لازم است که کارتی برای تبریک تولد به برادرم ارسال کنم.
مسئله را به این شکل تجزیه و تحلیل میکنیم.
- کارتی در اختیار ندارم. ترجیح میدهم بهجای اینکه خودم کارت تبریک تولد بسازم به فروشگاه رفته و کارتی خریداری کنم.
الگوریتم سطح بالای مسئله و راهحل ارائه شده در بالا را میتوان به صورت زیر تعریف کرد.
- به فروشگاهی میرویم که کارهای تبریک میفروشد.
- کارت مناسبی را پیدا و انتخاب میکنیم.
- کارت را میخریم.
- کارت تهیه شده را به آدرس برادرمان با پست ارسال میکنیم.
این الگوریتم برای استفاده روزانه مناسب است. اما جزئیاتی را کم دارد که اگر قرار بر انجام وظیفه توسط کامپیوتر باشد باید به کامپیوتر ارائه شوند. این جزئیات شامل پاسخهای سوالاتی مانند سوالات آمده در پایین میشوند.
- چه مغازهای را باید ببینم؟
- چطور باید به مغازه مورد نظر برسم؟ با ماشین خودم، دوچرخه، موتور، پیاده یا با خطوط حمل و نقل شهری؟
- برادرم چه نوع از کارتهایی را دوستدارد؟ خندهدار، احساساتی یا هیجانی؟
این نوع از جزییات را در مرحله بعدی از فرایند طراحی الگوریتم در نظر خواهیم گرفت.
مرحله چهارم بهینه سازی الگوریتم با اضافه کردن جزییات بیشتر
الگوریتم سطح بالا مراحل اصلی و مهمی را شامل میشوند که برای رسیدن به جواب باید طی شوند. در این بخش باید به مراحل الگوریتم سطح بالا جزئیات بیشتری اضافه کنیم. اما مهم است که بدانیم به چه میزان و اصلا چه جزئیاتی را باید اضافه کنیم. متاسفانه پاسخ این سوال وابسته به موقعیت پیشآمده است. باید در نظر بگیریم که چه کسی یا چه چیزی قرار است این الگوریتم را پیادهسازی و اجرا کند و اینکه آن شخص یا چیز ـکامپیوترـ چقدر اطلاعات از قبل درباره روش انجام این کار دارد. اگر کس دیگری از طرف ما برای خرید کارت تولد به فروشگاه میرود، لازم است که دستورالعملهای نوشته شده را در ارتباط با آن شخص بهروزرسانی کنیم. با توجه به اینکه آن شخص چقدر به فضای مسئله آگاهی دارد یا فروشگاهها را میشناسد، با شرایط پاسخ سوال یا سلیقه برادرمان برای انتخاب کارت تبریک چقدر آشنایی دارد و غیره باید دستور العمل متفاوتی را ارائه دهیم.
وقتی که هدف توسعهدادن الگوریتم برای حل مسائل برنامهنویسی باشد، معمولا این الگوریتمها توسط کامپیوترها نیز اجرا و پردازش میشوند. باید تواناییهای کامپیوتر مجری الگوریتم را در نظر بگیریم. همچنین جزئیات کافی درباره الگوریتم تهیه کنیم تا شخص دیگری بتواند از الگوریتم طراحی شده برای نوشتن برنامه کامپیوتری خود استفاده کند. این برنامه کامپیوتری باید بتواند همه مراحل تعریف شده در الگوریتم را پیادهسازی کند. مانند مسئله کارت تبریک تولد، ضروری است که سطح جزئیات را با توانایی برنامهنویس هماهنگ کنیم. زمانی که در شک یا در حال یادگیری هستید داشتن جزئیات بیشتر خیلی بهتر از کم داشتن جزئیات است.
بیشتر مثالها در این مطلب، با یک قدم از الگوریتم سطح بالا به الگوریتم آغشته به جزئیات میرسند. اما این کار همیشه منطقی نیست. برای مسائل بزرگتر و پیچیدهتر، مرسوم است که این فرایند را چندین بار تکرار میکنند. در فرایند توسعه الگوریتمهای سطح متوسط، همینطور که انجام دادیم، الگوریتم را به تدریج و رفته رفته بهینهسازی میکنند.
هربار جزئیات بیشتری را به الگوریتم اضافه میکنیم. وقتی متوجه شدیم که بازسازی بیشتر هیچ سودی ندارد اضافه کردن بازبینی دوباره الگوریتم را متوقف میکنیم. این تکنیک حرکت تدریجی از الگوریتم سطح بالا به الگوریتم شامل جزئیات را اغلب «بهینهسازی قدم به قدم» (Stepwise Refinement) مینامند.
مرحله پنجم بازبینی کردن الگوریتم و کارایی آن
مرحله نهایی بازبینی کردن الگوریتم است. مهمترین کاری که در این مرحله باید انجام شود این است که با الگوریتم کار کنیم. با الگوریتم قدم به قدم کار میکنیم تا فرایند حل مسئله را ببینیم. مهمترین سوال این است که آیا مسئله اصلی که این الگوریتم به آن منظور طراحی شده حل میشود یا نه. وقتی که از کار الگوریتم درباره ارائه راهحل برای مسئله راضی شدیم، شروع به بررسی سایر مسائل خواهیم کرد. سوالهایی که در ادامه آمدهاند، نمونهای از سوالهایی هستند که در زمان بازبینی الگوریتمها باید برایشان به دنبال پاسخ باشیم. پرسیدن این سوالات و جستوجو به دنبال پاسخ مناسب برای آنها روش خوبی برای ارتقای مهارتهای حرفهای حل مسئله است. تسلط بر مهارتهای حل مسئله شاید در برخورد با مسئله بعدی نیز کمک حال طراحان الگوریتم شود.
- آیا این الگوریتم فقط مسئله خاصی را حل میکند یا میتواند مسائل عمومیتری را نیز حل کند؟ اگر این الگوریتم فقط میتواند مسئله مشخصی را حل کند آیا لازم است که عمومیتر شود. برای مثال، الگوریتم که مساحت دایرهای با شعاع ۵٫۲ متر را محاسبه میکند -با فرمول – فقط میتواند مسائل بسیار خاص را حل کند. اما الگوریتم که مساحت هر دایرهای را با فرمول حل میکند میتواند مسائل عمومیتر یا بیشتری را حل کند.
- آیا این الگوریتم میتواند سادهتر شود؟ برای مثال، یکی از فرمولهای محاسبه محیط مستطیل برابر با فرمول (طول + عرض + طول + عرض) است. ولی میتوانیم از فرمول سادهتر به شکل ۲ * (طول + عرض) استفاده کنیم.
- آیا این راهحل شبیه به راهحل مسئله دیگری است؟ این راهحلها چقدر با هم شباهت دارند و چقدر باهم تفاوت دارند؟
برای مثال دو فرمول آمده در زیر را درنظر بگیرید.
- مساحت مستطیل = طول × عرض
- مساحت مثلث = ۰٫۵ × ضلع پایه × ارتفاع
در ادامه، موضوعات مرتبط با این راهحل را بررسی میکنیم.
- شباهتها: هر دوی این فرمولها برای محاسبه مساحت بهکار برده میشوند. هر دوی این فرمولهای دو واحد قابل اندازهگیری را در یکدیگر ضرب میکنند.
- تفاوتها: واحدهایی که اندازهگیری میشوند، با یکدیگر تفاوت دارند. فرمول مربوط به محاسبه مثلث شامل عدد ۰.۵ نیز میشود.
- فرضیه: شاید هر فرمول محاسبه مساحتی شامل عملیات ضرب بر روی دو واحد قابل اندازهگیری است.
تا اینجا مراحل پنجگانه نوشتن الگوریتم را مطالعه و بررسی کردیم. در ادامه، با چند مثال متفاوت سعی میکنیم که الگوریتم خود را در مسئلههای مختلف طراحی کنیم.
مثال اول برای نوشتن الگوریتم: بردار و بکار
این بخش شامل مثال گسترشیافتهای است که فرایند توسعه الگوریتم را نمایش میدهد. برای اینکه الگوریتم را کامل کنیم، باید بدانیم که هر کانگوریی توانایی پریدن به جلو را دارد. کانگورو میتواند به چپ یا راست بچرخد و گلی را بردارد که در موقعیت فعلی او قرار دارد. به همچنین گلی را که در اختیار دارد را نیز در موقعیت فعلیاش بکارد.
مرحله اول صورت مساله در نوشتن الگوریتم
کانگورو از نقطه (۰،۰) حرکت خود را رو به شرق شروع میکند. در ابتدای حرکت هیچ گلی در کیسه کانگورو وجود ندارد. بر روی صفحه این جزیره، گلی در موقعیت (۳،۰) وجود دارد. در این مسئله باید برنامهای بنویسیم کانگورو را به سمت گل هدایت کند، کانگورو گل را بچیند و در موقعیت (۳،۲) بکارد. بعد از کاشت گل، کانگورو باید یک قدم به سمت شرق بپرد و سپس از حرکت بایستد. در این جزیره هیچ تور، گل یا کانگورو دیگری وجود ندارد. در مسئله بعدی مانعی به نام تور بر سر راه کانگورو قرار داده شده است.
مرحله دوم تجزیه و تحلیل مسئله
در این مرحله مسئله مطرح شده را به ۴ مرحله کلی زیر تجزیه میکنیم.
- گل دقیقا در ۳ خانه جلوتر از کانگورو قرار دارد.
- گل باید دقیقا در دو خانه رو به جنوب نسبت به جایی که قرار دارد کاشته شود.
- کانگورو باید یک خانه بعد از گل کاشته شده به سمت شرق حرکت کند و در نهایت به حرکت خود پایان دهد.
- در این جزیره هیچ توری وجود ندارد که عامل نگرانی باشد.
مرحله سوم نوشتن الگوریتم سطح بالا
در این بخش برای ادامه کار کانگورو را بابی bobby
مینامیم. بابی bobby
باید کارهای زیر را انجام دهد.
- گل را بردارد.
- گل را بچیند.
- به شرق بپرد.
مرحله چهارم به الگوریتم جزئیات بیشتری اضافه شود
همانطور که در مرحله قبل قرار گذاشتیم، نام کانگورو از این به بعد بابی bobby
است. بابی bobby
باید کارهای پایین را به ترتیب انجام دهد.
- گل را بردارد
- به اندازه ۳ خانه بپرد.
- گل را بچیند.
- گل را زمین بگذارد.
- به سمت راست بچرخد و ۲ بار بپرد. سپس گل را در زمین بکارد.
- به شرق بپرد.
- به سمت چپ بچرخد و یک خانه بپرد.
مرحله پنجم بازبینی الگوریتم
در این مرحله برای بازبینی الگوریتم به سه نکته کلی توجه میکنیم.
- الگوریتم سطح بالا کل مسئله را به سه زیر مسئله نسبتا سادهتر تقسیم کرده است. این کار تکنیک بسیار خوبی برای حل همه مسائل است.
- این الگوریتم فقط مسائل بسیار خاص را میتواند حل کند. زیرا در این الگوریتم کانگورو و گل در مختصات بسیار واضح و مشخصی قرار داده شدهاند.
- در واقع با کمک این الگوریتم میتوانیم برای مشکلات نسبتا کلیتری راهحل ارائه کنیم. مثلا فرض کنیم که کانگورو در هر جایی از صفحه بتواند حرکت خود را شروع کند با این شرط که گل دقیقا سه خانه جلوتر از محل قرار گیری کانگورو باشد.
کد جاوا برای مسئله بردار و بکار
برنامه نویسهای حرفهای در ابتدای کار همه برنامه را نمینویسند. این برنامهنویسها در عوض، برنامه مورد نظرشان را در چندسری مراحل ساخت مختلف مینویسند و آزمایش میکنند. بهمرور هر مرحله ساخت را به مرحله قبلی اضافه میکنند. طراحی الگوریتم سطح بالا به برنامهنویس برای طی کردن این فرایند کمک میکند.
برنامهنویسهای حرفهای قدم به قدم کار میکنند. قطعههای کوچک را در هر مرحله کم کم به برنامه اضافه میکنند و داعما روند کار را بررسی میکنند.
اولین مرحله ساخت
برای اینکه این راهحل را در عمل ببینیم، میتوانیم سناریو جدیدی در نرمافزار «Greenfoot» ایجاد کنیم. در این نرم افزار میتوانیم از کلاس مربوط به کانگورو و جزیره برای پیادهسازی چنین مسائلی استفاده کنیم. کدهای این برنامه را با زبان برنامه نویسی جاوا پیادهسازی کردهایم.
توصیه میشود که اولین مرحله ساخت شامل بخشهای زیر شود.
- متد اصلی که در اینجا به نام myProgram()
نامگذاری کردهایم و در زیر کلاس جزیره -صفحه حرکت کانگورو- تعریف میشود.
- از هر کانگورویی که قرار است در جزیره استفاده کنیم، نمونهسازی انجام بدهیم.
- الگوریتم سطح بالا را به شکل توضیحات به کدها اضافه کنیم.
1public void myProgram()
2{
3 Jeroo bobby = new Jeroo();
4 this.add(bobby);
5
6 // --- Get the flower ---
7
8 // --- Put the flower ---
9
10 // --- Hop East ---
11
12} // ===== end of method myProgram() =====
نمونهسازی اولیه از کانگورو bobby
در برنامه myProgram()
در منطقه (۰،۰) رو به شرق و بدون هیچ گلی قرار داده میشود.
وقتی که اولین مرحله ساخت برنامه به طور صحیح و سالم کارکرد، میتوانیم به انجام بقیه کار بپردازیم. در این مورد، هر مرحله ساخت به یک بخش در الگوریتم سطح بالا اختصاص دارد. این روند شاید شبیه به میزان زیادی کار برای ساخت چهار مرحله از چنین برنامهی سادهای است. اما انجام این فرایند به بنانهادن عادتهایی کمک میکند که هرچه برنامهها بیچیدهتر شوند ارزشمندتر میشوند.
برای آشنایی بیشتر با مبحث طراحی و نوشتن الگوریتم میتوانید به مطلب طراحی الگوریتم چیست؟ – از کاربرد تا یادگیری به زبان ساده از مجله فرادرس مراجعه کنید.
مرحله دوم ساخت
این مرحله ساخت، منطق مربوط به برداشتن گل را پیادهسازی میکند. این منطق در الگوریتم جزئیاتپردازی شده –مرحله ۴ در بالا- شامل ۳ بار پرش و برداشتن گل میشود. کد جدید توسط توضیحات برنامه نشانهگذاری شده است. توضیحات در برنامه اصلی نمایش داده نمیشوند. این توضیحات فقط به این دلیل اینجا قرار داده شدهاند تا توجه برنامهنویس را به بخشهایی جلب کند که باید به برنامه اضافه شوند. خطوط خالی نیز به نمایش سازماندهی منطق برنامهها کمک میکند.
1public void myProgram()
2{
3 Jeroo bobby = new Jeroo();
4 this.add(bobby);
5
6 // --- Get the flower ---
7 bobby.hop(3); // <-- new code to hop 3 times
8 bobby.pick(); // <-- new code to pick the flower
9
10 // --- Put the flower ---
11
12 // --- Hop East ---
13
14} // ===== end of method myProgram() =====
قبل از نوشتن بقیه برنامه باید کدهای قبلی را تست کنیم. در ادامه، بررسی میکنیم که آیا این برنامه با الگوریتم طراحی شده کار مورد انتظار را تا اینجا انجام داده یا نداده است.
مرحله سوم ساخت
در این مرحله از ساخت الگوریتم، منطق مربوط به عملیات کاشتن گل را پیادهسازی میکنیم. کد جدید به وسیله توضیحاتی نشان داده میشود که در الگوریتم سطح بالا اضافه شده بود. این کد مواردی که باید اضافه شوند را یادآوری میکند.
1public void myProgram()
2{
3 Jeroo bobby = new Jeroo();
4 this.add(bobby);
5
6 // --- Get the flower ---
7 bobby.hop(3);
8 bobby.pick();
9
10 // --- Put the flower ---
11 bobby.turn(RIGHT); // <-- new code to turn right
12 bobby.hop(2); // <-- new code to hop 2 times
13 bobby.plant(); // <-- new code to plant a flower
14
15 // --- Hop East ---
16
17} // ===== end of method myProgram() =====
مرحله چهارم و نهایی
این مرحله منطق مربوط به آخرین حرکت کانگورو یعنی پرش یک خانه به سمت شرق را به برنامه اضافه میکند.
1public void myProgram()
2{
3 Jeroo bobby = new Jeroo();
4 this.add(bobby);
5
6 // --- Get the flower ---
7 bobby.hop(3);
8 bobby.pick();
9
10 // --- Put the flower ---
11 bobby.turn(RIGHT);
12 bobby.hop(2);
13 bobby.plant();
14
15 // --- Hop East ---
16 bobby.turn(LEFT); // <-- new code to turn left
17 bobby.hop(); // <-- new code to hop 1 time
18
19} // ===== end of method myProgram() =====
مثال دوم نوشتن الگوریتم: جابه جا کردن تور با گل
این بخش شامل مثال دیگری برای نمایش فرایند توسعه الگوریتم است. در این قست از دو کانگورو استفاده کردهایم. در واقع الگوریتم پیچیدهتری را طراحی خواهیم کرد.
مرحله اول وضعیت مسئله
در این مسئله دو کانگورو مجزا از هم وجود دارند. یکی از کانگوروها از موقعیت (۰،۰) و رو به شمال بر روی صفحه شروع به حرکت میکند. در کیسه این کانگورو یک گل قرار دارد. کانگورو دوم از موقعیت (۰،۲) رو به شرق شروع به حرکت میکند. در کیسه این کانگورو نیز گلی قرار داده شده است. در موقعیت (۳،۲) روی این جزیره نیز یک تور قرار گرفته است. مسئله این است که باید برنامهای بنویسیم کانگورو اول را به سمت کانگورو دوم راهنمایی کند. سپس گل کانگورو اول را نیز به کانگورو دوم بدهد. بعد از گرفتن گل، کانگورو دوم باید تور را با استفاده از یکی از گلها غیرفعال کند و گل دیگر را در محل قرار گرفتن این تور بکارد. بعد از کاشت گل، کانگورو باید بچرخد و روبه جنوب قرار بگیرد. بر روی این جزیره هیچ گل، تور یا کانگورو دیگری قرار ندارد.
مرحله دوم تحلیل مسئله
در این بخش مسئله را قدم به قدم تحلیل کرده و به بخشهای مختلفی تقسیم میکنیم.
- کانگورو شماره دو Jeroo_2
دقیقا در دو خانه عقبتر از کانگورو شماره یک Jeroo_1
قرار دارد.
- تنها تور موجود در جزیره دقیقا در سه خانه جلوتر از کانگورو شماره دو Jeroo_2
قرار دارد.
- هر کانگورو دقیقا یک گل در کیسه خود دارد.
- کانگورو شماره دو Jeroo_2
بعد از اینکه گل متعلق به کانگورو شماره یک Jeroo_1
را تحویل گرفت، دو عدد گل در کیسه خود خواهد داشت.
- گل اول باید برای غیر فعال کردن تور استفاده شود.
- گل دیگر باید در موقعیت متعلق به تور یعنی خانه (۳،۲) کاشته شود.
- کانگورو شماره یک Jeroo_1
حرکت خود را در خانه (۰،۱) در حالی که رو به جنوب قرار گرفته به پایان میرساند.
- کانگورو شماره دو Jeroo_2
نیز حرکت خود را در خانه (۳،۲) در حالی که رو به جنوب قرار گرفته به پایان میرساند.
- کار مربوط به هر دو کانگورو در حالی به پایان میرسد که تعداد گل موجود در کیسه هر کدام برابر با صِفر است. زیرا گلی برای غیرفعال کردن تور استفاده شده و گل دیگر بر روی صفحه کاشته شده است.
مرحله سوم نوشتن الگوریتم سطح بالا
برای نوشتن الگوریتم سطح بالای این مسئله به زبان نزدیک به انسان، کانگورو اول را آنه Ann
و کانگورو دوم را اندی Andy
نامگذاری میکنیم.
- آنه Ann
باید کارهای زیر را انجام دهد.
- اندی Andy
را پیدا کند اما به او برخورد نکند.
- گل خود را به اندی Andy
تحویل دهد. اندی Andy
نیز مستقیم رو به جلو قرار خواهد داشت.
- اندی Andy
- اندی Andy
بعد از تحویل گرفتن گل باید کارهای زیر را انجام دهد.
- در ابتدا باید تور را پیدا کند اما نباید بر روی تور بپرد.
- تور را غیر فعال کند.
- گلی را در موقعیت آزاد شده از تور بکارد.
- صورت خود را رو به جنوب بگرداند.
مرحله چهارم اضافه کردن جزئیات بیشتر به الگوریتم
طبق روال سابق، کانگورو اول را آنه Ann
و کانگورو دوم را اندی Andy
مینامیم. در این مرحله برای الگوریتم سطح بالای مرحله قبل باید جزئیات بیشتری را تعریف کنیم.
- آنه Ann
باید کارهای زیر را انجام دهد.
- اندی Andy
را پیدا کند.
- فرقی نمیکند راست یا چپ اما دوبار پشت سرهم به یک جهت باید بچرخد.
- به منطقه (۰،۱) پرش کند.
- گل خود را به اندی Andy
بدهد.
- مستقیم به جلو تحویل دهد.
- اندی Andy
- الان نوبت اندی Andy
است. اندی Andy
باید کارهای زیر را انجام دهد.
- تور را پیدا کند.
- دوبار رو به جلو بپرد تا به خانه (۲،۲) برسد.
- تور را غیر فعال کند.
- گلی را بر روی تور انداخته و تور را جمع کند.
- گل دیگر را در موقعیت مربوط به تور غیر فعال شده بکارد.
- در ابتدا به خانه شماره (۳،۲) بپرد.
- گل را بکارد.
- رو به جنوب قرار بگیرد.
- به سمت راست بچرخد.
- تور را پیدا کند.
در مرحله بعد باید الگوریتم را بازبینی کنیم.
مرحله پنجم بازبینی الگوریتم
نوشتن الگوریتم سطح بالا به مدیریت جزئیات کمک میکند.
این الگوریتم مسئله بسیار خاص با مشخصات ثابتی را میتواند حل کند. اما مکانهای مشخص شده مهم نیستند. تنها نکات مهم این است که:
- محل شروع کانگوروها نسبت به یکدیگر باید ثابت باشد.
- موقعیت قرار گیری تور نسبت به کانگورو شماره ۲ نیز باید ثابت باشد.
- ضمنا جهت قرارگیری اولیه کانگوروها نیز از اهمیت زیادی برخوردار است.
کد جاوا برای مسئله جابه جایی تور با گل
همانند مسئله قبل کد را باید به تدریج در سری منظمی از مراحل ساخت، پشت سر هم نوشت. برای این مسئله چهار مرحله ساخت مناسب خواهد بود.
- طبق معمول، مرحله ساخت اول شامل متد اصلی خواهد شد. یعنی در این مرحله باید کلاس کانگورو را تعریف کنیم و از روی این کلاس نمونهسازی انجام دهیم. سپس الگوریتم سطح بالا را به صورت توضیحات به صفحه کدنویسی خود اضافه کنیم.
- در مرحله ساخت دوم، آنه Ann
باید گل خود را به اندی Andy
تحویل دهد.
- در مرحله سوم ساخت، اندی Andy
را خواهیم داشت. اندی Andy
خود را به تور میرساند و تور را غیرفعال میکند.
- در مرحله چهارم، اندی Andy
گل را در محل مورد نظر قرار میدهد و رو به سمت جنوب قرار میگیرد. در این قسمت فرایند حل مسئله به پایان میرسد.
مرحله اول ساخت یا نوشتن الگوریتم
در این مرحله ساخت، متد اصلی را ایجاد میکنیم. از روی کلاس کانگورو نمونههای مورد نیاز را تولید میکنیم و در نهایت، باید الگوریتم سطح بالا را به صورت توضیحات به متن کدهایمان اضافه کنیم. در این مثال، متد اصلی را به نام myProgram()
تعریف میکنیم. این متد شامل زیر کلاسهایی از اشیا موجود در جزیره خواهد بود.
1public void myProgram()
2{
3 Jeroo ann = new Jeroo(0, 0, NORTH, 1);
4 this.add(ann);
5 Jeroo andy = new Jeroo(0, 2 , 1); // default EAST
6 this.add(andy);
7
8 // --- Ann, find Andy ---
9
10 // --- Ann, give Andy a flower ---
11
12 // --- Andy, find and disable the net ---
13
14 // --- Andy, place a flower at (3, 2) ---
15
16 // --- Andy, face South ---
17
18} // ===== end of method myProgram() =====
مرحله دوم ساخت
در این مرحله از ساخت منطق مربوط به آنه Ann
را پیادهسازی میکنیم. آنه Ann
باید اندی Andy
را پیدا کند و گل خود را به اندی Andy
تحویل دهد.
1public void myProgram()
2{
3 Jeroo ann = new Jeroo(0, 0, NORTH, 1);
4 this.add(ann);
5 Jeroo andy = new Jeroo(0, 2 , 1); // default EAST
6 this.add(andy);
7
8 // --- Ann, find Andy ---
9 ann.turn(LEFT);
10 ann.turn(LEFT);
11 ann.hop();
12 // Now, Ann is at (0, 1) facing South, and Andy is directly ahead
13
14 // --- Ann, give Andy a flower ---
15 ann.give(AHEAD); // Ann now has 0 flowers, Andy has 2
16
17 // --- Andy, find and disable the net ---
18
19 // --- Andy, place a flower at (3, 2) ---
20
21 // --- Andy, face South ---
22
23} // ===== end of method myProgram() =====
مرحله سوم ساخت
در این مرحله قسمت اول منطق مربوط به اندی Andy
را به کدها اضافه میکنیم. در این منطق اندی Andy
باید تور را پیدا و سپس غیرفعال کند.
1public void myProgram()
2{
3 Jeroo ann = new Jeroo(0, 0, NORTH, 1);
4 this.add(ann);
5 Jeroo andy = new Jeroo(0, 2 , 1); // default EAST
6 this.add(andy);
7
8 // --- Ann, find Andy ---
9 ann.turn(LEFT);
10 ann.turn(LEFT);
11 ann.hop();
12 // Now, Ann is at (0, 1) facing South, and Andy is directly ahead
13
14 // --- Ann, give Andy a flower ---
15 ann.give(AHEAD); // Ann now has 0 flowers, Andy has 2
16
17 // --- Andy, find and disable the net ---
18 andy.hop(2); // Andy is at (2, 2) facing the net
19 andy.toss();
20
21 // --- Andy, place a flower at (3, 2) ---
22
23 // --- Andy, face South ---
24
25} // ===== end of method myProgram() =====
مرحله چهارم ساخت یا مرحله نهایی نوشتن الگوریتم
در این مرحله نیز قسمت دوم منطق مربوط به رفتار اندی Andy
را به کدها اضافه کردهایم. اندی Andy
گل را در موقعیت (۳،۲) میکارد و سپس رو به جنوب قرار میگیرد.
1public void myProgram()
2{
3 Jeroo ann = new Jeroo(0, 0, NORTH, 1);
4 this.add(ann);
5 Jeroo andy = new Jeroo(0, 2 , 1); // default EAST
6 this.add(andy);
7
8 // --- Ann, find Andy ---
9 ann.turn(LEFT);
10 ann.turn(LEFT);
11 ann.hop();
12 // Now, Ann is at (0, 1) facing South, and Andy is directly ahead
13
14 // --- Ann, give Andy a flower ---
15 ann.give(AHEAD); // Ann now has 0 flowers, Andy has 2
16
17 // --- Andy, find and disable the net ---
18 andy.hop(2); // Andy is at (2, 2) facing the net
19 andy.toss();
20
21 // --- Andy, place a flower at (3, 2) ---
22 andy.hop();
23 andy.plant();
24
25 // --- Andy, face South ---
26 andy.turn(RIGHT);
27
28} // ===== end of method myProgram() =====
دروس دانشگاهی در رابطه با نوشتن الگوریتم
این قسمت از مطلب به طور خاص مناسب دانشجویانی طراحی شده است که نه تنها میخواهند روش نوشتن صحیح الگوریتم ها را بدانند بلکه باید برای آزمونهای دانشگاهی و کنکور ارشد نیز آماده شوند. وبسایت آموزشی فرادرس فیلمهای بسیار خوبی درباره طراحی، نوشتن و کار با الگوریتمها را با استفاده از اساتید حرفهای تهیه کردهاست. در این فیلمهای آموزشی تجزیه و تحلیل سوالات کنکور سالهای متمادی نیز تهیه شدهاند.
در این بخش چند مورد از این فیلمهای آموزشی را معرفی کردهایم. این فیلمها هم برای دانشجویان، هم برای برنامهنویسان و هم برای افرادی که میخواهند با مبحث طراحی الگوریتم تا حد بسیار خوبی آشنا شوند مفید است.
جمع بندی
تسلط به نوشتن الگوریتم یکی از تخصصهای است که برنامهنویسهای حرفهای برای قدرتمندتر شدن رزومه خود حتما باید آن را داشته باشند. طراحی و نوشتن الگوریتم، رابطه بسیار نزدیکی به علم ساختمان داده دارد. در این مطلب از مجله فرادرس درباره طراحی الگوریتم صحبت کردیم. مزایا و اصول نوشتن الگوریتمها را بررسی کردیم و در نهایت با استفاده از زبان برنامهنویسی جاوا فرایند نوشتن الگوریتم را با دو مثال مختلف، پیادهسازی کردیم.
توجه کنید که الگوریتمهای نوشته شده در این مطلب با زبان جاوا و در نرم افزار Greenfoot اجرا شدهاند. در صورت نیاز به پیادهسازی این کدها در ادیتور کدنویسی خود، نیاز به اعمال تغییرات کوچکی خواهید داشت. اما الگوریتمها را با هر زبان برنامهنویسی دیگری مانند پایتون، ++C، پی اچ پی و غیره نیز میتوانید پیادهسازی کنید.
source