Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2020
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.64 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <ctime>
  4. #include <cmath>
  5.  
  6. #include <stack>
  7. #include <queue>
  8. #include <string>
  9. #include <fstream>
  10. #include <vector>
  11.  
  12. using namespace std;
  13.  
  14. class Point
  15. {
  16.     int id;
  17.     double x, y;
  18.  
  19. public:
  20.     Point(int, double, double);
  21.  
  22.     int getId();
  23.     double getX();
  24.     double getY();
  25.  
  26.     void display();
  27.  
  28.     double operator*(Point&);
  29.     bool operator>(Point&);
  30.     bool operator<(Point&);
  31.  
  32.     static int calcAngle(Point*, Point*);
  33. };
  34.  
  35. class GrahamAlgorithm
  36. {
  37.     vector<Point*> points;
  38.     vector<Point*> results;
  39.  
  40.     Point createVector(Point*, Point*);
  41. public:
  42.     GrahamAlgorithm(string);
  43.     ~GrahamAlgorithm();
  44.  
  45.     Point* findMinimium();
  46.     vector<Point*> sort();
  47.  
  48.     void execute();
  49.     void display();
  50.  
  51.     bool comparator(Point*, Point*);
  52. };
  53.  
  54. Point::Point(int id, double x, double y)
  55. {
  56.     this->id = id;
  57.     this->x = x;
  58.     this->y = y;
  59. }
  60.  
  61. int Point::getId()
  62. {
  63.     return this->id;
  64. }
  65.  
  66. double Point::getX()
  67. {
  68.     return this->x;
  69. }
  70.  
  71. double Point::getY()
  72. {
  73.     return this->y;
  74. }
  75.  
  76. void Point::display()
  77. {
  78.     cout << id << " " << x << " " << y << endl;
  79. }
  80.  
  81. double Point::operator*(Point& b)
  82. {
  83.     return this->y * b.x - b.y * this->x;
  84. }
  85.  
  86. bool Point::operator>(Point& b)
  87. {
  88.     return *this * b >= 0;
  89. }
  90.  
  91. bool Point::operator<(Point& b)
  92. {
  93.     return *this * b < 0;
  94. }
  95.  
  96. int Point::calcAngle(Point* point1, Point* point2)
  97. {
  98.     double x1 = point1->getX();
  99.     double x2 = point2->getX();
  100.  
  101.     double y1 = point1->getY();
  102.     double y2 = point2->getY();
  103.  
  104.     double a = fabs(x2 - x1);
  105.     double b = y2 - y1;
  106.  
  107.     int angle = atan(b / a) * 180 / M_PI;
  108.  
  109.     return x2 < x1 ? 180 - angle : angle;
  110. }
  111.  
  112. GrahamAlgorithm::GrahamAlgorithm(string filePath)
  113. {
  114.     fstream file(filePath);
  115.  
  116.     if (!file.good()) {
  117.         throw "ERROR: Cannot read file!";
  118.     }
  119.  
  120.     int n;
  121.     file >> n;
  122.  
  123.     for (int i = 0; i < n; i++) {
  124.         double x, y;
  125.  
  126.         file >> x;
  127.         file >> y;
  128.  
  129.         this->points.push_back(new Point(i, x, y));
  130.     }
  131.  
  132.     file.close();
  133. }
  134.  
  135. GrahamAlgorithm::~GrahamAlgorithm()
  136. {
  137.     for (auto & it : this->points) {
  138.         delete it;
  139.     }
  140. }
  141.  
  142. Point GrahamAlgorithm::createVector(Point* a, Point* b)
  143. {
  144.     Point vector(0, b->getX() - a->getX(), b->getY() - a->getY());
  145.     return vector;
  146. }
  147.  
  148. Point* GrahamAlgorithm::findMinimium()
  149. {
  150.     Point* minimum = points[0];
  151.  
  152.     for (auto & point : points) {
  153.         if (*minimum > *point) {
  154.             minimum = point;
  155.         }
  156.     }
  157.  
  158.     return minimum;
  159. }
  160.  
  161. // znowu heap sort, jakby ktoś pytał
  162. vector<Point*> GrahamAlgorithm::sort()
  163. {
  164.     vector<Point*> heap;
  165.  
  166.     Point* minimal = findMinimium();
  167.     Point normal = *minimal;
  168.  
  169.     int heapSize = 0;
  170.     for (auto & point : points) {
  171.         if (point == minimal) {
  172.             continue;
  173.         }
  174.  
  175.         heap.push_back(point);
  176.         heapSize++;
  177.  
  178.         int index = heapSize - 1;
  179.         int parentIndex = (index - 1) / 2;
  180.  
  181.         while (index > 0) {
  182.             Point* current = heap[index];
  183.             Point* parent = heap[parentIndex];
  184.  
  185.             if (Point::calcAngle(minimal, current) < Point::calcAngle(minimal, parent)) {
  186.                 Point* temp = heap[index];
  187.                 heap[index] = heap[parentIndex];
  188.                 heap[parentIndex] = temp;
  189.             } else {
  190.                 break;
  191.             }
  192.  
  193.             index = parentIndex;
  194.             parentIndex = (index - 1) / 2;
  195.         }
  196.     }
  197.  
  198.     vector<Point*> sorted;
  199.  
  200.     while (heapSize > 0) {
  201.         sorted.push_back(heap[0]);
  202.  
  203.         Point* temp = heap[0];
  204.         heap[0] = heap[heapSize - 1];
  205.         heap[heapSize - 1] = temp;
  206.  
  207.         heap.erase(heap.end() - 1);
  208.         heapSize--;
  209.  
  210.         int parent = 0;
  211.  
  212.         int left = parent * 2 + 1;
  213.         int right = parent * 2 + 2;
  214.  
  215.         while (parent < heapSize) {
  216.             if (right < heapSize) {
  217.                 if (Point::calcAngle(minimal, heap[left]) < Point::calcAngle(minimal, heap[right])) {
  218.                     if (Point::calcAngle(minimal, heap[left]) < Point::calcAngle(minimal, heap[parent])) {
  219.                         temp = heap[parent];
  220.                         heap[parent] = heap[left];
  221.                         heap[left] = temp;
  222.  
  223.                         parent = left;
  224.                     } else {
  225.                         break;
  226.                     }
  227.                 } else {
  228.                     if (Point::calcAngle(minimal, heap[left]) < Point::calcAngle(minimal, heap[parent])) {
  229.                         temp = heap[parent];
  230.                         heap[parent] = heap[right];
  231.                         heap[right] = temp;
  232.  
  233.                         parent = right;
  234.                     } else {
  235.                         break;
  236.                     }
  237.                 }
  238.             } else if (left < heapSize) {
  239.                 if (Point::calcAngle(minimal, heap[left]) < Point::calcAngle(minimal, heap[parent])) {
  240.                     temp = heap[parent];
  241.                     heap[parent] = heap[left];
  242.                     heap[left] = temp;
  243.  
  244.                     parent = left;
  245.                 } else {
  246.                     break;
  247.                 }
  248.             } else {
  249.                 break;
  250.             }
  251.  
  252.             left = parent * 2 + 1;
  253.             right = parent * 2 + 2;
  254.         }
  255.     }
  256.  
  257.     return sorted;
  258. }
  259.  
  260. bool GrahamAlgorithm::comparator(Point* a, Point* b)
  261. {
  262.     int angle = Point::calcAngle(a, b);
  263.     return angle > 0 && angle < 90;
  264. }
  265.  
  266. void GrahamAlgorithm::execute()
  267. {
  268.     Point* minimal = findMinimium();
  269.     vector<Point*> sortedPoints = sort();
  270.  
  271.     results.push_back(minimal);
  272.     results.push_back(sortedPoints[0]);
  273.  
  274.     queue<Point*> line;
  275.     for (int i = 1; i < sortedPoints.size(); i++) {
  276.         line.push(sortedPoints[i]);
  277.     }
  278.  
  279.     Point* current = line.front();
  280.     line.pop();
  281.  
  282.     Point* prelast = line.front();
  283.     line.pop();
  284.  
  285.     Point* last;
  286.  
  287.     while (!line.empty()) {
  288.         last = line.front();
  289.         line.pop();
  290.  
  291.         results.push_back(current);
  292.  
  293.         Point a = createVector(current, prelast);
  294.         Point b = createVector(prelast, last);
  295.  
  296.         while (b * a < 0) {
  297.             prelast = *(results.end() - 1);
  298.             results.pop_back();
  299.  
  300.             current = *(results.end() - 1);
  301.  
  302.             a = createVector(current, prelast);
  303.             b = createVector(prelast, last);
  304.         }
  305.  
  306.         current = prelast;
  307.         prelast = last;
  308.     }
  309. }
  310.  
  311. void GrahamAlgorithm::display()
  312. {
  313.     Point* minimum = findMinimium();
  314.  
  315.     cout << "Points:" << endl;
  316.     for (auto & point : points) {
  317.         point->display();
  318.     }
  319.  
  320.     cout << endl << "Sorted: " << endl;
  321.     for (auto & it : sort()) {
  322.         it->display();
  323.     }
  324.  
  325.     cout << endl << "Solution: ";
  326.     for (auto & point : results) {
  327.         cout << point->getId() << " -> ";
  328.     }
  329.  
  330.     cout << results[0]->getId() << endl
  331.          << "Number of points: " << results.size() << endl << endl;
  332.  
  333.     Point* a = points[88];
  334.     Point* b = points[5];
  335.     Point* c = points[84];
  336.  
  337.     Point vecA = createVector(a, b);
  338.     Point vecB = createVector(b, c);
  339.  
  340.     cout << vecB * vecA << endl << endl;
  341. }
  342.  
  343. int main()
  344. {
  345.     try {
  346.         GrahamAlgorithm* algorithm = new GrahamAlgorithm("points2.txt");
  347.  
  348.         clock_t start = clock();
  349.         algorithm->execute();
  350.         clock_t end = clock();
  351.         algorithm->display();
  352.  
  353.         cout << fixed << "Total time: " << (double) (end - start) / CLOCKS_PER_SEC << endl << endl;
  354.         delete algorithm;
  355.     } catch (string err) {
  356.         cerr << err << endl << endl;
  357.         exit(EXIT_FAILURE);
  358.     }
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement