কম্পিউটার টিউটোরিয়াল

ডায়রেক্টেড গ্রাফে সাইকেল শনাক্তকরণ (Detect Cycle in a Directed Graph)

ডেপথ ফার্স্ট সার্চ (DFS) ট্রাভার্সাল অ্যালগরিদম ব্যবহার করে একটি ডায়রেক্টেড গ্রাফে সাইকেল শনাক্ত করা যায়। যদি কোনো নোডে সেলফ-লুপ থাকে, তবে সেটিকে একটি সাইকেল মाना হবে। অন্যথায়, যখন চাইল্ড নোডের অন্য কোনো এজ থাকে তার প্যারেন্টের সাথে সংযুক্ত হতে, তবে সেটিও একটি সাইকেল।

অসংযুক্ত গ্রাফের জন্য, ভিন্ন ভিন্ন ট্রি উপস্থিত থাকতে পারে, যাদেরকে আমরা একটি ফরেস্ট বলি। এখন আমাদের ফরেস্টের সব ট্রির জন্য সাইকেল শনাক্ত করতে হবে।

ডায়রেক্টেড গ্রাফে সাইকেল শনাক্তকরণ (Detect Cycle in a Directed Graph)

এই পদ্ধতিতে, আমরা নোডগুলোকে DFS ট্রাভার্সাল করার জন্য তিনটি ভিন্ন সেটে ভাগ করব: হোয়াইট (White), গ্রে (Grey) এবং ব্ল্যাক (Black)। প্রাথমিকভাবে সব নোড হোয়াইট সেটে থাকবে। যখন একটি নতুন নোড ট্রাভার্স করা হবে, তবে সেটিকে গ্রে সেটে রাখা হবে এবং হোয়াইট সেট থেকে সরিয়ে দেওয়া হবে। এবং ব্যাকট্র্যাকিং সম্পূর্ণ হলে, যখন সেই নোডের কাজ শেষ হয়ে যায়, তখন সেটিকে গ্রে থেকে ব্ল্যাক সেটে সরিয়ে দেওয়া হবে।

ইনপুট এবং আউটপুট

ইনপুট: অ্যাডজেসেন্সি ম্যাট্রিক্স।
0 1 0 0 0
0 0 0 0 0
1 0 0 1 0
0 0 0 0 1
0 0 1 0 0
আউটপুট: গ্রাফটিতে সাইকেল আছে।

এলগরিদম

dfs(curr, wSet, gSet, bSet)

ইনপুট: বর্তমান নোড, হোয়াইট, গ্রে এবং ব্ল্যাক সেট।

আউটপুট: সাইকেল থাকলে true।

শুরু
  curr কে হোয়াইট সেট থেকে মুছে গ্রে সেটে যোগ করুন
  curr-র সাথে সংযুক্ত গ্রাফের সব নোড v এর জন্য, করুন
    যদি v ব্ল্যাক সেটে থাকে, তবে
      পরবর্তী অংশ স্কিপ করুন, এবং পরবর্তী ইটারেশনের জন্য যান
    যদি v গ্রে সেটে থাকে, তবে
      return true
    যদি dfs(v, wSet, gSet, bSet) true হয়, তবে
      return true
  শেষ লুপ
  curr কে গ্রে সেট থেকে মুছে ব্ল্যাক সেটে যোগ করুন
  return false
শেষ

hasCycle(graph)

ইনপুট: প্রদত্ত গ্রাফ।

আউটপুট: গ্রাফে সাইকেল থাকলে true।

শুরু
  প্রাথমিকভাবে সব নোডকে হোয়াইট সেটে যোগ করুন
  যতক্ষণ হোয়াইট সেটে কিছু উপাদান থাকে, করুন
    গ্রাফের সব নোড v এর জন্য, করুন
      যদি v হোয়াইট সেটে না থাকে, তবে
        যদি dfs(v, wSet, gSet, bSet), তবে
          return true
      শেষ শর্ত
    শেষ লুপ
  শেষ লুপ
  return false
শেষ

উদাহরণ (C++ কোড)

#include <iostream>
#include <set>
#define NODE 5
using namespace std;

int graph[NODE][NODE] = {
  {0, 1, 0, 0, 0},
  {0, 0, 0, 0, 0},
  {1, 0, 0, 1, 0},
  {0, 0, 0, 0, 1},
  {0, 0, 1, 0, 0}
};

bool dfs(int curr, set<int> &wSet, set<int> &gSet, set<int> &bSet) {
  // curr কে হোয়াইট সেট থেকে গ্রে সেটে সরানো
  wSet.erase(wSet.find(curr));
  gSet.insert(curr);
  for(int v = 0; v < NODE; v++) {
    if(graph[curr][v] != 0) {  // সব সন্নিহিত ভার্টেক্সের জন্য
      if(bSet.find(v) != bSet.end())  // যদি ভার্টেক্সগুলো ব্ল্যাক সেটে থাকে
        continue;
      if(gSet.find(v) != gSet.end())  // এটি একটি সাইকেল
        return true;
      if(dfs(v, wSet, gSet, bSet))    // সাইকেল পাওয়া গেলে
        return true;
    }
  }
  // v কে গ্রে সেট থেকে ব্ল্যাক সেটে সরানো
  gSet.erase(gSet.find(curr));
  bSet.insert(curr);
  return false;
}

bool hasCycle() {
  set<int> wSet, gSet, bSet;  // তিনটি সেট: হোয়াইট, গ্রে এবং ব্ল্যাক
  for(int i = 0; i < NODE; i++)
    wSet.insert(i);  // প্রাথমিকভাবে সব নোডকে হোয়াইট সেটে যোগ করুন
  while(wSet.size() > 0) {
    for(int current = 0; current < NODE; current++) {
      if(wSet.find(current) != wSet.end())
        if(dfs(current, wSet, gSet, bSet))
          return true;
    }
  }
  return false;
}

int main() {
  bool res;
  res = hasCycle();
  if(res)
    cout << "The graph has cycle." << endl;
  else
    cout << "The graph has no cycle." << endl;
}

আউটপুট

The graph has cycle.
  1. C++ প্রোগ্রাম: নির্দেশিত গ্রাফে অয়লার চক্র আছে কিনা যাচাই

  2. Python-এ ডায়реक्टেড গ্রাফে সর্বোচ্চ রঙ মান বের করার প্রোগ্রাম

  3. পাইথনে ডায়रेक्टেড গ্রাফকে উল্টে ফেলার প্রোগ্রাম

  4. ডায়রেক্টেড গ্রাফে সাইকেল ডিটেক্ট করার পাইথন প্রোগ্রাম