সরাসরি পর্বে যান
পর্ব ৬১ · ৭০-এর মধ্যে · মডিউল ১০

Project planning — WBS, Gantt chart, CPM আর PERT

Project Planning — Work Breakdown, Network Diagrams, CPM, PERT, Crashing, Gantt Charts and Earned Value

Taught in Bangla, this lesson covers project planning: work breakdown structures and the 100% rule, dependency types and AON and AOA network diagrams, CPM forward and backward passes with total and free float, PERT expected times, variance and completion probability, crashing and fast-tracking, resource levelling, Gantt charts and earned value, compared with Agile planning, using a CPM/PERT simulator.

এই পর্বে যা শিখবেন

  • Project আর operations-এর পার্থক্য, triple constraint, আর WBS বানানোর নিয়ম (100% নিয়ম, work package, WBS dictionary)
  • চার ধরনের dependency, lag-lead, আর AON ও AOA network diagram (dummy activity-সহ)
  • CPM-এর forward ও backward pass, total float, free float, critical আর near-critical path — হাতে ও কোডে
  • PERT দিয়ে প্রত্যাশিত সময়, variance আর নির্দিষ্ট তারিখের মধ্যে শেষ হওয়ার সম্ভাবনা, আর merge bias
  • Crashing, fast-tracking, resource levelling, Gantt chart, earned value — আর Agile planning-এর সাথে তুলনা

১ · Project আর operations — পরিকল্পনা কেন আলাদা বিদ্যা

একটি কাল্পনিক জেলা শহরের স্কুল ঠিক করল, এবার থেকে পরীক্ষার ফলাফল কাগজের খাতায় নয়, একটি অ্যাপে প্রকাশ হবে — শিক্ষক নম্বর তুলবেন, অ্যাপ নিজেই grade বের করবে, অভিভাবক মোবাইলে ফল দেখবেন। প্রধান শিক্ষক জানতে চাইলেন তিনটি প্রশ্নের উত্তর: কবে হবে? কত খরচ? দেরি হলে আগে থেকে বুঝব কীভাবে? এই পর্বের পুরোটা জুড়ে আমরা এই “স্কুল ফলাফল অ্যাপ” (কাল্পনিক) project-টি পরিকল্পনা করব।

প্রথমে একটি পার্থক্য। একটি project-এর নির্দিষ্ট শুরু আর শেষ আছে, আর এটি একটি অনন্য ফল তৈরি করে — এই অ্যাপটি আগে কখনো এই স্কুলের জন্য বানানো হয়নি। অন্যদিকে operations হলো নিয়মিত, পুনরাবৃত্ত কাজ: অ্যাপ চালু হওয়ার পর প্রতি পরীক্ষায় নম্বর তোলা, server চালু রাখা, ছোট bug সারানো। Operations-এ অতীতের অভিজ্ঞতা প্রায় হুবহু খাটে; project-এ প্রতিবার কিছু না কিছু নতুন, তাই অনিশ্চয়তা বেশি। এ কারণেই project-এর জন্য আলাদা পরিকল্পনার পদ্ধতি দরকার।

বিয়েবাড়ির আয়োজনের কথা ভাবুন। প্রতিদিনের রান্না হলো operations — কী লাগবে, কতক্ষণ লাগবে, সবাই জানে। কিন্তু বিয়ের আয়োজন একটি project: তারিখ নির্দিষ্ট, বাজেট সীমিত, আর কাজের তালিকা লম্বা — কমিউনিটি সেন্টার ভাড়া, বাবুর্চি, কার্ড ছাপানো, অতিথির তালিকা। কিছু কাজ পরস্পরের ওপর নির্ভর করে (অতিথির সংখ্যা না জানলে বাবুর্চিকে মাপ বলা যায় না), কিছু কাজ একসাথে চলতে পারে (কার্ড ছাপা আর গায়ে হলুদের কেনাকাটা)। অভিজ্ঞ মুরুব্বি জানেন কোন কাজটি দেরি হলে পুরো বিয়ের তারিখ পিছিয়ে যাবে — আর কোনটিতে দুই দিন এদিক-ওদিক হলেও ক্ষতি নেই। এই পর্বের CPM আসলে সেই মুরুব্বির জ্ঞানকে অঙ্কে লেখা।

Triple constraint — scope, সময়, খরচ আর মাঝখানে quality

Project management-এর সবচেয়ে পরিচিত ছবি একটি ত্রিভুজ: তিন কোণে scope (কী কী বানাতে হবে), সময় আর খরচ, আর মাঝখানে quality. একে triple constraint বা iron triangle বলে। ধারণাটি সাধারণত Martin Barnes-এর নামে উদ্ধৃত হয় (১৯৬৯ সালের দিকে একটি প্রশিক্ষণ কোর্সে) — তবে উৎস নিয়ে বিভিন্ন বর্ণনা আছে। মূল কথা: তিনটির একটি বদলালে অন্তত আরেকটি বদলাতে হবে, নইলে চাপটা নিঃশব্দে quality-র ওপর পড়ে।

  • প্রধান শিক্ষক যদি বলেন “SMS-এ ফল পাঠানোর feature-ও চাই” (scope বাড়ল), তাহলে হয় সময় বাড়বে, নয় খরচ (আরও লোক), নয়তো test কম হবে — অর্থাৎ quality কমবে।
  • “ফল প্রকাশের তারিখ দুই সপ্তাহ এগিয়ে আনুন” (সময় কমল) — তাহলে scope কাটতে হবে বা খরচ বাড়াতে হবে (অংশ ৬-এর crashing).

পর্ব ২৪-এ (requirement management) আপনি scope creep দেখেছেন — প্রভাব না মেপে scope বাড়তে থাকা। Triple constraint সেই সমস্যারই হিসাবের দিক: প্রতিটি নতুন চাহিদার সাথে প্রশ্ন, “এর বদলে কোনটি ছাড়ব?”

মূল ধারণা

পরিকল্পনার লক্ষ্য ভবিষ্যৎ নিখুঁত জানা নয়। লক্ষ্য হলো: (১) কী কী কাজ, (২) কোনটি কোনটির পরে, (৩) কোনগুলো দেরি হলে শেষ তারিখ পেছাবে, আর (৪) বাস্তব কখন পরিকল্পনা থেকে সরে যাচ্ছে — এগুলো আগে থেকে দেখতে পাওয়া। পরিকল্পনা একটি মানচিত্র, ভবিষ্যদ্বাণী নয়।

২ · Work breakdown structure — বড় কাজকে ভাঙার নিয়ম

“স্কুল ফলাফল অ্যাপ বানানো” — এই এক লাইনের কাজের সময় অনুমান করা অসম্ভব। কিন্তু “শিক্ষকের নম্বর তোলার screen” বা “grade হিসাবের module” — এগুলোর অনুমান সম্ভব। Work breakdown structure (WBS) হলো পুরো project-কে ধাপে ধাপে ছোট অংশে ভাঙা একটি গাছ। ওপরে project, তার নিচে বড় বড় deliverable (হস্তান্তরযোগ্য ফল), তার নিচে আরও ছোট অংশ, আর সবচেয়ে নিচের পাতাগুলো work package.

WBS কোডঅংশ (deliverable বা work package)এখানে কী কাজ ধরা আছে
১স্কুল ফলাফল অ্যাপ (project)নিচের সবকিছুর যোগফল — ১০০%
১.১Requirement ও SRSশিক্ষক-অভিভাবকের সাথে আলোচনা, grading নিয়ম সংগ্রহ, SRS অনুমোদন
১.২নকশা১.২.১ Database নকশা · ১.২.২ UI নকশা (wireframe)
১.৩Software১.৩.১ Backend API · ১.৩.২ Frontend screen · ১.৩.৩ Grading module
১.৪যাচাই১.৪.১ Integration · ১.৪.২ Testing (শিক্ষকদের নিয়ে acceptance test-সহ)
১.৫চালু করাDeployment, শিক্ষকদের প্রশিক্ষণ, হস্তান্তর
১.৬Project managementপরিকল্পনা, সাপ্তাহিক মিটিং, রিপোর্ট — এটিও কাজ, তাই WBS-এ থাকে

ভালো WBS-এর কয়েকটি প্রচলিত নিয়ম:

  • Deliverable-কেন্দ্রিক: শাখাগুলো “কী তৈরি হবে” দিয়ে সাজানো, “কে করবে” বা “কোন মাসে” দিয়ে নয়। এতে কাজ বাদ পড়লে সহজে চোখে পড়ে।
  • ১০০% নিয়ম (100% rule): প্রতিটি স্তরের অংশগুলোর যোগফল ঠিক তার ওপরের অংশের সমান — scope-এর বাইরের কিছু নয়, আবার scope-এর কিছু বাদও নয়। PMI-এর WBS-বিষয়ক practice standard এই নিয়মকে কেন্দ্রে রাখে। খেয়াল করুন, “Project management” শাখাটি না রাখলে ১০০% পূর্ণ হতো না — মিটিং আর রিপোর্টেও সময় যায়।
  • একই কাজ দুই জায়গায় নয়: শাখাগুলো পরস্পর-বিচ্ছিন্ন হতে হবে, নইলে খরচ দুবার গোনা হয়।
  • Work package কত ছোট? এমন ছোট যে একজন দায়িত্বপ্রাপ্ত মানুষ, নির্ভরযোগ্য অনুমান আর মাপা যায় এমন অগ্রগতি থাকে। একটি প্রচলিত হাতের হিসাব হলো 8/80 heuristic: work package মোটামুটি ৮ থেকে ৮০ ঘণ্টার কাজ। এটি কোনো মানদণ্ডের বাধ্যতামূলক নিয়ম নয় — দল, project আর রিপোর্টিং-এর সময়সীমা অনুযায়ী বদলায়।

WBS-এর প্রতিটি অংশের বিস্তারিত বিবরণ রাখা হয় একটি সঙ্গী দলিলে — WBS dictionary. যেমন ১.৩.৩ Grading module-এর ঘরে লেখা থাকে: কাজের বর্ণনা (নম্বর থেকে GPA, স্কুলের নিয়ম অনুযায়ী), কে দায়িত্বে, অনুমিত সময় ও খরচ, নির্ভরতা (database নকশা আগে), আর শেষের শর্ত (“২০টি নমুনা শিক্ষার্থীর হাতে-হিসাব করা ফলের সাথে মিলেছে”)।

WBS কাজের ক্রম নয়। WBS বলে কী কী কাজ; কোনটি আগে, কোনটি পরে — তা বলে না। ক্রম আর সময় আসে পরের ধাপে, network diagram-এ। পরীক্ষায় প্রায়ই এই দুটি গুলিয়ে ফেলা হয়।

৩ · Activity, dependency আর network diagram

Work package থেকে আমরা activity বের করি — সময় নেয় এমন নির্দিষ্ট কাজ। আমাদের অ্যাপের জন্য নয়টি activity, প্রতিটির সময় (দিনে) আর পূর্বসূরি (যে কাজ আগে শেষ হতে হবে):

Activityকাজসময় (দিন)পূর্বসূরি
ARequirement সংগ্রহ ও SRS৪—
BDatabase নকশা৩A
CUI নকশা (wireframe)৫A
DBackend API৬B
EFrontend screen৩C
FGrading module৪B
GIntegration৩D, E, F
HTesting৪G
IDeployment ও প্রশিক্ষণ২H

চার ধরনের dependency আর lag-lead

উপরের টেবিলের সব নির্ভরতা একই ধরনের: আগেরটি শেষ হলে পরেরটি শুরু — finish-to-start (FS). বাস্তবে আরও তিনটি ধরন আছে:

ধরনঅর্থSoftware-এর উদাহরণ
FS finish-to-startX শেষ হলে Y শুরু হতে পারেDatabase নকশা শেষ → backend লেখা শুরু
SS start-to-startX শুরু হলে Y শুরু হতে পারেFrontend কোড শুরু হলে (প্রায়ই ২ দিনের lag দিয়ে) তার UI test লেখাও শুরু
FF finish-to-finishX শেষ হলে তবেই Y শেষ হতে পারেশেষ feature শেষ না হলে user manual শেষ করা যায় না
SF start-to-finishX শুরু হলে তবেই Y শেষ হতে পারেনতুন server চালু হলে তবেই পুরোনো server বন্ধ (বিরল)

