نویسنده: نادر خرمي راد
همیشه میگوییم شناوری کل مدت زمانیه که اگه فعالیت به اون اندازه به تاخیر بیفته تاریخ پایان پروژه رو به تاخیر نمیندازه. این تعریف خیلی قدیمیه و باید تعریف کاملتری به جاش به کار ببریم. چیزی که تو تعیین شناوری موثره صرفا تاریخ پایان پروژه نیست؛ تاریخهای مهم پروژه است. شناوری مدت زمانی که اگه فعالیت به اون اندازه به تاخیر بیفته، هیچکدام از تاریخهای مهم پروژه به تاخیر نمیافتند.
تاریخهای مهم اینها هستند:
تاریخ پایان پروژه
تاریخ پایان فعالیتهایی که پسنیاز ندارند (توضیح 1)
فرجهها
تاریخ قیدهایی که انعطافپذیر نیستند
توضیح 1: وقتی تاریخ پایان فعالیتهایی که پسنیاز ندارند در تعیین شناوریها مبنا قرار میگیره که گزینه Calculate Multiple Critical Tasks رو در Tools| Options| Calculation فعال کرده باشید.
حالا ماجرا رو با هم مرور میکنیم. برنامه شکل زیر رو ببینید:
تو این برنامه سه گروه فعالیت تعریف شده است. هر گروه دو فعالیت دارد که با هم لینک هستند. میشد مسئله رو روی فعالیتهای تکی هم نشون داد، ولی ما از گروههای دوتایی استفاده کردیم تا سرایت کردن شناوریها رو به عقب هم نشان داده شود. برای هرکدام از این سه گروه نقشههایی کشیدیم. گروه اول طولانیترین مدت زمانها را دارند و به همین خاطر بحرانی شدند. فعالیتهای بحرانی در این نما با رنگ قرمز دیده میشوند. شناوری کل فعالیتها هم با خطهای سبز رنگ باریک نشان داده شدند. الان چهار تا فعالیت آخر شناوری کل دارند. مقدار شناوری کل رو میتوانید در جدول هم ببینید.
برای فعالیت چهارم فرجهای در پایان روز 9 قرار میدهیم. وضعیت اینطوری میشود:
فرجه میگوید که فعالیت باید تا اون موقع تمام شده باشد، پس منطقیه که برنامه شناوری را طوری تنظیم کند که فعالیت از اون تاریخ نگذرد. به عبارت دیگر به فرجه اهمیتی در حد تاریخ پایان پروژه بدهد. حالا نگاهی به شناوری فعالیت سوم بندازید، متوجه شدید که چه اتفاقی افتاد؟ کم شدن شناوری فعالیت چهارم به پیشنیازش هم سرایت کرد.
حالا به فعالیت ششم قید Finish No Later Than برای پایان روز نهم میدهیم:
در این حالت هم شناوری فعالیت ششم و پیشنیازش به طور متناسب کم شد. واقعیت اینه که چنین قیدی تفاوت چندانی با فرجه نداشت. حالا به شکل بالایی نگاه کنید و تصور کنید که وقتی فرجه را به پایان روز هشتم بکشیم. شناوری فعالت چهارم چقدر میشود؟ اگر اون رو به پایان روز هفتم بکشیم چطور؟ بله، در این حالت شناوری کل فعالیت صفر میشود و اون فعالیت همراه با پیشنیازش بحرانی میشوند.
حالا باز هم تصور کنید که فرجه رو عقبتر بکشیم، مثلا پایان روز ششم. در این حالت شناوری فعالیت چقدر میشود؟
این هم همون شناوری منفیه ! مفهوم پیچیدهای نیست، هست؟
تو این وضعیت فعالیت چهارم اگه طبق برنامه پیش برود هم یکی از تاریخهای مهم پروژه یک روز به تاخیر میافتد، یعنی فعالیت باید یک روز کمتر از برنامه وقت ببره تا تاریخ حفظ بشه. یک روز کمتر، یعنی شناوری منفی یک.
حالا فرض کنید تاریخ قید فعالیت ششم که قبلا پایان روز نهم بود رو تبدیل کنیم به پایان روز پنجم. قبل از اینکه به شکل نگاه کنید سعی کنید وضعیت را در ذهنتان به تصویر بکشید. خوب، این کار رو کردید؟ این هم وضعیت برنامه:
خوب، اگه تصورتان اشتباه بود ناراحت نباشید، به هر حال اگه مسئله خیلی سادهای بود اینجا توضیحش نمیدادیم. الان در سومین گروه فعالیتها تناقض وجود دارد. رابطهای که بین فعالیتهای پنجم و ششم وجود دارد رابطه FS سادهای، بدون همپوشانیه، که ایجاب میکند T6 زودتر از روز پنجم شروع نشود، یعنی همان چیزی که در شکلهای قبلی میدیدید. حالا ما قیدی به این فعالیت دادیم که حکم میکنه فعالیت بعد از روز چهارم شروع نشود. این یعنی تناقض.
وقتی بین قید و روابط تناقض وجود داشته باشه تکلیف چیست؟
پیشفرض این است که قید مبنا قرار بگیرد.
حالا میتوانید بروید در منوی Tools| Options| Schedule و گزینه Tasks will always honor their constraint dates را غیر فعال کنید. حالا اگه تناقضی بین قید و روابط وجود داشته باشد اولویت به روابط داده میشود. این هم میشود وضعیت همان برنامه قبلی، بعد از تغییر تنظیم
خوب، حالا ما قید و فرجه رو برمیداریم، یعنی وضعیت برنامه میشود مثل اولین شکلی که دیدید (بد نیست الان برگردید بالا و نگاهی بهش بیندازید). حالا میریم به Tools| Options| Calculate و گزینه Calculate multiple critical paths را فعال میکنیم. نتیجه این میشود:
اصولا همیشه توصیه میشود که در هر برنامه فقط یک فعالیت بدون پسنیاز باشه، یعنی آخرین فعالیت پروژه. البته بهتره بگویم پسنیاز مستقیم و غیر مستقیم، چون ممکنه فعالیتی خودش پسنیاز نداشته باشه، ولی خلاصه فعالیتش پسنیاز داشته باشه و در نتیجه تاریخ پایان فعالیت غیر مستقیم روی بقیه فعالیتها اثر میگذارد. به هر حال؛ اگه بیشتر از یک فعالیت پسنیاز مستقیم یا غیر مستقیم داشته باشند، در حالت معمول به جز یکیشون همه شناوری میگیرند. حالا فرض کنید پروژهای داریم از 10 بلوک ساختمانی. تاریخ پایان هرکدام از بلوکها پسنیازی ندارد، و در عین حال ترجیح میدهیم که هر بلوک در زودترین زمان ممکن تمام بشود و شناوری برایشان نگذاریم. در این صورت میتوانیم این گزینه رو فعال کنیم، در نتیجه شناوری فعالیتهای آزاد حذف میشود و به پیشنیازهاشون هم منتقل میشود. به این ترتیب احتمالا مسیرهای بحرانی جدیدی هم ایجاد میشود. خوب، این وضعیت رو میتوانید در شکل بالا هم ببینید.
خوب، من امیدوارم این مطالب رو به شما منتقل کرده باشم:
تنها تاریخ مقدسی که برای محاسبه شناوریها به کار میره تاریخ پایان پروژه نیست.
شناوری منفی با ……. به وجود میاد. با چی؟
مسیرهای بحرانی متعدد با مقید کردن فعالیتهای آزاد به وجود میاد.
طولانی ترین مسیر یا کمترین شناوری
کلا دو روش برای بحرانی به حساب آوردن فعالیتها و در نتیجه تعیین «مسیر بحرانی»، یعنی مجموعه فعالیتهای بحرانی – که از قدیم علاقه داشتیم تو یه مسیر باشن – وجود داره:
- بر اساس حداکثر شناوری کل فعالیتها
- بر اساس قرار گرفتن روی طولانیترین مسیر
روش اول برای اکثر افراد آشناتره و معمولا جاهایی که تئوری CPM رو توضیح میدن از همین روش استفاده میکنن. تو این روش زودترین و دیرترین تاریخهای شروع و پایان هر فعالیت تو دو مرحله رفت و برگشت محاسبه میشه و تفاضل زودترین و دیرترین تاریخها دو مقدار شناوری شروع و شناوری پایان رو به وجود میاره. نرمافزارهای مختلف یا یکی از این دوتا رو شناوری کل میشناسن، یا حداقل اونها رو، یا حتی انتخاب اون رو به شما بدن؛ البته این دو مقدار تو حالتهای معمولی با هم برابر هستن. حالا حدی برای اونها در نظر گرفته میشه و هر فعالیتی که شناوری کلش از اون مقدار بیشتر نباشه بحرانی به حساب میاد.
شناوری کل فعالیتها تو برنامهای که آزاد باشه از صفر کمتر نمیشه و این فرض تو حالتهای قدیمی که تو تئوریها توضیح داده میشه هم وجود داره. برای همین رسم بر این بوده که شناوری صفر بحرانی به حساب بیاد. حالا تو پروژههایی که مدت زمانشون زیاد باشه و مدت زمان فعالیتهاشون هم خیلی کم نباشه، شناوریهایی مثل یک روز چندان با صفر فرق نمیکنه. به همین خاطر این گزینه هم وجود داره که حداکثر دیگهای برای شناوری تعیین کنین و مثلا بگین که فعالیتهایی که شناوریشون بیشتر از یک روز نباشه بحرانی به حساب میاد.
اگه برنامهتون آزاد نباشه میتونه شناوری منفی هم داشته باشه، که در این صورت منفیها هم بحرانی به حساب میان. البته میدونین که بهتره از برنامههای غیر آزاد استفاده نکنین و در نتیجه نباید انتظار شناوری منفی داشته باشین.
تو روش دوم به جای شناوری کل، از شناوری روابط برای تعیین «طولانیترین مسیر» و به دنبال اون فعالیتهای بحرانی استفاده میشه. هر رابطه بر اساس تفاضل تاریخهای پیشنیاز و پسنیازش مقداری داره که به اون هم میگیم شناوری. اگه شناوری صفر باشه، به رابطه حاکم (driver) گفته میشه. معمولا بین تمام روابطی که برای یه فعالیت تعریف شده فقط یکیشون حاکمه. اگه همه روابط رو به جز رابطه حاکم حذف کنین، زمانبندیتون تغییری نمیکنه. با این حال باید روابط غیر حاکم رو خیلی با دقت وارد کنین، چون هم روی شناوریها اثر میذاره و هم اینکه ممکنه بعد از مدتی به خاطر وارد کردن مقدارهای واقعی وضعیت تغییر کنه و رابطه دیگهای حاکم بشه.
به هر حال، کار از انتهای برنامه شروع میشه. فعالیت انتهایی به عنوان آخرین عنصر «طولانیترین مسیر» انتخاب میشه و بعد مسیر بر اساس روابط حاکم دنبال میشه و فعالیتهای دیگه دونه دونه انتخاب میشن. مجموعه این فعالیتها میشن طولانیترین مسیر برنامه و میتونن بحرانی به حساب بیان.
پس مسیر بحرانی میتونه بر اساس شناوری فعالیتها یا بر اساس شناوری روابط (قرار داشتن تو طولانیترین مسیر) تعیین بشه. این دو روش تو شبکههای خیلی ساده، مشابه اون چیزهایی که برای توضیح دادن تئوری CPM به کار میرن نتیجه یکسانی داره، ولی تو برنامههای پیچیدهای که تو پروژههای واقعی داریم، به خاطر قیدهایی که ممکنه استفاده شده باشه، به خاطر تسطیح منابع، به خاطر تقویمها و خیلی مسایل دیگه ممکنه تفاوتهایی بین نتایج اونها وجود داشته باشه.
نظرهای متفاوتی وجود داره که کدوم روش بهتره. انتخاب ممکنه تا حدی به سبک برنامهریزی هم برگرده؛ ولی به هر حال من شخصا روش مبتنی بر شناوری فعالیتها رو ترجیح میدم، چون سادهتر با المانهایی مثل تقویم و تسطیح و قید کارش رو پیش میبره.
بر گرفته از سایت: توسعه شبکه مهندسی صنایع ایران