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

C++ প্রোগ্রাম: ডিসজয়েন্ট সেট (Disjoint Set) ডেটা স্ট্রাকচার ইমপ্লিমেন্টেশন

পরিচয়

ডিসজয়েন্ট সেট (Disjoint Set) বা ইউনিয়ন-ফাইন্ড (Union-Find) একটি ডেটা স্ট্রাকচার যা একটি সেটকে অপরিবর্তনীয় সাবসেটে ভাগ করে রাখে। এটি দুটি প্রধান অপারেশন সাপোর্ট করে: Find এবং Union।

অপারেশনসমূহ:

  • MakeSet(x): প্রতিটি এলিমেন্টকে আলাদা একটি সেটে রাখে (parent[x] = x)।
  • Find(x): x-র রিপ্রেজেন্টেটিভ (রুট) ফেরত দেয়। পাথ কমপ্রেশন (path compression) ব্যবহার করে অপ্টিমাইজ করা যায়।
  • Union(x, y): দুটি সেটকে মার্জ করে। ইউনিয়ন বাই র‍্যাঙ্ক (union by rank) ব্যবহার করে ট्री আঁচড় রাখা যায়।

উদাহরণ কোড (অপ্টিমাইজড ভার্সন)

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

class DisjointSet {
    unordered_map<int, int> parent;
    unordered_map<int, int> rank;

public:
    void makeSet(vector<int> const &universe) {
        for (int i : universe) {
            parent[i] = i;
            rank[i] = 0;
        }
    }

    int Find(int x) {
        if (parent[x] != x)
            parent[x] = Find(parent[x]); // Path Compression
        return parent[x];
    }

    void Union(int x, int y) {
        int xRoot = Find(x);
        int yRoot = Find(y);
        if (xRoot == yRoot) return;

        // Union by Rank
        if (rank[xRoot] < rank[yRoot])
            parent[xRoot] = yRoot;
        else if (rank[xRoot] > rank[yRoot])
            parent[yRoot] = xRoot;
        else {
            parent[yRoot] = xRoot;
            rank[xRoot]++;
        }
    }

    void printSets(vector<int> const &universe) {
        for (int i : universe)
            cout << Find(i) << " ";
        cout << "\n";
    }
};

int main() {
    vector<int> universe = {6, 7, 1, 2, 3};
    DisjointSet ds;
    ds.makeSet(universe);

    ds.Union(7, 6);
    cout << "ইউনিয়ন(7,6) এর পর: ";
    ds.printSets(universe);

    cout << "Find(7) == Find(6): " << (ds.Find(7) == ds.Find(6) ? "Yes" : "No") << "\n";
    cout << "Find(3) == Find(4): " << (ds.Find(3) == ds.Find(4) ? "Yes" : "No") << "\n";
    return 0;
}

আউটপুট

ইউনিয়ন(7,6) এর পর: 6 6 1 2 3
Find(7) == Find(6): Yes
Find(3) == Find(4): No

ব্যবহার ক্ষেত্র

  • ক্রুস্কালের এমএসটি (MST) অ্যালগরিদম
  • সাইকেল ডিটেকশন অ্যান্ডিরেক্টেড গ্রাফে
  • নেটওয়ার্ক কানেক্টিভিটি
  • ইমেজ প্রসেসিং (কানেক্টেড কম্পোনেন্ট লেবেলিং)

ব্যাখ্যা

পাথ কমপ্রেশন এবং ইউনিয়ন বাই র‍্যাঙ্ক দুটো একসাথে ব্যবহার করলে অ্যামর্টাইজড টাইম কমপ্লেক্সিটি প্রায় O(α(n)) হয়, যা প্রায় কনস্ট্যান্ট। এই ইমপ্লিমেন্টেশনে `unordered_map` ব্যবহার করা হয়েছে যাতে যেকোনো ইন্টিজার ভ্যালু হ্যান্ডেল করা যায়।

  1. C++ STL-এ Set Union বাস্তবায়ন: দুটি সেটের ইউনিয়ন

  2. C++ STL-এ Set Intersection বাস্তবায়ন: দুটি সেটের অন্তঃসেট

  3. C++ STL-এ Set Difference বাস্তবায়ন: সেট বিয়োগ

  4. C++ প্রোগ্রাম: র‍্যাডিক্স সর্ট বাস্তবায়ন