提交 befec354 编写于 作者: F Filip Hlásek

Merge branch 'master' into fixgraph

/**
* @file
* @brief Implementation of [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm.
*
* @details
* Given a set of points in the plane. the convex hull of the set
* is the smallest convex polygon that contains all the points of it.
*
* ### Algorithm
* The idea of Jarvis’s Algorithm is simple, we start from the leftmost point
* (or point with minimum x coordinate value) and we
* keep wrapping points in counterclockwise direction.
*
* The idea is to use orientation() here. Next point is selected as the
* point that beats all other points at counterclockwise orientation, i.e.,
* next point is q if for any other point r,
* we have “orientation(p, q, r) = counterclockwise”.
*
* For Example,
* If points = {{0, 3}, {2, 2}, {1, 1}, {2, 1},
{3, 0}, {0, 0}, {3, 3}};
*
* then the convex hull is
* (0, 3), (0, 0), (3, 0), (3, 3)
*
* @author [Rishabh Agarwal](https://github.com/rishabh-997)
*/
#include <vector>
#include <cassert>
#include <iostream>
/**
* @namespace geometry
* @brief Geometry algorithms
*/
namespace geometry {
/**
* @namespace jarvis
* @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm
*/
namespace jarvis {
/**
* Structure defining the x and y co-ordinates of the given
* point in space
*/
struct Point {
int x, y;
};
/**
* Class which can be called from main and is globally available
* throughout the code
*/
class Convexhull {
std::vector<Point> points;
int size;
public:
/**
* Constructor of given class
*
* @param pointList list of all points in the space
* @param n number of points in space
*/
explicit Convexhull(const std::vector<Point> &pointList) {
points = pointList;
size = points.size();
}
/**
* Creates convex hull of a set of n points.
* There must be 3 points at least for the convex hull to exist
*
* @returns an vector array containing points in space
* which enclose all given points thus forming a hull
*/
std::vector<Point> getConvexHull() const {
// Initialize Result
std::vector<Point> hull;
// Find the leftmost point
int leftmost_point = 0;
for (int i = 1; i < size; i++) {
if (points[i].x < points[leftmost_point].x) {
leftmost_point = i;
}
}
// Start from leftmost point, keep moving counterclockwise
// until reach the start point again. This loop runs O(h)
// times where h is number of points in result or output.
int p = leftmost_point, q = 0;
do {
// Add current point to result
hull.push_back(points[p]);
// Search for a point 'q' such that orientation(p, x, q)
// is counterclockwise for all points 'x'. The idea
// is to keep track of last visited most counter clock-
// wise point in q. If any point 'i' is more counter clock-
// wise than q, then update q.
q = (p + 1) % size;
for (int i = 0; i < size; i++) {
// If i is more counterclockwise than current q, then
// update q
if (orientation(points[p], points[i], points[q]) == 2) {
q = i;
}
}
// Now q is the most counterclockwise with respect to p
// Set p as q for next iteration, so that q is added to
// result 'hull'
p = q;
} while (p != leftmost_point); // While we don't come to first point
return hull;
}
/**
* This function returns the geometric orientation for the three points
* in a space, ie, whether they are linear ir clockwise or
* anti-clockwise
* @param p first point selected
* @param q adjacent point for q
* @param r adjacent point for q
*
* @returns 0 -> Linear
* @returns 1 -> Clock Wise
* @returns 2 -> Anti Clock Wise
*/
static int orientation(const Point &p, const Point &q, const Point &r) {
int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0) {
return 0;
}
return (val > 0) ? 1 : 2;
}
};
} // namespace jarvis
} // namespace geometry
/**
* Test function
* @returns void
*/
static void test() {
std::vector<geometry::jarvis::Point> points = {{0, 3},
{2, 2},
{1, 1},
{2, 1},
{3, 0},
{0, 0},
{3, 3}
};
geometry::jarvis::Convexhull hull(points);
std::vector<geometry::jarvis::Point> actualPoint;
actualPoint = hull.getConvexHull();
std::vector<geometry::jarvis::Point> expectedPoint = {{0, 3},
{0, 0},
{3, 0},
{3, 3}};
for (int i = 0; i < expectedPoint.size(); i++) {
assert(actualPoint[i].x == expectedPoint[i].x);
assert(actualPoint[i].y == expectedPoint[i].y);
}
std::cout << "Test implementations passed!\n";
}
/** Driver Code */
int main() {
test();
return 0;
}
......@@ -9,8 +9,8 @@
/**
* Iterative function/method to print graph:
* @param a[] : array of vectors (2D)
* @param V : vertices
* @param a adjacency list representation of the graph
* @param V number of vertices
* @return void
**/
void print(const std::vector< std::vector<int> > &a, int V) {
......@@ -29,10 +29,10 @@ void print(const std::vector< std::vector<int> > &a, int V) {
/**
* //Recursive function/method to push vertices into stack passed as parameter:
* @param v : vertices
* @param &st : stack passed by reference
* @param &vis : array to keep track of visited nodes (boolean type)
* @param adj[] : array of vectors to represent graph
* @param v vertices
* @param st stack passed by reference
* @param vis array to keep track of visited nodes (boolean type)
* @param adj adjacency list representation of the graph
* @return void
**/
void push_vertex(int v, std::stack<int> *st, std::vector<bool> *vis, const std::vector< std::vector<int> > &adj) {
......@@ -47,9 +47,9 @@ void push_vertex(int v, std::stack<int> *st, std::vector<bool> *vis, const std::
/**
* //Recursive function/method to implement depth first traversal(dfs):
* @param v : vertices
* @param vis : array to keep track of visited nodes (boolean type)
* @param grev[] : graph with reversed edges
* @param v vertices
* @param vis array to keep track of visited nodes (boolean type)
* @param grev graph with reversed edges
* @return void
**/
void dfs(int v, std::vector<bool> *vis, const std::vector< std::vector<int> > &grev) {
......@@ -65,8 +65,8 @@ void dfs(int v, std::vector<bool> *vis, const std::vector< std::vector<int> > &g
// function/method to implement Kosaraju's Algorithm:
/**
* Info about the method
* @param V : vertices in graph
* @param adj[] : array of vectors that represent a graph (adjacency list/array)
* @param V vertices in graph
* @param adj array of vectors that represent a graph (adjacency list/array)
* @return int ( 0, 1, 2..and so on, only unsigned values as either there can be
no SCCs i.e. none(0) or there will be x no. of SCCs (x>0)) i.e. it returns the
count of (number of) strongly connected components (SCCs) in the graph.
......
......@@ -5,7 +5,7 @@
//#include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
const int mx = 1e6 + 5;
typedef int64_t ll;
using ll = int64_t;
std::array<ll, mx> parent;
ll node, edge;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册