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

C++ প্রোগ্রাম: গ্রাহাম স্ক্যান অ্যালগরিদম দিয়ে কনভেক্স হাল খুঁজে বের করা

কনভেক্স হাল হলো সর্বনিম্ন বন্ধ এলাকা যা সমস্ত দিয়ে गये ডেটা পয়েন্ট কভার করতে পারে।

গ্রাহাম স্ক্যান অ্যালগরিদম কনভেক্স হালের কর্নার পয়েন্টগুলো বের করে। এই অ্যালগরিদমে, প্রথমে সবচেয়ে নিচের পয়েন্টটি বেছে নেওয়া হয়। সেই পয়েন্টটি কনভেক্স হালের শুরুতের পয়েন্ট। বাকি n-1 টি ভার্টেক্স শুরুতের পয়েন্ট থেকে অ্যান্টি-ক্লকওয়াইজ ডিরেকশন অনুযায়ী সর্ট করা হয়। যদি দুই বা ততোধিক পয়েন্ট একই কোণ তৈরি করে, তবে শুরুতের পয়েন্ট থেকে সবচেয়ে দূরবর্তী পয়েন্টটি বাদে অন্যগুলো মুছে ফেলা হয়।

বাকি পয়েন্টগুলো থেকে, সেগুলো স্টকে পুশ করা হয়। এবং স্টক থেকে একে একে আইটেম পপ করা হয়, যখন স্টকের টপ পয়েন্ট, সেকেন্ড টপ পয়েন্ট এবং নতুন বেছে নেওয়া পয়েন্ট points[i] অ্যান্টি-ক্লকওয়াইজ রোটেশন তৈরি করে না, চেক করার পর points[i] স্টকে ইনসার্ট করা হয়।

ইনপুট: পয়েন্ট সেট: {(-7,8), (-4,6), (2,6), (6,4), (8,6), (7,-2), (4,-6), (8,-7),(0,0), (3,-2),(6,-10),(0,-6),(-9,-5),(-8,-2),(-8,0),(-10,3),(-2,2),(-10,4)}
আউটপুট: কনভেক্স হালের বাউন্ডারি পয়েন্টগুলো: (-9, -5) (-10, 3) (-10, 4) (-7, 8) (8, 6) (8, -7) (6, -10)

অ্যালগরিদম

findConvexHull(points, n)

ইনপুট: পয়েন্ট সেট, পয়েন্টের সংখ্যা।

আউটপুট: কনভেক্স হালের বাউন্ডারি পয়েন্টগুলো।

শুরু
  minY := points[0].y
  min := 0
  for i := 1 to n-1 do
    y := points[i].y
    if y < minY or (minY = y and points[i].x < points[min].x), then
      minY := points[i].y
      min := i
  লুপ শেষ
  swap points[0] and points[min]
  p0 := points[0]
  points[1] থেকে শেষ পর্যন্ত সর্ট করুন
  arrSize := 1
  for i := 1 to n, do
    when i < n-1 and (p0, points[i], points[i+1]) are collinear, do
      i := i + 1
    লুপ শেষ
    points[arrSize] := points[i]
    arrSize := arrSize + 1
  লুপ শেষ
  if arrSize < 3, then
    return cHullPoints
  push points[0] into stack
  push points[1] into stack
  push points[2] into stack
  for i := 3 to arrSize, do
    while top of stack, item below the top and points[i] is not in anticlockwise rotation, do
      delete top element from stack
    লুপ শেষ
    push points[i] into stack
  লুপ শেষ
  while stack is not empty, do
    item stack top element into cHullPoints
    pop from stack
  লুপ শেষ
শেষ

উদাহরণ কোড

#include<iostream>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;

struct point {
    int x, y;
};

point p0;

point secondTop(stack<point> &stk) {
    point tempPoint = stk.top();
    stk.pop();
    point res = stk.top();
    stk.push(tempPoint);
    return res;
}

int squaredDist(point p1, point p2) {
    return ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
}

int direction(point a, point b, point c) {
    int val = (b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y);
    if (val == 0)
        return 0; //colinear
    else if(val < 0)
        return 2; //anti-clockwise direction
    return 1; //clockwise direction
}

int comp(const void *point1, const void*point2) {
    point *p1 = (point*)point1;
    point *p2 = (point*)point2;
    int dir = direction(p0, *p1, *p2);
    if(dir == 0)
        return (squaredDist(p0, *p2) >= squaredDist(p0, *p1))?-1 : 1;
    return (dir==2)? -1 : 1;
}

vector<point> findConvexHull(point points[], int n) {
    vector<point> convexHullPoints;
    int minY = points[0].y, min = 0;
    for(int i = 1; i < n; i++) {
        int y = points[i].y;
        if((y < minY) || (minY == y) && points[i].x < points[min].x) {
            minY = points[i].y;
            min = i;
        }
    }
    swap(points[0], points[min]);
    p0 = points[0];
    qsort(&points[1], n-1, sizeof(point), comp);
    int arrSize = 1;
    for(int i = 1; i < n; i++) {
        while(i < n-1 && direction(p0, points[i], points[i+1]) == 0)
            i++;
        points[arrSize] = points[i];
        arrSize++;
    }
    if(arrSize < 3)
        return convexHullPoints;
    stack<point> stk;
    stk.push(points[0]); stk.push(points[1]); stk.push(points[2]);
    for(int i = 3; i < arrSize; i++) {
        while(direction(secondTop(stk), stk.top(), points[i]) != 2)
            stk.pop();
        stk.push(points[i]);
    }
    while(!stk.empty()) {
        convexHullPoints.push_back(stk.top());
        stk.pop();
    }
    return convexHullPoints;
}

int main() {
    point points[] = {{-7,8},{-4,6},{2,6},{6,4},{8,6},{7,-2},{4,-6},{8,-7},{0,0},
        {3,-2},{6,-10},{0,-6},{-9,-5},{-8,-2},{-8,0},{-10,3},{-2,2},{-10,4}};
    int n = 18;
    vector<point> result;
    result = findConvexHull(points, n);
    cout << "Boundary points of convex hull are: " << endl;
    vector<point>::iterator it;
    for(it = result.begin(); it != result.end(); it++)
        cout << "(" << it->x << ", " << it->y << ") ";
}

আউটপুট

Boundary points of convex hull are: (-9, -5) (-10, 3) (-10, 4) (-7, 8) (8, 6) (8, -7) (6, -10)
  1. সি++-এ একটি রেখার মিড-পয়েন্ট বের করার প্রোগ্রাম

  2. সি++-এ ত্রিভুজের কেন্ড্রয়েড (Centroid) বের করার প্রোগ্রাম

  3. সি++-এ সমান্তরাল চতুর্ভুজের (Parallelogram) ক্ষেত্রফল বের করার প্রোগ্রাম

  4. C++-এ ভিজিনার সাইফার (Vigenere Cipher) ইমপ্লিমেন্টেশন