নির্ভরতার সাথে সময় যোগ করা যায় — lag আর lead. “FS + ২ দিন” (lag) মানে আগেরটি শেষ হওয়ার ২ দিন পর পরেরটি শুরু — যেমন SRS পাঠানোর পর অনুমোদনের জন্য ২ দিন অপেক্ষা। “FS − ২ দিন” (lead) মানে আগেরটি শেষ হওয়ার ২ দিন আগেই পরেরটি শুরু — অংশ ৬-এর fast-tracking আসলে এটাই।

AON আর AOA — দুই রকম network diagram

Activity-on-node (AON) রীতিতে প্রতিটি activity একটি বাক্স, আর তীর শুধু নির্ভরতা। চারটি dependency ধরন আর lag এখানে সহজে দেখানো যায়; আধুনিক tool প্রায় সবই AON ব্যবহার করে (একে precedence diagramming method-ও বলে)। অংশ ৪-এর ছবিটি AON.

পুরোনো activity-on-arrow (AOA) রীতিতে উল্টো: activity হলো তীর, আর বৃত্ত (node) হলো ঘটনা — “এই মুহূর্তে আগের কাজগুলো শেষ”। মূল CPM আর PERT এই রীতিতেই আঁকা হতো, আর পরীক্ষায় এখনো আসে। এর একটি বিশেষ জিনিস হলো dummy activity: শূন্য সময়ের ড্যাশ-দেওয়া তীর, যার কাজ দুটি —

  1. নির্ভরতা ঠিক রাখা: ধরুন G-এর জন্য D, E, F তিনটিই লাগে, কিন্তু অন্য একটি কাজ (ধরুন “user manual”) লাগে শুধু F-এর পরে। শুধু ঘটনা-বৃত্ত দিয়ে এটি আঁকলে ভুল নির্ভরতা তৈরি হয়; তাই F-এর শেষ-ঘটনা থেকে একটি dummy তীর G-এর শুরু-ঘটনায় যায়।
  2. প্রতিটি activity আলাদা চেনানো: AOA-তে activity-কে তার শুরু ও শেষ ঘটনার জোড়া (i, j) দিয়ে চেনা হয়। D আর F দুটোই ঘটনা ৩ থেকে শুরু; দুটো একই শেষ-ঘটনায় গেলে দুটোই হতো (৩, ৫) — তাই একটির শেষে আলাদা ঘটনা আর একটি dummy লাগে।

AOA রীতিতে একই project — dummy activity কোথায় লাগে

Activities on arrows, events in circles, two dashed dummies (zero duration)

১ ২ ৩ ৪ ৫ ৬ ৭ ৮ ৯ A ৪ B ৩ C ৫ D ৬ F ৪ E ৩ dummy G ৩ H ৪ I ২ তীর = activity, বৃত্ত = ঘটনা, ড্যাশ = শূন্য সময়ের dummy
ছবি ৬১.১ — D আর F দুটোই ঘটনা ৩ থেকে শুরু। F-কে আলাদা ঘটনা ৫-এ শেষ করে একটি dummy দিয়ে ঘটনা ৬-এ জোড়া হয়েছে, যাতে D = (৩, ৬) আর F = (৩, ৫) আলাদা চেনা যায়।

একটি network-এ কোনো চক্র থাকতে পারে না — “A-র আগে B, B-র আগে A” অসম্ভব। অর্থাৎ network হলো একটি DAG (directed acyclic graph) — Git-এর commit graph-এর মতোই। আর DAG-এর node-গুলোকে নির্ভরতার ক্রমে সাজানোর অ্যালগরিদম হলো topological sort; DSA কোর্সে এর প্রমাণ আর Kahn-এর পদ্ধতি আছে (Topological sort আর DAG, পটভূমির জন্য গ্রাফের পরিভাষা)।

৪ · CPM — forward pass, backward pass আর float

Critical path method (CPM) দুটি প্রশ্নের উত্তর দেয়: পুরো project কমপক্ষে কত দিনে শেষ হবে, আর কোন কাজ কতটা দেরি সইতে পারবে। প্রতিটি activity-র জন্য চারটি সংখ্যা বের করা হয়:

সংক্ষেপপুরো নামহিসাব
ESEarliest start — সবচেয়ে আগে কখন শুরুসব পূর্বসূরির EF-এর সর্বোচ্চ (শুরুর activity-র জন্য ০)
EFEarliest finish — সবচেয়ে আগে কখন শেষES + সময়
LFLatest finish — শেষ তারিখ না পিছিয়ে সবচেয়ে দেরিতে কখন শেষসব উত্তরসূরির LS-এর সর্বনিম্ন (শেষের activity-র জন্য project-এর সময়)
LSLatest start — সবচেয়ে দেরিতে কখন শুরুLF − সময়
TFTotal float (slack)LS − ES = LF − EF
FFFree floatউত্তরসূরিদের সর্বনিম্ন ES − নিজের EF

ES/EF বের করা হয় শুরু থেকে শেষের দিকে — forward pass; LS/LF বের করা হয় শেষ থেকে শুরুর দিকে — backward pass. মনে রাখার কৌশল: সামনে যেতে বড়টি নিন (সব পূর্বসূরি শেষ না হলে শুরু করা যায় না), পেছনে যেতে ছোটটি নিন (যে উত্তরসূরি সবচেয়ে আগে শুরু হতে হবে, সে-ই সীমা ঠিক করে)। এখানে “দিন ০ থেকে শুরু” রীতি নেওয়া হয়েছে: ES = ০, সময় ২ হলে EF = ২। কিছু বই “দিন ১ থেকে শুরু” রীতি নেয় (তখন ES = ১, EF = ২); উত্তর একই থাকে, শুধু লেখা আলাদা — পরীক্ষায় যে রীতি নেবেন, শুরুতেই লিখে দিন।

প্রথমে একটি ছোট network-এ হাতে-কলমে দেখি — একটি login feature-এর ছয়টি কাজ (কাল্পনিক)। প্রতিটি বাক্সে ওপরে ES ও EF, নিচে LS, float (F) ও LF. “পরে” চেপে এগোন; কমলা দাগ দেখাবে কোন বাক্সের হিসাব চলছে।

ES –EF –P · নকশা ২LS –LF – ES –EF –Q · Backend ৪LS –LF – ES –EF –R · UI ৩LS –LF – ES –EF –S · Test লেখা ২LS –LF – ES –EF –T · Integrate ২LS –LF – ES –EF –U · Release ১LS –LF –
  1. শুরুর অবস্থা। P (নকশা, ২ দিন) সবার আগে। তারপর তিনটি কাজ একসাথে চলতে পারে: Q (৪), R (৩), S (২)। T (২) লাগে Q আর R দুটোর পরে; U (১) লাগে T আর S-এর পরে। এখনো কোনো সংখ্যা জানা নেই।
  2. Forward pass শুরু — P. P-র কোনো পূর্বসূরি নেই, তাই ES = ০, EF = ০ + ২ = ২।
  3. Q, R, S. তিনটিরই একমাত্র পূর্বসূরি P, তাই তিনটির ES = ২। EF: Q = ২ + ৪ = ৬, R = ২ + ৩ = ৫, S = ২ + ২ = ৪।
  4. T — দুটি পূর্বসূরি। T-কে Q আর R দুটোর জন্যই অপেক্ষা করতে হবে। ES = max(৬, ৫) = ৬, EF = ৮। এখানেই “সামনে যেতে বড়টি” নিয়ম।
  5. U — forward pass শেষ। ES = max(T-র EF ৮, S-এর EF ৪) = ৮, EF = ৯। পুরো project-এর ন্যূনতম সময় ৯ দিন.
  6. Backward pass — U, T, S. U শেষের activity, তাই LF = ৯, LS = ৯ − ১ = ৮। T আর S-এর একমাত্র উত্তরসূরি U, তাই দুটোরই LF = U-র LS = ৮। LS: T = ৮ − ২ = ৬, S = ৮ − ২ = ৬।
  7. Q, R, তারপর P. Q আর R-এর উত্তরসূরি T, তাই LF = ৬; LS: Q = ৬ − ৪ = ২, R = ৬ − ৩ = ৩। P-র তিন উত্তরসূরির LS ২, ৩ আর ৬; “পেছনে যেতে ছোটটি” — LF = min(২, ৩, ৬) = ২, LS = ০।
  8. Float আর critical path. F = LS − ES: P ০, Q ০, R ১, S ৪, T ০, U ০। Float শূন্য এমন কাজগুলো P → Q → T → U = ২ + ৪ + ২ + ১ = ৯ দিন — এটিই critical path (লাল)। R এক দিন আর S চার দিন দেরি করলেও শেষ তারিখ বদলাবে না।

এবার আমাদের নয়টি activity-র পুরো network. একই নিয়মে হিসাব করলে ছবির সংখ্যাগুলো পাওয়া যায়:

স্কুল ফলাফল অ্যাপের AON network — critical path লাল

Each box: ES · duration · EF on top, LS · float · LF below

০৪ দিন৪A · চাহিদা০F ০৪ ৪৩ দিন৭B · DB নকশা৪F ০৭ ৪৫ দিন৯C · UI নকশা৫F ১১০ ৭৬ দিন১৩D · Backend৭F ০১৩ ৭৪ দিন১১F · Grading৯F ২১৩ ৯৩ দিন১২E · Frontend১০F ১১৩ ১৩৩ দিন১৬G · Integration১৩F ০১৬ ১৬৪ দিন২০H · Testing১৬F ০২০ ২০২ দিন২২I · Release২০F ০২২
ছবি ৬১.২ — প্রতিটি বাক্সে ওপরে ES, সময়, EF; নিচে LS, float (F), LF. Critical path A → B → D → G → H → I, মোট ২২ দিন। C আর E-এর float ১ দিন, F-এর ২ দিন।

Total float বনাম free float — সূক্ষ্ম কিন্তু পরীক্ষার প্রিয়

C-এর total float ১ দিন: C এক দিন দেরি করলে project-এর শেষ তারিখ বদলায় না। কিন্তু C-এর free float শূন্য — কারণ C-এর EF ৯ আর তার উত্তরসূরি E-র ES-ও ৯। C এক দিন দেরি করলে E-কেও এক দিন পিছাতে হয়, আর তখন E-র নিজের float খেয়ে ফেলা হয়। অর্থাৎ C আর E একটি float ভাগ করে নিচ্ছে: পথ A → C → E → G-তে মোট বাড়তি সময় মাত্র ১ দিন। E-র ক্ষেত্রে total float আর free float দুটোই ১, কারণ E-র পরে G-এর ES ১৩ আর E-র EF ১২। F-এর দুটোই ২।

A → C → E → G → H → I পথটির দৈর্ঘ্য ২১ দিন — critical path-এর চেয়ে মাত্র ১ দিন কম। একে বলে near-critical path. এখানে একটু দেরিতেই পথটি নতুন critical path হয়ে যাবে। তাই ভালো পরিকল্পনাকারী শুধু critical path নয়, কম float-এর পথগুলোও ঝুঁকির তালিকায় রাখেন — পর্ব ৬২-এর (risk আর quality management) risk register-এ এর জায়গা।

এবার পুরো হিসাবটি কোডে। নিচের প্রোগ্রাম Kahn-এর অ্যালগরিদমে topological order বানায়, সেই ক্রমে forward pass, উল্টো ক্রমে backward pass করে, তারপর float-এর টেবিল আর সব critical path ছাপে:

// CPM on a 9-activity AON network (fictional school result app), in days.
// activity: [duration, predecessors]
const acts = {
  A: [4, []], B: [3, ["A"]], C: [5, ["A"]], D: [6, ["B"]], E: [3, ["C"]],
  F: [4, ["B"]], G: [3, ["D", "E", "F"]], H: [4, ["G"]], I: [2, ["H"]] };
const ids = Object.keys(acts), succ = {}, indeg = {};
for (const k of ids) { succ[k] = []; indeg[k] = acts[k][1].length; }
for (const k of ids) for (const p of acts[k][1]) succ[p].push(k);
// Kahn's algorithm: take an activity once all its predecessors are placed
const order = [], ready = ids.filter(k => indeg[k] === 0);
while (ready.length) { const k = ready.shift(); order.push(k);
  for (const s of succ[k]) if (--indeg[s] === 0) ready.push(s); }
console.log("topological order:", order.join(" "));
const ES = {}, EF = {}, LS = {}, LF = {};
for (const k of order) {                         // forward pass
  ES[k] = Math.max(0, ...acts[k][1].map(p => EF[p])); EF[k] = ES[k] + acts[k][0]; }
const T = Math.max(...ids.map(k => EF[k]));
for (const k of [...order].reverse()) {          // backward pass
  LF[k] = Math.min(T, ...succ[k].map(s => LS[s])); LS[k] = LF[k] - acts[k][0]; }
console.log("act dur  ES  EF  LS  LF  TF  FF");
for (const k of order) {
  const ff = Math.min(T, ...succ[k].map(s => ES[s])) - EF[k];   // free float
  console.log([k, acts[k][0], ES[k], EF[k], LS[k], LF[k], LS[k] - ES[k], ff]
    .map((v, i) => String(v).padStart(i ? 4 : 3)).join(""));
}
// critical path(s): chains of zero-float activities that touch end to end
const crit = k => LS[k] === ES[k];
const walk = (k, path) => succ[k].length === 0 ? [path] : succ[k]
  .filter(s => crit(s) && ES[s] === EF[k]).flatMap(s => walk(s, [...path, s]));
const starts = ids.filter(k => acts[k][1].length === 0 && crit(k));
console.log("project duration:", T, "days");
console.log("critical path(s):", starts.flatMap(s => walk(s, [s])).map(p => p.join("-")).join(", "));

আউটপুট:

topological order: A B C D F E G H I
act dur  ES  EF  LS  LF  TF  FF
  A   4   0   4   0   4   0   0
  B   3   4   7   4   7   0   0
  C   5   4   9   5  10   1   0
  D   6   7  13   7  13   0   0
  F   4   7  11   9  13   2   2
  E   3   9  12  10  13   1   1
  G   3  13  16  13  16   0   0
  H   4  16  20  16  20   0   0
  I   2  20  22  20  22   0   0
project duration: 22 days
critical path(s): A-B-D-G-H-I

যেকোনো বৈধ topological order-এ ফল একই। টেবিলের প্রতিটি সংখ্যা ছবি ৬১.২-এর সাথে মেলে: C-এর TF ১ কিন্তু FF ০ (float-টি E-র সাথে ভাগাভাগি), F-এর দুটোই ২। Critical path A-B-D-G-H-I, ২২ দিন। এবার E: [3, ["C"]]-কে E: [4, ["C"]] করে চালিয়ে দেখুন: শেষ লাইনে দুটি critical path আসবে — A-B-D-G-H-I, A-C-E-G-H-I — কারণ near-critical পথটির একমাত্র float-দিনটি E খেয়ে ফেলেছে। Math.max(0, ...)-এর ভেতরের 0-টি ভুলে গেলে কী হয়, তা অনুশীলন ৪-এ দেখবেন।

অল্প কথায় গ্রাফের ভাষায়: critical path হলো DAG-এর সবচেয়ে লম্বা পথ (ওজন = সময়)। সাধারণ graph-এ longest path কঠিন সমস্যা, কিন্তু DAG-এ topological order ধরে একবার ঘুরলেই হয় — O(V + E) সময়ে। Forward pass আসলে এই dynamic programming.

৫ · PERT — তিনটি অনুমান থেকে সম্ভাবনা

CPM ধরে নেয় প্রতিটি কাজের সময় নিশ্চিত। Software-এ তা প্রায় কখনো সত্য নয় — testing-এ কত bug বেরোবে, কেউ আগে জানেন না। PERT প্রতিটি activity-র জন্য একটি সংখ্যার বদলে তিনটি নেয় — একটি three-point estimate:

  • a — optimistic: সব ঠিকঠাক চললে সবচেয়ে কম সময়
  • m — most likely: সবচেয়ে সম্ভাব্য সময়
  • b — pessimistic: অনেক কিছু খারাপ হলে (কিন্তু অসম্ভব বিপর্যয় নয়) সবচেয়ে বেশি সময়

পর্ব ৬০-এ (software estimation) প্রতিটি task-এর three-point অনুমান কীভাবে নেওয়া হয়, তা দেখবেন। এখানে আমাদের কাজ তার পরের ধাপ — task-গুলোর অনুমান জুড়ে পুরো schedule-এর সম্ভাবনা বের করা। সূত্রগুলো:

te = (a + 4m + b) / 6   ·   σ² = ((b − a) / 6)²

এরপর critical path ধরে: project-এর প্রত্যাশিত সময় μ = পথের te-গুলোর যোগফল, variance = পথের σ²-গুলোর যোগফল (activity-গুলো পরস্পর-নিরপেক্ষ ধরে), আর standard deviation σ = √Σσ². Central limit theorem-এর যুক্তিতে মোট সময়কে মোটামুটি normal বণ্টন ধরা হয়। তাহলে T দিনের মধ্যে শেষ হওয়ার সম্ভাবনা:

Z = (T − μ) / σ   →   P(সময় ≤ T) = Φ(Z)

এখানে Φ হলো standard normal-এর cumulative distribution — পরীক্ষায় normal table থেকে পড়া হয়, কোডে math.erf দিয়ে: Φ(z) = ½(১ + erf(z/√২))। Z-score বলে T গড় থেকে কত σ দূরে। কয়েকটি মান মুখস্থ রাখলে কাজে লাগে: Φ(০) = ০.৫, Φ(১) ≈ ০.৮৪১৩, Φ(১.৬৪৫) ≈ ০.৯৫, Φ(২) ≈ ০.৯৭৭২, আর Φ(−z) = ১ − Φ(z).

প্রচলিত বর্ণনা অনুযায়ী PERT তৈরি হয় ১৯৫৭–৫৮ সালে, US Navy-র Special Projects Office-এ Polaris ক্ষেপণাস্ত্র কর্মসূচির জন্য — পরামর্শক প্রতিষ্ঠান Booz Allen Hamilton আর Lockheed-এর সহায়তায়। প্রায় একই সময়ে (১৯৫৬–৫৭ সালের দিকে) রাসায়নিক কোম্পানি DuPont-এর Morgan Walker আর Remington Rand-এর James Kelley কারখানার রক্ষণাবেক্ষণের কাজ সাজাতে CPM গড়ে তোলেন; তাঁদের পরিচিত প্রবন্ধ “Critical-Path Planning and Scheduling” ১৯৫৯ সালে প্রকাশিত। সন তারিখ উৎসভেদে এক-দুই বছর এদিক-ওদিক পাওয়া যায়।

আমাদের অ্যাপের প্রতিটি activity-র (a, m, b) এমনভাবে নেওয়া হয়েছে যে te ঠিক অংশ ৪-এর সময়গুলোর সমান — তাই critical path একই থাকে। খেয়াল করুন H (Testing)-এর অনুমান (২, ৩, ১০) — ডান দিকে লম্বা লেজ, কারণ testing-এ বড় bug বেরোলে অনেক দিন লাগতে পারে। প্রশ্ন: project ২৪ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা কত?

Critical path A-B-D-G-H-I · (a, m, b): A (২,৪,৬) · B (২,৩,৪) · D (৩,৬,৯) · G (২,৩,৪) · H (২,৩,১০) · I (১,২,৩)
te = (a+4m+b)/6
μ = Σ te
σ² = ((b−a)/6)²
σ = √Σσ²
Z
উত্তর
  1. তথ্য। CPM থেকে critical path জানা: A-B-D-G-H-I. প্রতিটির তিনটি অনুমান ওপরে। প্রশ্ন: ২৪ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা।
  2. প্রত্যাশিত সময়। যেমন H: (২ + ৪×৩ + ১০) ÷ ৬ = ২৪ ÷ ৬ = ৪। লক্ষ করুন, H-এর most likely ৩ হলেও te ৪ — লম্বা লেজ গড়কে টেনেছে।
  3. Project-এর গড়। μ = ৪ + ৩ + ৬ + ৩ + ৪ + ২ = ২২ দিন। মানে প্রায় ৫০% সম্ভাবনায় ২২ দিনে — “২২ দিনে শেষ হবে” বলা মানে মুদ্রা ছোঁড়ার মতো প্রতিশ্রুতি।
  4. প্রতিটির variance. H: ((১০ − ২) ÷ ৬)² = (১.৩৩৩)² ≈ ১.৭৭৮; D: (৬ ÷ ৬)² = ১। মোট অনিশ্চয়তার অর্ধেক আসছে শুধু H থেকে।
  5. যোগ করুন variance, তারপর বর্গমূল। Σσ² = ০.৪৪৪ + ০.১১১ + ১ + ০.১১১ + ১.৭৭৮ + ০.১১১ = ৩.৫৫৬; σ = √৩.৫৫৬ ≈ ১.৮৮৬। সাধারণ ভুল: σ-গুলো সরাসরি যোগ করা — যোগ হয় variance, standard deviation নয়।
  6. Z-score. Z = (২৪ − ২২) ÷ ১.৮৮৬ ≈ ১.০৬ — ২৪ দিন গড় থেকে প্রায় ১.০৬ σ ডানে।
  7. Normal table. Φ(১.০৬) ≈ ০.৮৫৫৪। অর্থাৎ ২৪ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা প্রায় ৮৫.৫% (দশমিক না কেটে হিসাব করলে ০.৮৫৫৬)।
  8. উল্টো প্রশ্ন। প্রধান শিক্ষক ৯৫% নিশ্চয়তার তারিখ চাইলে: Φ(Z) = ০.৯৫ ⇒ Z ≈ ১.৬৪৫, তাই T = μ + Zσ = ২২ + ১.৬৪৫ × ১.৮৮৬ ≈ ২৫.১ দিন — মানে ২৬তম দিনের শুরুতে। ৫০%-এর তারিখ থেকে ৯৫%-এর তারিখ তিন দিনেরও বেশি দূরে।

এবার একই হিসাব Python-এ, কয়েকটি T-এর জন্য, আর ৯৫%-এর তারিখ একটি সরল খোঁজ দিয়ে। শেষ অংশে একটি Monte Carlo simulation: প্রতিটি activity-র সময় একটি beta-PERT বণ্টন থেকে এলোমেলোভাবে নিয়ে (নির্দিষ্ট seed-এ) ৫০,০০০ বার পুরো network চালানো হয় — এখানে শুধু critical path নয়, সব পথ প্রতিযোগিতা করে।

import math, random
# activity: (optimistic a, most likely m, pessimistic b, predecessors), in days
acts = {"A": (2, 4, 6, ""), "B": (2, 3, 4, "A"), "C": (3, 5, 7, "A"), "D": (3, 6, 9, "B"),
        "E": (1, 3, 5, "C"), "F": (2, 4, 6, "B"), "G": (2, 3, 4, "DEF"),
        "H": (2, 3, 10, "G"), "I": (1, 2, 3, "H")}
te = {k: (a + 4 * m + b) / 6 for k, (a, m, b, _) in acts.items()}
var = {k: ((b - a) / 6) ** 2 for k, (a, m, b, _) in acts.items()}
print("  ".join(f"{k}:{te[k]:.0f}/{var[k]:.3f}" for k in acts))
crit = "ABDGHI"                        # critical path found by the CPM pass
mu = sum(te[k] for k in crit)
sigma = math.sqrt(sum(var[k] for k in crit))
Phi = lambda z: 0.5 * (1 + math.erf(z / math.sqrt(2)))    # standard normal CDF
print(f"critical path {crit}: mu={mu:.2f} days, var={sigma**2:.3f}, sigma={sigma:.3f}")
for T in (20, 22, 23, 24, 25):
    z = (T - mu) / sigma
    print(f"  P(finish <= {T}) : z={z:+.3f}  p={Phi(z):.4f}")
T = mu                                 # inverse search: smallest T (0.01 steps), p >= 0.95
while Phi((T - mu) / sigma) < 0.95:
    T += 0.01
print(f"95% sure by about {T:.2f} days")
# merge bias: simulate beta-PERT durations so that ALL paths compete
random.seed(61)
N, hit, total = 50000, 0, 0.0
def draw(a, m, b):
    return a + (b - a) * random.betavariate(1 + 4 * (m - a) / (b - a), 1 + 4 * (b - m) / (b - a))
for _ in range(N):
    fin = {}
    for k, (a, m, b, pre) in acts.items():      # dict order is a topological order here
        fin[k] = max((fin[p] for p in pre), default=0) + draw(a, m, b)
    hit += fin["I"] <= 24
    total += fin["I"]
print(f"simulated: mean={total / N:.2f} days, P(finish <= 24)={hit / N:.3f}")

আউটপুট:

A:4/0.444  B:3/0.111  C:5/0.444  D:6/1.000  E:3/0.444  F:4/0.444  G:3/0.111  H:4/1.778  I:2/0.111
critical path ABDGHI: mu=22.00 days, var=3.556, sigma=1.886
  P(finish <= 20) : z=-1.061  p=0.1444
  P(finish <= 22) : z=+0.000  p=0.5000
  P(finish <= 23) : z=+0.530  p=0.7021
  P(finish <= 24) : z=+1.061  p=0.8556
  P(finish <= 25) : z=+1.591  p=0.9442
95% sure by about 25.11 days
simulated: mean=22.28 days, P(finish <= 24)=0.821

প্রথম অংশ stepper-এর সাথে মেলে: μ = ২২, σ ≈ ১.৮৮৬, P(≤ ২৪) ≈ ০.৮৫৫৬। ৯৫%-এর তারিখ সূত্রে ২৫.১০, কিন্তু খোঁজে ২৫.১১ এসেছে — কারণ ০.০১ দিনের ধাপে প্রথম যে মান ৯৫% ছাড়ায়, সেটি ২৫.১১। শেষ লাইনটিই সবচেয়ে গুরুত্বপূর্ণ: সব পথ একসাথে চালালে গড় সময় ২২ নয়, ২২.২৮ দিন, আর ২৪ দিনের মধ্যে শেষের সম্ভাবনা ৮৫.৬% নয়, প্রায় ৮২.১%. PERT-এর সূত্র শুধু একটি পথ দেখে বলে আশাবাদী। Simulation-এর সংখ্যা ধরে নেওয়া বণ্টনের ওপর নির্ভর করে — seed বা বণ্টন বদলালে সামান্য বদলাবে, কিন্তু দিকটি একই থাকবে।

PERT-এর সীমা — merge bias আর অন্যান্য ধারণা

আমাদের near-critical পথ A-C-E-G-H-I-এর গড় ২১, σ ≈ ১.৮২৬; একা এটি ২৪ দিনে শেষ হওয়ার সম্ভাবনা প্রায় ৯৫%. Project শেষ হয় তখনই, যখন সব পথ শেষ। কোনো দিন critical path তাড়াতাড়ি শেষ হলো কিন্তু UI-এর পথ দেরি করল — তখনো project দেরি। একে বলে merge bias: যে বিন্দুতে কয়েকটি পথ মেলে (এখানে G), সেখানে প্রকৃত সময় সবচেয়ে লম্বা গড়-পথের চেয়ে বেশি হওয়ার প্রবণতা থাকে। ১৯৬০-এর দশকেই গবেষকেরা (যেমন MacCrimmon ও Ryavec, ১৯৬৪ সালের দিকে) PERT-এর ধারণাগুলোর এই দুর্বলতা বিশ্লেষণ করেন। অন্য সীমাগুলো:

  • স্বাধীনতার ধারণা: variance যোগ করা যায় শুধু activity-গুলো পরস্পর-নিরপেক্ষ হলে। বাস্তবে একই কারণ (একজন অভিজ্ঞ developer অসুস্থ, requirement অস্পষ্ট) অনেক কাজকে একসাথে দেরি করায়।
  • (b − a)/6 একটি অনুমান: beta বণ্টনের জন্য একটি সুবিধাজনক সরলীকরণ; আর a, b নিজেই মানুষের অনুমান, প্রায়ই খুব সরু।

তাই আধুনিক চর্চায় Monte Carlo schedule simulation বেশি ব্যবহৃত হয়। তবু PERT-এর সূত্র পরীক্ষায় সবচেয়ে বেশি আসে, আর এর মূল শিক্ষাটি মূল্যবান: একটি তারিখ নয়, সম্ভাবনাসহ তারিখ বলুন।

৬ · Schedule ছোট করা — crashing আর fast-tracking

প্রধান শিক্ষক জানালেন, শিক্ষা অফিসের পরিদর্শন এগিয়ে এসেছে — অ্যাপ ২২ নয়, ১৯ দিনে চাই। Scope কাটা যাবে না। দুটি প্রচলিত কৌশল আছে।

Crashing মানে টাকা দিয়ে সময় কেনা: বাড়তি developer, overtime, দ্রুত server ভাড়া। প্রতিটি activity-র একটি normal সময় ও খরচ আর একটি crash সময় ও খরচ থাকে — যার কমে আর নামানো যায় না। এক দিন কমানোর খরচের হার হলো cost slope:

Cost slope = (crash খরচ − normal খরচ) ÷ (normal সময় − crash সময়)

যেমন D (Backend): normal ৬ দিনে ৯০ হাজার টাকা, crash ৪ দিনে ১১৪ হাজার — slope = (১১৪ − ৯০) ÷ (৬ − ৪) = ১২ হাজার টাকা প্রতি দিন। আমাদের project-এর slope-গুলো (হাজার টাকা প্রতি দিন; বন্ধনীতে normal → crash সময়): A ৩০ (৪→৩), B ১০ (৩→২), C ৮ (৫→৪), D ১২ (৬→৪), E ৬ (৩→২), F ৫ (৪→৩), G ২৫ (৩→২), H ১৫ (৪→৩), I কমানো যায় না (২)। Normal খরচের মোট ৩৯০ হাজার টাকা।

নিয়ম তিনটি: (১) শুধু critical activity কমালে project ছোট হয় — F-এর slope সবচেয়ে কম (৫), কিন্তু F critical নয়, তাই F কমানো টাকা নষ্ট। (২) Critical activity-গুলোর মধ্যে সবচেয়ে কম slope-এরটি এক দিন কমান। (৩) প্রতিবার critical path নতুন করে দেখুন — একটি কমাতেই আরেকটি পথ critical হয়ে যেতে পারে, তখন সব critical পথ একসাথে কমাতে হয়।

তিনটি পথের দৈর্ঘ্য (দিন) আর খরচ (হাজার টাকা) · পরোক্ষ খরচ দিনে ১৯
A-B-D-G-H-I
A-C-E-G-H-I
A-B-F-G-H-I
Project-এর সময়
সরাসরি খরচ
মোট (সরাসরি + ১৯ × দিন)
বিকল্প
সিদ্ধান্ত
  1. শুরু। তিনটি পথ: ২২, ২১ আর ২০ দিন। Project ২২ দিন, সরাসরি খরচ ৩৯০। ধরা যাক অফিস ভাড়া, ব্যবস্থাপনা ইত্যাদি পরোক্ষ খরচ দিনে ১৯ হাজার — তাই মোট ৩৯০ + ১৯ × ২২ = ৮০৮।
  2. Critical path-এ বিকল্প। শুধু A-B-D-G-H-I critical. এর activity-গুলোর slope: A ৩০, B ১০, D ১২, G ২৫, H ১৫; I কমানো যায় না। সবচেয়ে সস্তা B. (F-এর slope ৫ হলেও সে এই পথে নেই।)
  3. B এক দিন কমল। খরচ +১০ = ৪০০। এখন A-B-D-G-H-I = ২১, আর B যে পথে আছে সেই A-B-F-G-H-I-ও ১৯। A-C-E-G-H-I আগের মতোই ২১। Project ২১ দিন, মোট ৪০০ + ৩৯৯ = ৭৯৯।
  4. এবার দুটি critical path! দুটোকেই এক দিন কমাতে হবে, নইলে project ছোট হবে না। বিকল্প: দুই পথের সাধারণ activity — H (১৫), G (২৫), A (৩০); অথবা প্রতিটি পথ থেকে একটি করে — D+E (১২ + ৬ = ১৮), D+C (১২ + ৮ = ২০)। B আর কমানো যায় না। সবচেয়ে সস্তা H (১৫)।
  5. H এক দিন কমল। তিনটি পথই এক দিন কমে: ২০, ২০, ১৮। খরচ ৪১৫, মোট ৪১৫ + ৩৮০ = ৭৯৫। পরের সস্তা বিকল্প D+E (১৮) — তাতে ১৯ দিন, সরাসরি খরচ ৪৩৩, মোট ৭৯৪।
  6. কোথায় থামবেন? প্রতিটি দিন কমালে পরোক্ষ খরচ ১৯ বাঁচে। যতক্ষণ crash-এর খরচ ১৯-এর কম (১০, ১৫, ১৮), মোট খরচ কমে। পরের ধাপ C+D (২০) করলে মোট বেড়ে ৭৯৫ হবে। তাই মোট খরচের দিক থেকে সেরা ১৯ দিন — আর এটিই প্রধান শিক্ষকের লক্ষ্য। এর চেয়ে ছোট করতে হলে টাকা বেশি লাগবে।

দুটি পথ critical হলে “সব critical পথ কাটে এমন সবচেয়ে সস্তা activity-সেট” খুঁজতে হয়। ছোট network-এ সব সম্ভাব্য সেট পরীক্ষা করে দেখাই যথেষ্ট — নিচের প্রোগ্রাম তাই করে:

// Crashing: shorten the project 1 day at a time for the least extra money.
// activity: [normal days, crash days, cost slope in thousand taka per day]
const A = { A: [4, 3, 30], B: [3, 2, 10], C: [5, 4, 8], D: [6, 4, 12], E: [3, 2, 6],
            F: [4, 3, 5], G: [3, 2, 25], H: [4, 3, 15], I: [2, 2, 0] };
const paths = ["ABDGHI", "ACEGHI", "ABFGHI"];      // every start-to-end path
const dur = {}; for (const k in A) dur[k] = A[k][0];
const len = p => [...p].reduce((s, k) => s + dur[k], 0);
const INDIRECT = 19, TARGET = 18;                  // overhead per day, goal in days
let direct = 390;                                  // sum of normal (direct) costs
function report() {
  const T = Math.max(...paths.map(len));
  console.log(`T=${T}  direct=${direct}  indirect=${INDIRECT * T}  total=${direct + INDIRECT * T}`);
  return T;
}
let T = report();
while (T > TARGET) {
  const crit = paths.filter(p => len(p) === T);
  const can = Object.keys(A).filter(k => dur[k] > A[k][1]);   // still crashable
  let best = null;              // cheapest set that shortens EVERY critical path
  for (let mask = 1; mask < 1 << can.length; mask++) {
    const set = can.filter((_, i) => (mask >> i) & 1);
    if (!crit.every(p => set.some(k => p.includes(k)))) continue;
    const cost = set.reduce((s, k) => s + A[k][2], 0);
    if (!best || cost < best.cost || (cost === best.cost && set.length < best.set.length))
      best = { set, cost };
  }
  if (!best) { console.log("no way to crash further"); break; }
  console.log(`  critical: ${crit.join(", ")} -> crash ${best.set.join("+")} by 1 day (+${best.cost})`);
  best.set.forEach(k => dur[k]--); direct += best.cost;
  T = report();
}

আউটপুট:

T=22  direct=390  indirect=418  total=808
  critical: ABDGHI -> crash B by 1 day (+10)
T=21  direct=400  indirect=399  total=799
  critical: ABDGHI, ACEGHI -> crash H by 1 day (+15)
T=20  direct=415  indirect=380  total=795
  critical: ABDGHI, ACEGHI -> crash D+E by 1 day (+18)
T=19  direct=433  indirect=361  total=794
  critical: ABDGHI, ACEGHI -> crash C+D by 1 day (+20)
T=18  direct=453  indirect=342  total=795

প্রথম তিন ধাপ stepper-এর সাথে হুবহু মেলে: B (+১০), H (+১৫), D+E (+১৮)। মোট খরচ সবচেয়ে কম ১৯ দিনে — ৭৯৪। ১৮ দিনে যেতে C+D (+২০) লাগে, যা দৈনিক পরোক্ষ খরচ ১৯-এর বেশি, তাই মোট বেড়ে ৭৯৫। খেয়াল করুন ১৮ দিনে A-B-F-G-H-I-ও ১৮ — তিনটি পথই তখন critical, পরের ধাপ আরও দামি হবে। TARGET ১০ করে দেখুন: ১৭ দিনে যেতে G (+২৫), ১৬-তে A (+৩০), তারপর “no way to crash further” — critical path-এর সব activity তখন crash সময়ে পৌঁছে গেছে, আর মোট খরচ বেড়ে ৮১২।

Fast-tracking দ্বিতীয় কৌশল: ক্রমানুসারে হওয়ার কথা এমন কাজ আংশিক একসাথে চালানো — যেমন UI নকশা পুরো অনুমোদনের আগেই frontend-এর কোড শুরু (FS-এর বদলে SS বা lead). টাকা প্রায় লাগে না, কিন্তু rework-এর ঝুঁকি বাড়ে: নকশা বদলালে লেখা কোড ফেলে দিতে হয়। আর software-এ crashing-এর একটি বিশেষ ফাঁদ আছে — দেরি হওয়া project-এ নতুন মানুষ যোগ করলে শেখানো আর যোগাযোগের খরচে কাজ আরও পিছিয়ে যেতে পারে (Brooks-এর সূত্র, The Mythical Man-Month, ১৯৭৫)।

৭ · Resource levelling আর Gantt chart

CPM ধরে নেয় যত লোক দরকার, তত পাওয়া যাবে। বাস্তবে দলে নির্দিষ্ট সংখ্যক developer. অংশ ৪-এর ছোট network-এ ধরা যাক প্রতিটি কাজে developer লাগে: P ১, Q ২, R ১, S ১, T ২, U ১। সবাই ES-এ শুরু করলে প্রতিদিন কতজন লাগবে, তার resource histogram:

দিন০১২৩৪৫৬৭৮
সবাই ES-এ (আগে)১১৪৪৩২২২১
S দিন ৫-এ শুরু (পরে)১১৩৩৩৩৩২১

দিন ২–৩-এ চারজন লাগছে (Q-র দুজন, R আর S-এর একজন করে), অথচ বাকি দিনে দুই-তিনজন। S-এর float ৪ দিন — তাই S-কে তিন দিন পিছিয়ে, দিন ৫-এ শুরু করলে (তখনো ১ দিন float বাকি) চূড়া ৪ থেকে ৩-এ নামে, আর project-এর সময় ৯ দিনই থাকে। মোট কাজ দুই সারিতেই ২০ developer-দিন — শুধু সাজানো বদলেছে। একে বলে resource levelling (float-এর ভেতরে থাকলে অনেকে বলেন resource smoothing). কিন্তু দলে যদি মাত্র ২ জন থাকেন, float দিয়ে আর হবে না: ২০ developer-দিনের কাজে কমপক্ষে ১০ দিন লাগবে — অর্থাৎ সম্পদের সীমা নিজেই project লম্বা করবে, আর critical path তখন শুধু নির্ভরতা দিয়ে নয়, মানুষ দিয়েও ঠিক হয়।

Gantt chart — schedule-এর ছবি

Network diagram নির্ভরতা দেখাতে ভালো, কিন্তু “আজ কী চলার কথা?” প্রশ্নের উত্তর দেয় Gantt chart: আড়াআড়ি সময়ের অক্ষ, প্রতিটি activity একটি দণ্ড। সাথে থাকে milestone (শূন্য সময়ের গুরুত্বপূর্ণ বিন্দু, সাধারণত ◆ চিহ্নে), নির্ভরতার তীর, আর দিন ১২-র অবস্থায় প্রকৃত অগ্রগতি:

স্কুল ফলাফল অ্যাপের Gantt chart — baseline বনাম প্রকৃত, দিন ১২-তে

Planned bars (red = critical), dashed float, thin green bars = actual, ◆ = milestone

০ ৪ ৮ ১২ ১৬ ২০ ২২ A B C D E F G H I ◆ SRS অনুমোদন ◆ Release (দিন ২২) আজ (দিন ১২) criticalnon-criticalfloatপ্রকৃত
ছবি ৬১.৩ — B এক দিন দেরিতে (দিন ৮-এ) শেষ হয়েছে, তাই critical activity D-ও এক দিন দেরিতে শুরু হয়েছে। B থেকে D-তে তীরটি finish-to-start নির্ভরতা। C, E, F-এর পরের ড্যাশ-দেওয়া অংশ তাদের float.

এখানে দুটি স্তর আছে। মোটা দণ্ডগুলো schedule baseline — অনুমোদিত মূল পরিকল্পনার স্থির কপি; পর্ব ২৪-এর requirement baseline-এর মতোই, এটি শুধু আনুষ্ঠানিক অনুমোদনে বদলায়। সরু সবুজ দণ্ড প্রকৃত অবস্থা। ছবি থেকেই বোঝা যায়: D এক দিন দেরিতে শুরু, আর D critical — তাই কিছু না করলে release ২২ নয়, ২৩ দিনে। F-ও এক দিন দেরিতে শুরু, কিন্তু তার float ২ দিন, তাই বিপদ নেই।

Gantt chart-এর দুর্বলতা: দণ্ডগুলো নিশ্চিত দেখায়, অথচ পেছনে অনুমান। অনেক tool নির্ভরতার তীর লুকিয়ে রাখে, তখন কোন দেরি কাকে ধাক্কা দেবে, বোঝা যায় না।

৮ · Earned value — পরিকল্পনা বনাম বাস্তব, টাকার ভাষায়

দিন ১২-তে হিসাবরক্ষক বললেন, “বাজেটের ২৪৩ হাজার খরচ হয়েছে, পরিকল্পনায় এই সময়ে ২৭৫ হাজার খরচ হওয়ার কথা — তাহলে আমরা টাকা বাঁচাচ্ছি!” কথাটি বিপজ্জনকভাবে ভুল হতে পারে, কারণ এতে বলা নেই কতটা কাজ হয়েছে। Earned value management (EVM) তিনটি সংখ্যা মিলিয়ে এই ফাঁক বন্ধ করে:

নামঅর্থ / সূত্রকীভাবে পড়বেন
PV (planned value)এ তারিখ পর্যন্ত baseline অনুযায়ী যত কাজ হওয়ার কথা, তার বাজেট“কতটা কাজ হওয়ার কথা”
EV (earned value)যত কাজ আসলে হয়েছে, তার বাজেট-মূল্য = Σ (বাজেট × % শেষ)“কতটা কাজ হয়েছে”
AC (actual cost)সেই কাজে আসলে যত খরচ“কত টাকা গেছে”
SV, CVSV = EV − PV; CV = EV − ACঋণাত্মক = পিছিয়ে / বাজেট ছাড়িয়ে
SPI, CPISPI = EV ÷ PV; CPI = EV ÷ AC১-এর কম = খারাপ, ১-এর বেশি = ভালো
BAC, EACBAC = মোট বাজেট; একটি প্রচলিত রূপ EAC = BAC ÷ CPIশেষে মোট খরচের পূর্বাভাস

সূত্রগুলো PMI-এর বই আর বিভিন্ন মানদণ্ডে (যেমন যুক্তরাষ্ট্রের ANSI/EIA-748) প্রায় একইভাবে লেখা, তবে EAC-র কয়েকটি রূপ আছে, আর কোনটি নেবেন তা নির্ভর করে খরচের বাড়তি কেন হলো তার ওপর। নিচের প্রোগ্রাম আমাদের অ্যাপের দিন ১২-র অবস্থা থেকে সবগুলো হিসাব করে। ধরে নেওয়া হয়েছে, প্রতিটি activity-র বাজেট তার পরিকল্পিত দণ্ড জুড়ে সমানভাবে খরচ হওয়ার কথা:

# Earned value at the end of day 12 (fictional school result app, thousand taka).
# activity: (planned start, planned finish, budget, % complete, actual cost so far)
acts = {"A": (0, 4, 40, 100, 42), "B": (4, 7, 30, 100, 33), "C": (4, 9, 50, 100, 55),
        "D": (7, 13, 90, 50, 50), "E": (9, 12, 40, 50, 25), "F": (7, 11, 40, 100, 38),
        "G": (13, 16, 30, 0, 0), "H": (16, 20, 50, 0, 0), "I": (20, 22, 20, 0, 0)}
DAY, PLANNED_DAYS = 12, 22

def planned_share(start, finish, day):     # budget assumed spread evenly over the bar
    return min(max((day - start) / (finish - start), 0), 1)

BAC = sum(b for _, _, b, _, _ in acts.values())
PV = sum(b * planned_share(s, f, DAY) for s, f, b, _, _ in acts.values())
EV = sum(b * pc / 100 for _, _, b, pc, _ in acts.values())
AC = sum(ac for *_, ac in acts.values())
SV, CV, SPI, CPI = EV - PV, EV - AC, EV / PV, EV / AC
print(f"BAC={BAC}  PV={PV:.1f}  EV={EV:.1f}  AC={AC:.1f}")
print(f"SV={SV:+.1f}  CV={CV:+.1f}  SPI={SPI:.3f}  CPI={CPI:.3f}")
variants = [("BAC/CPI          (cost rate so far continues)", BAC / CPI),
            ("AC+(BAC-EV)      (overrun was a one-off)", AC + (BAC - EV)),
            ("AC+(BAC-EV)/(CPI*SPI) (late AND over budget)", AC + (BAC - EV) / (CPI * SPI))]
for name, eac in variants:
    print(f"EAC = {name}: {eac:.1f}   VAC = {BAC - eac:+.1f}")
print(f"ETC with BAC/CPI = {BAC / CPI - AC:.1f}")
print(f"rough finish = {PLANNED_DAYS} / SPI = {PLANNED_DAYS / SPI:.1f} days (crude, see text)")

আউটপুট:

BAC=390  PV=275.0  EV=225.0  AC=243.0
SV=-50.0  CV=-18.0  SPI=0.818  CPI=0.926
EAC = BAC/CPI          (cost rate so far continues): 421.2   VAC = -31.2
EAC = AC+(BAC-EV)      (overrun was a one-off): 408.0   VAC = -18.0
EAC = AC+(BAC-EV)/(CPI*SPI) (late AND over budget): 460.8   VAC = -70.8
ETC with BAC/CPI = 178.2
rough finish = 22 / SPI = 26.9 days (crude, see text)

হিসাবরক্ষকের “টাকা বাঁচছে” ভুল ছিল। PV ২৭৫ (যেমন D-র ৬ দিনের ৫ দিন পেরিয়েছে, তাই ৯০-এর ৫/৬ = ৭৫), কিন্তু EV মাত্র ২২৫ — পরিকল্পনার চেয়ে কম কাজ হয়েছে (SPI ০.৮১৮), আর যতটুকু হয়েছে তাতেও বেশি খরচ (CPI ০.৯২৬ — প্রতি ১ টাকায় ০.৯৩ টাকার কাজ)। এখনকার হারে চললে শেষে খরচ প্রায় ৪২১ হাজার, বাজেটের চেয়ে ৩১ হাজার বেশি; বাড়তি খরচটি এককালীন হলে ৪০৮, আর দেরি পুষিয়ে নিতে বাড়তি চাপ দিলে ৪৬১ পর্যন্ত। শেষ লাইনটি খুব মোটা হিসাব: SPI টাকার মাপ, আর project-এর শেষের দিকে সব কাজ শেষ হলে SPI ১-এ ফেরে, দেরি হলেও। এই সীমা এড়াতে Walt Lipke ২০০৩ সালের দিকে “earned schedule” প্রস্তাব করেন। আর আসল বিপদ অংশ ৭-এর মতোই: D critical, তাই critical path ধরে দেখলে দেরি ১ দিন — SPI একা সেটা বলতে পারে না, কারণ এতে non-critical কাজের দেরিও মেশে।

“৯০% শেষ” সমস্যা: EV নির্ভর করে “% শেষ”-এর ওপর, আর software-এ developer-রা প্রায়ই অনেক দিন ধরে “৯০% শেষ” বলেন। তাই অনেক দল নিয়ম বাঁধে: work package শুরু হলে ০%, শেষ হলে ১০০% (0/100 নিয়ম), বা শুরুতে ৫০%, শেষে বাকি ৫০% (50/50 নিয়ম)।

৯ · Agile planning-এর সাথে তুলনা — কখন কোনটি

পর্ব ৫-এ (Agile আর Scrum) আপনি sprint planning, velocity আর burndown দেখেছেন। প্রশ্ন ওঠে: Agile দলের কি CPM, Gantt chart লাগে? উত্তর: পরিকল্পনা লাগে, কিন্তু অন্য আকারে আর অন্য স্তরে।

দিকপ্রচলিত (CPM, Gantt)Agile
কী স্থিরScope; সময় আর খরচ হিসাব করে বের করা হয়সময় (sprint) আর দল; scope অগ্রাধিকার দিয়ে বদলায়
বিস্তারিত কতদূরশুরুতেই পুরো projectকাছের sprint বিস্তারিত, দূরের কাজ মোটা দাগে
অগ্রগতির মাপBaseline-এর সাথে তুলনা, earned valueDone হওয়া Increment, burndown/burnup
দীর্ঘ মেয়াদের ছবিGantt chart, milestoneProduct roadmap আর release planning
সবচেয়ে ভালো খাটেনির্ভরতা জটিল, পরিবর্তন কম, বাইরের তারিখ নির্দিষ্টRequirement অনিশ্চিত, দ্রুত feedback দরকার

Release planning-এ দল velocity দিয়ে মোটা হিসাব করে: backlog-এ ধরুন ১২০ story point, velocity sprint-প্রতি গড়ে ২০ (সাম্প্রতিক কয়েকটির পরিসর ১৬ থেকে ২৪), তাহলে প্রায় ৫ থেকে ৮টি sprint — একটি পরিসর, একটি তারিখ নয়। Roadmap আরও উঁচু স্তরের: “এই প্রান্তিকে অভিভাবকের app, পরের প্রান্তিকে SMS” — লক্ষ্যের ক্রম, তারিখের প্রতিশ্রুতি নয়। দুই জগতের মাঝে সেতু হলো rolling wave planning: কাছের কাজ বিস্তারিত, দূরের কাজ মোটা দাগে, তথ্য এলে ধাপে ধাপে বিস্তারিত।

বাস্তবে অনেক project দুটোই মেশায়: ফল প্রকাশের নির্দিষ্ট তারিখ, server কেনা আর শিক্ষক প্রশিক্ষণের মতো বাইরের নির্ভরতার জন্য উঁচু স্তরের network আর milestone; screen-এর ভেতরের feature-গুলো sprint-এ, অগ্রাধিকার অনুযায়ী। পর্ব ৪-এর (process model) waterfall বনাম iterative-এর সিদ্ধান্তটাই এখানে পরিকল্পনার ভাষায় ফিরে এসেছে।

আরও গভীরে: Project management-এর প্রধান সংকলন PMI-এর A Guide to the Project Management Body of Knowledge (PMBOK Guide; সপ্তম সংস্করণ ২০২১ থেকে নীতিভিত্তিক) আর আন্তর্জাতিক নির্দেশিকা ISO 21502 (২০২০)। CPM-এর সময়-খরচ বিশ্লেষণের মূল উৎস Kelley ও Walker-এর ১৯৫৯-এর প্রবন্ধ; PERT-এর মূল প্রবন্ধ Malcolm, Roseboom, Clark ও Fazar-এর (Operations Research, ১৯৫৯)। Eliyahu Goldratt-এর উপন্যাস Critical Chain (১৯৯৭) critical chain পদ্ধতি দেয়, যা Parkinson-এর সূত্র আর student syndrome-এর কারণে প্রতিটি কাজের ভেতরে লুকানো নিরাপত্তা-সময়কে সরিয়ে পথের শেষে একটি সাধারণ buffer রাখে।

পরীক্ষা ও ইন্টারভিউতে:

  • Critical path কী, আর এর activity-র float কত? — শুরু থেকে শেষের সবচেয়ে লম্বা পথ, যার দৈর্ঘ্য project-এর ন্যূনতম সময়; এর প্রতিটি activity-র total float শূন্য (নির্দিষ্ট শেষ তারিখ না দিলে)।
  • Total float আর free float-এর পার্থক্য? — Total float: শেষ তারিখ না পিছিয়ে দেরি; free float: কোনো উত্তরসূরির ES না পিছিয়ে দেরি। Free float ≤ total float.
  • PERT-এ te আর σ²-এর সূত্র? — (a + 4m + b)/6 আর ((b − a)/6)²; project-এর variance = critical path-এর variance-এর যোগফল।
  • Crashing-এ কোন activity আগে? — Critical path-এর সবচেয়ে কম cost slope-এর activity; প্রতিবার critical path নতুন করে দেখতে হয়।
  • CPI ০.৮ মানে কী? — প্রতি ১ টাকা খরচে ০.৮ টাকার কাজ হচ্ছে — বাজেট ছাড়াচ্ছে।

পর্ব ৬৬-এ CPM-PERT-এর আরও numerical পূর্ণ সমাধানসহ পাবেন।

১০ · AI-এর যুগে — schedule-এর হিসাব যাচাই

AI এখন এক লাইনের বর্ণনা থেকে WBS, Gantt chart আর ঝুঁকির তালিকা বানিয়ে দেয়। শুরু করার জন্য এটি কাজের, কিন্তু project planning-এ AI-এর কিছু চেনা ভুল আছে:

AI-এর ভুলকীভাবে ধরবেন
Forward pass-এ সর্বোচ্চের বদলে যোগ, backward pass-এ সর্বনিম্নের বদলে সর্বোচ্চ, বা σ-গুলো সরাসরি যোগএকটি ছোট network হাতে করুন, বা অংশ ৪-এর কোডে তথ্য বসিয়ে মেলান
Non-critical কিন্তু সস্তা activity crash করার পরামর্শপ্রতিটি ধাপে জিজ্ঞেস করুন: এটি কি এখন critical path-এ?
PERT-এর সম্ভাবনাকে নিশ্চিত সত্য বলা, merge bias উল্লেখ না করাNear-critical পথগুলো দেখুন; দরকারে Monte Carlo চালান
WBS-এ project management, testing বা প্রশিক্ষণের মতো কাজ বাদ — 100% নিয়ম ভাঙাপ্রতিটি deliverable-এর নিচের অংশ যোগ করে দেখুন সব কাজ এসেছে কি না
বানানো পরিসংখ্যান (“software project-এর এত % দেরি হয়”) বা ভুল সংস্করণ-সাল (PMBOK, ISO)উৎস চান; মূল প্রকাশকের সাইটে নিজে যাচাই করুন

নিচের prompt AI-কে প্রতিটি ধাপ দেখাতে আর ধারণাগুলো আলাদা করে লিখতে বলে — যাতে প্রতিটি সংখ্যা আপনি নিজে মেলাতে পারেন। দলের আসল তথ্য দেওয়ার আগে গ্রাহক, কর্মী বা চুক্তির গোপন অংশ মুছে দিন।

নিচে একটি project-এর activity-র তালিকা দিলাম: নাম, পূর্বসূরি, আর তিনটি অনুমান (a, m, b) দিনে। [এখানে তালিকা — গোপন নাম বাদ দিয়ে] ১. প্রতিটির te = (a+4m+b)/6 আর variance বের করো, তারপর te দিয়ে forward ও backward pass করে ES, EF, LS, LF, total float আর free float-এর টেবিল দাও। ২. সব critical path আর ২ দিনের কম float-এর near-critical পথ আলাদা করে দেখাও। ৩. Critical path ধরে μ, σ আর ৩০ দিনের মধ্যে শেষের সম্ভাবনা Z-সহ দেখাও; তারপর merge bias-এর কারণে আসল সম্ভাবনা কেন কম হতে পারে, এক অনুচ্ছেদে বলো। ৪. যা ধরে নিচ্ছ (দিন ০ না ১ থেকে গোনা, activity-গুলো স্বাধীন কি না), আলাদা তালিকায় লেখো। কোনো পরিসংখ্যান বা মানদণ্ডের নাম বানিয়ে বলবে না।

AI-এর দেওয়া schedule হাতে পেলে — চেকলিস্ট

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।

প্র ০১CPM আর PERT প্রায় একই সময়ে দুটি ভিন্ন জায়গায় জন্মেছিল। দুটোর মূল প্রশ্ন কি একই ছিল? আর Polaris কর্মসূচির সাফল্য কি সত্যিই PERT-এর কৃতিত্ব?

দুটোর পটভূমি আলাদা ছিল, আর সেই পার্থক্যই দুটোর গঠন ঠিক করেছে। DuPont-এর রাসায়নিক কারখানায় রক্ষণাবেক্ষণের কাজের সময় মোটামুটি জানা ছিল — একই ধরনের কাজ আগেও বহুবার হয়েছে। সেখানে প্রশ্ন ছিল: কারখানা বন্ধ রাখার প্রতিটি দিনের দাম বিশাল, তাহলে কোন কাজে বাড়তি লোক দিলে সবচেয়ে কম খরচে সবচেয়ে বেশি দিন বাঁচে? তাই CPM-এর কেন্দ্রে নির্দিষ্ট সময় আর সময়-খরচের বিনিময় — আজকের crashing.

Polaris ছিল উল্টো: ডুবোজাহাজ থেকে ক্ষেপণাস্ত্র ছোঁড়ার প্রযুক্তি তখনো তৈরি হয়নি, হাজার হাজার ঠিকাদার এমন কাজ করছিলেন যা আগে কেউ করেননি। সময় অনুমানই ছিল সবচেয়ে অনিশ্চিত জিনিস। তাই PERT তিনটি অনুমান নেয় আর সম্ভাবনার ভাষায় কথা বলে; খরচ এর মূল রূপে কেন্দ্রে ছিল না।

Polaris নির্ধারিত সময়ের আগেই চালু হয়েছিল বলে বহুল প্রচলিত বর্ণনা আছে, আর PERT দ্রুত বিখ্যাত হয় — সরকারি চুক্তিতে কিছু সময় এটি প্রায় বাধ্যতামূলকও হয়ে ওঠে। কিন্তু রাষ্ট্রবিজ্ঞানী Harvey Sapolsky ১৯৭২ সালের একটি গবেষণা-বইয়ে যুক্তি দেন যে PERT-এর আসল প্রভাব প্রচারের তুলনায় কম ছিল; এর বড় ভূমিকা ছিল কর্মসূচিকে আধুনিক ও সুপরিচালিত হিসেবে দেখানো, যাতে বাজেট আর রাজনৈতিক সমর্থন বজায় থাকে। এই ব্যাখ্যা নিয়েও বিতর্ক আছে, তবে শিক্ষাটি গুরুত্বপূর্ণ: একটি পদ্ধতির পাশে একটি সফল project থাকলেই সাফল্যের কারণ পদ্ধতিটি — এমন নয়।

মূল উপলব্ধি: CPM-এর প্রশ্ন “টাকা দিয়ে কতটা সময় কেনা যায়”, PERT-এর প্রশ্ন “অনিশ্চয়তা কতটা”। পদ্ধতি বেছে নিন আপনার project-এর আসল অনিশ্চয়তা দেখে, আর কোনো পদ্ধতির খ্যাতিকে তার প্রমাণ ভাববেন না।

প্র ০২PERT বলল ২৪ দিনের মধ্যে শেষের সম্ভাবনা ৮৫.৬%, simulation বলল ৮২.১%. এই পার্থক্য কোথা থেকে, আর বড় project-এ এটি কতটা বড় হতে পারে?

PERT-এর সূত্র শুধু একটি পথ দেখে — critical path. কিন্তু project শেষ হয় তখন, যখন সব পথ শেষ। আমাদের অ্যাপে G (integration) শুরু হতে পারে D, E আর F তিনটি শেষ হলে। কোনো এক “ভবিষ্যতে” backend তাড়াতাড়ি শেষ হলো, কিন্তু UI-এর পথে দেরি হলো — তখন UI-এর পথটিই সেদিনের critical path. সূত্রটি এই সম্ভাবনাগুলো গোনে না। গাণিতিকভাবে: কয়েকটি এলোমেলো সংখ্যার সর্বোচ্চের গড় তাদের গড়গুলোর সর্বোচ্চের চেয়ে বড় বা সমান — সমান হয় শুধু যখন একটি পথ সবসময় অন্যগুলোর চেয়ে স্পষ্টভাবে লম্বা।

আমাদের উদাহরণে পার্থক্য ছোট (গড় ২২ বনাম ২২.২৮), কারণ near-critical পথ মাত্র একটি, আর তাও critical path-এর সাথে A, G, H, I ভাগ করে নেয় — শেয়ার করা অংশ দুই পথে একই দিকে নড়ে। বড় software project-এ শত শত activity আর অনেকগুলো প্রায় সমান লম্বা সমান্তরাল পথ থাকে — যেমন অনেকগুলো microservice আলাদা দলে তৈরি হয়ে একটি integration-এ মেলে। তখন merge bias অনেক বড় হতে পারে, আর PERT-এর ৮৫% তারিখ বাস্তবে হয়তো অর্ধেক সম্ভাবনারও নয়।

দ্বিতীয় কারণ স্বাধীনতার ধারণা। Simulation-ও activity-গুলোকে স্বাধীন ধরেছে; বাস্তবে একই কারণ (requirement অস্পষ্ট, দলের অভিজ্ঞ সদস্য চলে গেলেন) অনেক কাজকে একসাথে দেরি করায়। এতে আসল বণ্টন আরও ছড়ানো হয়।

করণীয়: merge point-এর আগে near-critical পথগুলো চিহ্নিত করুন, integration আগে ও বারবার করুন (পর্ব ৫৮-এর continuous integration এখানে একটি schedule-এর হাতিয়ারও), আর তারিখের সাথে সম্ভাবনা বলুন — তাও simulation বা অতীত তথ্য দিয়ে যাচাই করে।

মূল উপলব্ধি: PERT-এর সম্ভাবনা একটি ঊর্ধ্বসীমা-ধরনের আশাবাদী হিসাব। যত বেশি সমান্তরাল পথ এক বিন্দুতে মেলে, তত বেশি সন্দেহ করুন।

প্র ০৩Crashing-এর মডেল ধরে নেয়, টাকা দিলে সময় সরলরেখায় কমে। Software project-এ এই ধারণা কোথায় ভাঙে?

Cost slope-এর পেছনের ছবিটি কারখানা বা নির্মাণ কাজের: দুজন রাজমিস্ত্রির বদলে চারজন দিলে দেয়াল মোটামুটি অর্ধেক সময়ে ওঠে, কারণ কাজটি সহজে ভাগ করা যায় আর একজনের কাজ অন্যজনকে বেশি বোঝাতে হয় না। Fred Brooks তাঁর The Mythical Man-Month (১৯৭৫) বইয়ে দেখান, software-এর কাজ প্রায়ই এমন নয়। তাঁর পরিচিত উপমা: একজন মা নয় মাসে একটি শিশু জন্ম দেন; নয়জন মা এক মাসে পারেন না। কিছু কাজ ভাগই করা যায় না।

দ্বিতীয় সমস্যা যোগাযোগ। n জন মানুষের মধ্যে যোগাযোগের পথ n(n − ১)/২ — ৪ জনে ৬টি, ৮ জনে ২৮টি। নতুন মানুষকে codebase, নিয়ম আর domain শেখাতে পুরোনো সদস্যদের সময় যায়; প্রথম কয়েক সপ্তাহ নতুন সদস্যের অবদান প্রায়ই ঋণাত্মক। তাই Brooks-এর সূত্র: দেরি হওয়া software project-এ লোক যোগ করলে তা আরও দেরি হয়। এটি একটি পর্যবেক্ষণ, প্রাকৃতিক নিয়ম নয় — খুব আগে, ভালোভাবে ভাগ করা কাজে, অভিজ্ঞ মানুষ যোগ করলে কাজে আসতে পারে।

তৃতীয়ত, overtime-এর খরচ টাকায় সীমিত নয়। দীর্ঘ সময় কাজে ক্লান্তি বাড়ে, ভুল বাড়ে, আর bug পরে আরও বেশি সময় খায় — অর্থাৎ crash করা activity-র “আসল” সময় হয়তো কমেইনি, শুধু পরের testing activity-তে সরে গেছে।

তাহলে software-এ কী কাজ করে? Scope কমানো (triple constraint-এর তৃতীয় কোণ), কিছু কাজ বাইরের তৈরি সমাধান দিয়ে করা (ভাড়া করা SMS সেবা), integration-এর ঝুঁকি আগে কমানো, আর যেখানে সত্যিই ভাগ করা যায় (যেমন আলাদা আলাদা report screen), সেখানে আগেভাগে বাড়তি মানুষ। Crashing-এর হিসাব তবুও কাজের: এটি প্রশ্ন করতে শেখায় — কোন দিনটি কিনতে সবচেয়ে কম দাম, আর কোন দিন কেনাই অর্থহীন কারণ সেটি critical নয়।

মূল উপলব্ধি: Crashing-এর যুক্তি (critical, সস্তা, আবার দেখুন) ঠিক থাকে, কিন্তু software-এ cost slope সরলরেখা নয়, আর অনেক সময় scope কমানোই সবচেয়ে সস্তা “crash”.

প্র ০৪Gantt chart একশো বছরেরও বেশি পুরোনো। আজকের software দলে এটি কতটা কাজের, আর কোথায় এটি ভুল ধারণা দেয়?

Chart-টির নাম আমেরিকান প্রকৌশলী Henry L. Gantt-এর নামে; সাধারণভাবে বলা হয় তিনি ১৯১০-এর দশকে কারখানার উৎপাদন আর পরে প্রথম বিশ্বযুদ্ধের সময় অস্ত্র-উৎপাদন তদারকিতে এ ধরনের chart জনপ্রিয় করেন। এর আগেই, ১৮৯৬ সালের দিকে, পোলিশ প্রকৌশলী Karol Adamiecki একটি অনুরূপ চিত্র (“harmonogram”) ব্যবহার করেছিলেন বলে উল্লেখ আছে, কিন্তু তাঁর লেখা অনেক পরে পোলিশ ভাষায় প্রকাশিত হওয়ায় পশ্চিমে কম পরিচিত ছিল। সাল আর কৃতিত্ব উৎসভেদে কিছুটা আলাদা।

Gantt chart-এর শক্তি তার সরলতায়: যে কেউ — প্রধান শিক্ষক থেকে অভিভাবক প্রতিনিধি — এক নজরে বোঝেন কোন সপ্তাহে কী চলছে, milestone কবে, আর baseline-এর পাশে প্রকৃত দণ্ড দেখলে দেরি চোখে পড়ে। বাইরের নির্ভরতা (server কেনা, প্রশিক্ষণের হল ভাড়া, ফল প্রকাশের তারিখ) সমন্বয়ে এটি এখনো খুব কাজের।

দুর্বলতা তিনটি। এক, নিশ্চয়তার ভান: একটি দণ্ডের নির্দিষ্ট শুরু-শেষ দেখে মনে হয় সময়টা জানা, অথচ পেছনে PERT-এর মতো ছড়ানো বণ্টন। দুই, নির্ভরতা লুকানো: তীর ছাড়া Gantt chart বলে না কোন দেরি কাকে ধাক্কা দেবে — critical path দেখাতে আলাদা রং বা network লাগে। তিন, বিস্তারিতের ফাঁদ: ছয় মাসের প্রতিটি দিনের দণ্ড আঁকলে, requirement বদলানোর সাথে সাথে chart হালনাগাদ করতেই অনেক সময় যায়, আর পুরোনো chart মিথ্যা নিরাপত্তা দেয়।

তাই অনেক Agile দল দীর্ঘ মেয়াদে Gantt-এর বদলে roadmap রাখে (মাস বা প্রান্তিক ধরে লক্ষ্য), আর কাছের কাজ sprint board-এ। আবার বড় প্রতিষ্ঠানে কয়েকটি দলের মধ্যে নির্ভরতা দেখাতে উঁচু স্তরের Gantt-ধরনের ছবি এখনো সাধারণ। প্রশ্নটা “Gantt chart ভালো না খারাপ” নয়, বরং “কোন স্তরের বিস্তারিত, কত দূর ভবিষ্যৎ পর্যন্ত, আর কার জন্য”।

মূল উপলব্ধি: Gantt chart যোগাযোগের চমৎকার হাতিয়ার, কিন্তু ভবিষ্যদ্বাণীর নয়। কাছের কাজ বিস্তারিত, দূরের কাজ মোটা দাগে রাখুন, critical path আলাদা করে দেখান, আর baseline-এর পাশে বাস্তব।

প্র ০৫Earned value প্রতিরক্ষা খাতের বড় project থেকে এসেছে। একটি ছোট software দলের জন্য এটি কি অতিরিক্ত ভার, নাকি সত্যিই কাজের?

EVM-এর ধারণাগুলো সাধারণত যুক্তরাষ্ট্রের প্রতিরক্ষা দপ্তরের ১৯৬০-এর দশকের খরচ-নিয়ন্ত্রণের নিয়ম থেকে উদ্ভূত বলে বর্ণনা করা হয় (১৯৬৭ সালের C/SCSC নির্দেশনা প্রায়ই উদ্ধৃত হয়); পরে শিল্পখাতের মানদণ্ড ANSI/EIA-748 এবং PMI-এর বইয়ে এটি সাধারণ রূপ পায়। এর মূল অবদান একটি সরল কিন্তু শক্তিশালী ধারণা: খরচ আর সময়কে আলাদা নয়, কাজের মূল্য দিয়ে একই মাপে মাপা। অংশ ৮-এ দেখেছেন, শুধু “খরচ পরিকল্পনার চেয়ে কম” দেখলে ভুল সিদ্ধান্ত হতো।

ছোট software দলে সমস্যা হলো “% শেষ” মাপা। কোড, test আর review মিলিয়ে একটি feature কতটা শেষ, তা মাপা কঠিন; আর “৯০% শেষ” কয়েক সপ্তাহ ঝুলে থাকতে পারে। এর সমাধান অংশ ৮-এর সতর্কতায়: ছোট work package, আর 0/100 বা 50/50-এর মতো কঠোর নিয়ম। এভাবে EVM আসলে Agile-এর “Done অথবা Not Done”-এর কাছাকাছি চলে আসে।

দ্বিতীয় সমস্যা baseline. Agile-এ scope ইচ্ছাকৃতভাবে বদলায়, তাই স্থির baseline-এর সাথে তুলনা অর্থহীন হয়ে যেতে পারে। কিছু গবেষক release-স্তরে story point-কে বাজেটের একক ধরে EVM-এর একটি Agile রূপ প্রস্তাব করেছেন (২০০০-এর দশকের মাঝামাঝি “AgileEVM” নামে একটি প্রস্তাব আলোচিত হয়)। আবার অনেক দল burnup chart-কেই যথেষ্ট মনে করে — সেখানে মোট scope-এর রেখা আর শেষ হওয়া কাজের রেখা দুটোই দেখা যায়, যা EV আর scope পরিবর্তন একসাথে দেখায়।

সারকথা: চুক্তিভিত্তিক, নির্দিষ্ট বাজেটের software project-এ (যেমন সরকারি বা প্রতিষ্ঠানের জন্য বানানো সিস্টেম) EVM-এর মূল তিনটি সংখ্যা মাসিক রিপোর্টে খুব কাজের। ছোট product দলে পুরো যন্ত্রপাতি ভারী, কিন্তু প্রশ্নটি — “যত টাকা গেছে, তত কাজ কি হয়েছে?” — সবসময় প্রাসঙ্গিক।

মূল উপলব্ধি: EVM-এর শক্তি নির্ভর করে “শেষ” মাপার সততার ওপর। মাপ কঠোর রাখুন, critical path পাশাপাশি দেখুন, আর scope বদলালে baseline আনুষ্ঠানিকভাবে বদলান।

অনুশীলন

CPM, PERT আর crashing-এর পরীক্ষা-ধরনের হিসাব, আর একটি আউটপুট অনুমান — প্রতিটির পূর্ণ উত্তর দেওয়া আছে।

  1. CPM-এর হিসাব: একটি কাল্পনিক অনলাইন ভর্তি পোর্টালের activity (দিনে): A ৩ (—), B ৫ (A), C ৪ (A), D ৬ (B), E ২ (C), F ৩ (C), G ৪ (D, E), H ২ (F, G). বন্ধনীতে পূর্বসূরি। (ক) প্রতিটির ES, EF, LS, LF বের করুন। (খ) Total float আর free float. (গ) Critical path আর project-এর সময়।

    Forward pass: A ০–৩; B ৩–৮; C ৩–৭; D ৮–১৪; E ৭–৯; F ৭–১০; G-এর ES = max(D ১৪, E ৯) = ১৪, EF ১৮; H-এর ES = max(F ১০, G ১৮) = ১৮, EF ২০। Project ২০ দিন.

    Backward pass: H LF ২০, LS ১৮; G LF ১৮, LS ১৪; F LF ১৮, LS ১৫; D LF ১৪, LS ৮; E LF ১৪, LS ১২; C LF = min(E-র LS ১২, F-এর LS ১৫) = ১২, LS ৮; B LF ৮, LS ৩; A LF = min(B ৩, C ৮) = ৩, LS ০।

    act dur  ES  EF  LS  LF  TF  FF
      A   3   0   3   0   3   0   0
      B   5   3   8   3   8   0   0
      C   4   3   7   8  12   5   0
      D   6   8  14   8  14   0   0
      E   2   7   9  12  14   5   5
      F   3   7  10  15  18   8   8
      G   4  14  18  14  18   0   0
      H   2  18  20  18  20   0   0

    (গ) Critical path A-B-D-G-H = ৩ + ৫ + ৬ + ৪ + ২ = ২০ দিন। লক্ষ করুন C-এর total float ৫ কিন্তু free float ০ — C দেরি করলে E আর F দুটোই সরে যায় (দুটোরই ES ৭)। এই টেবিল অংশ ৪-এর প্রোগ্রামে তথ্য বদলে চালিয়ে মিলিয়ে দেখা।

  2. PERT-এর সম্ভাবনা: একটি কাল্পনিক হাসপাতালের appointment app-এর activity, (a, m, b) দিনে: A (১, ৪, ৭) —; B (২, ৫, ১৪) A-র পরে; C (১, ২, ৩) A-র পরে; D (১, ৪, ১৩) B আর C-এর পরে; E (২, ৪, ৬) C-এর পরে। (ক) প্রতিটির te আর σ². (খ) Critical path, μ আর σ. (গ) ১৮ দিনের মধ্যে শেষের সম্ভাবনা। (ঘ) ১২ দিনের মধ্যে শেষের সম্ভাবনা। (ঙ) ৯৫% নিশ্চয়তার সময়।

    (ক) A: (১ + ১৬ + ৭)/৬ = ৪, σ² = (৬/৬)² = ১। B: (২ + ২০ + ১৪)/৬ = ৬, σ² = (১২/৬)² = ৪। C: ২, σ² = (২/৬)² ≈ ০.১১১। D: (১ + ১৬ + ১৩)/৬ = ৫, σ² = (১২/৬)² = ৪। E: ৪, σ² = (৪/৬)² ≈ ০.৪৪৪।

    (খ) শেষের activity D আর E. পথগুলো: A-B-D = ৪ + ৬ + ৫ = ১৫, A-C-D = ১১, A-C-E = ১০। Critical path A-B-D, μ = ১৫ দিন, Σσ² = ১ + ৪ + ৪ = ৯, σ = ৩ দিন.

    (গ) Z = (১৮ − ১৫)/৩ = ১ ⇒ Φ(১) ≈ ০.৮৪১৩ — প্রায় ৮৪.১%.

    (ঘ) Z = (১২ − ১৫)/৩ = −১ ⇒ Φ(−১) = ১ − ০.৮৪১৩ = ০.১৫৮৭ — প্রায় ১৫.৯%.

    (ঙ) T = ১৫ + ১.৬৪৫ × ৩ ≈ ১৯.৯ দিন, মানে কার্যত ২০ দিন। মন্তব্য: A-C-D পথের গড় ১১ — অনেক কম, তাই এখানে merge bias সামান্য। B আর D-এর লম্বা ডান লেজই প্রায় সব অনিশ্চয়তার উৎস; ঝুঁকি কমাতে এই দুটিতে মনোযোগ দিন।

  3. Crashing আর একটি পরিকল্পনার সমালোচনা: চারটি activity (দিনে; slope হাজার টাকা প্রতি দিন): P ৩ (crash ২, slope ৪), Q ৬ P-র পরে (crash ৪, slope ৩), R ৫ P-র পরে (crash ৪, slope ২), S ২ Q আর R-এর পরে (crash ১, slope ৭)। (ক) Project ৯ দিনে আনতে সবচেয়ে কম বাড়তি খরচ কত? (খ) একজন ব্যবস্থাপক বললেন, “R-এর slope সবচেয়ে কম, তাই আগে R দুই দিন কমান, তারপর দেখা যাবে।” এই পরিকল্পনার সমালোচনা করুন।

    (ক) পথ: P-Q-S = ১১, P-R-S = ১০। ধাপ ১: critical শুধু P-Q-S; বিকল্প P ৪, Q ৩, S ৭ — Q এক দিন কমান (+৩)। এখন দুটি পথই ১০। ধাপ ২: দুটোই critical; বিকল্প: সাধারণ activity P ৪ বা S ৭, অথবা জোড়া Q + R = ৩ + ২ = ৫। সবচেয়ে সস্তা P (+৪)। দুটি পথই ৯। মোট বাড়তি খরচ ৭ হাজার টাকা. (প্রথমে P কমালেও মোট ৭ আসে: P +৪ → ১০ আর ৯; তারপর Q +৩ → ৯ আর ৯।)

    (খ) R প্রথমে critical নয় (১০ দিনের পথে, float ১), তাই R কমালে project এক দিনও ছোট হয় না — ২ × ২ = ৪ হাজার টাকা নষ্ট। তার ওপর R-এর crash সীমা ৪ দিন, অর্থাৎ মাত্র এক দিন কমানো যায়, দুই দিন নয়। সঠিক নিয়ম: শুধু critical activity, সবচেয়ে কম slope আগে, এক দিন করে, আর প্রতিবার critical path নতুন করে দেখা। Software-এ এর সাথে যোগ করুন: Q যদি developer বাড়িয়ে কমানোর পরিকল্পনা হয়, Brooks-এর সূত্রের ঝুঁকিও বিবেচনা করুন।

  4. আউটপুট অনুমান করুন: নিচের JavaScript কোড একটি তিন-activity network-এ forward pass করছে। কী ছাপবে? তারপর এক জায়গায় সংশোধন করে সঠিক উত্তর বলুন।
    const dur = { A: 3, B: 2, C: 4 };
    const pre = { A: [], B: ["A"], C: ["A"] };
    const EF = {};
    for (const k of ["A", "B", "C"]) {
      const ES = Math.max(...pre[k].map(p => EF[p]));
      EF[k] = ES + dur[k];
    }
    console.log(EF.A, EF.B, EF.C);
    -Infinity -Infinity -Infinity

    A-র কোনো পূর্বসূরি নেই, তাই Math.max() ফাঁকা তালিকা পায় — আর ফাঁকা Math.max-এর মান -Infinity. A-র EF = −∞ + ৩ = −∞, আর সেই মান B ও C-তে ছড়িয়ে পড়ে। কোনো error আসে না, তাই ভুলটি সহজে চোখ এড়ায়। সংশোধন: Math.max(0, ...pre[k].map(p => EF[p])) — তখন ছাপবে 3 5 7 (A ০–৩, B ৩–৫, C ৩–৭)। অংশ ৪-এর প্রোগ্রামে ঠিক এ কারণেই 0 আছে; backward pass-এ একইভাবে Math.min(T, ...).

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি project-এর CPM schedule বানানোর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. WBS বানিয়ে পুরো scope-কে work package-এ ভাঙা
  2. Activity, তাদের সময় আর dependency ঠিক করা
  3. Network diagram আঁকা
  4. Forward pass — ES আর EF
  5. Backward pass — LS আর LF
  6. Float হিসাব করে critical path চিহ্নিত করা

একটি activity-র ES = ৫, EF = ৯, LS = ৮, LF = ১২ (দিনে)। এর total float কত?

  • ৩ দিন
  • ৪ দিন
  • ৭ দিন
  • ০ দিন

একটি activity-র PERT অনুমান: optimistic ৪, most likely ৭, pessimistic ১৬ দিন। প্রত্যাশিত সময় te আর standard deviation σ কত?

  • te = ৯, σ = ২
  • te = ৮, σ = ২
  • te = ৮, σ = ৪
  • te = ৭, σ = ২

একটি activity normal অবস্থায় ১০ দিনে ৫০,০০০ টাকায় হয়, আর crash করলে ৭ দিনে ৮০,০০০ টাকায়। এর cost slope কত?

  • প্রতি দিন প্রায় ১১,৪২৯ টাকা
  • প্রতি দিন ৩০,০০০ টাকা
  • প্রতি দিন ৫,০০০ টাকা
  • প্রতি দিন ১০,০০০ টাকা

“Frontend কোড লেখা শুরু হওয়ার ২ দিন পর থেকেই তার UI test লেখা শুরু করা যাবে” — এটি কোন ধরনের dependency?

  • Finish-to-start
  • Finish-to-finish
  • Start-to-start, ২ দিনের lag-সহ
  • Start-to-finish

একটি project-এ একটি নির্দিষ্ট তারিখে PV = ১০০, EV = ৮০, AC = ৯০ (হাজার টাকা)। কোনটি সঠিক?

  • SPI ১.২৫, project এগিয়ে আছে
  • SPI ০.৮ আর CPI প্রায় ০.৮৯ — পিছিয়ে আছে, বাজেটও ছাড়িয়েছে
  • খরচ পরিকল্পনার চেয়ে কম, তাই বাজেটের নিচে আছে
  • SV শূন্য, schedule ঠিক আছে

Activity-on-arrow (AOA) network-এ dummy activity কেন ব্যবহার করা হয়?

  • শূন্য সময়ে শুধু নির্ভরতা ঠিক রাখতে আর দুটি activity-কে আলাদা করে চেনাতে
  • ঝুঁকির জন্য বাড়তি সময়ের buffer রাখতে
  • Project-এর milestone দেখাতে
  • যে কাজে বাড়তি developer লাগবে, তা চিহ্নিত করতে

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. WBS deliverable ধরে পুরো scope ভাঙে — 100% নিয়ম: কিছু বাদ নয়, কিছু দুবার নয়; ক্রম আর সময় আসে network-এ।
  2. Forward pass-এ সর্বোচ্চ, backward pass-এ সর্বনিম্ন; total float = LS − ES, free float = উত্তরসূরিদের সর্বনিম্ন ES − EF; float শূন্যের পথই critical path.
  3. PERT: te = (a + 4m + b)/6, σ² = ((b − a)/6)²; critical path-এ variance যোগ, তারপর Z = (T − μ)/σ — কিন্তু merge bias-এর কারণে ফলটি আশাবাদী।
  4. Crashing: critical, সবচেয়ে কম cost slope, এক দিন করে, প্রতিবার critical path আবার দেখুন; slope দৈনিক পরোক্ষ খরচ ছাড়ালে থামুন। Software-এ লোক বাড়ানোর আগে Brooks-এর সূত্র মনে রাখুন।
  5. Gantt chart-এ baseline বনাম প্রকৃত, আর earned value-এ SPI = EV/PV, CPI = EV/AC; Agile দলে একই প্রশ্নের উত্তর দেয় release planning, roadmap আর burnup.

পরের পর্বে: পর্ব ৬২ — Risk আর quality management: risk register, CMMI, ISO 9001 আর software metric. আজকের near-critical path আর PERT-এর অনিশ্চয়তা সেখানে ঝুঁকির তালিকায় জায়গা পাবে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান