Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using 2D Coords #8

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
11ba7e6
🚧 Updating the code
amarrerod Apr 1, 2022
6ea7265
🔖 Initial version works
amarrerod Apr 1, 2022
4ce74a7
🐛 Includes working example
amarrerod Apr 1, 2022
5f18ad6
✨ Example completed
amarrerod Apr 1, 2022
c424e64
Create c-cpp.yml
amarrerod Apr 1, 2022
c94af7d
Merge branch 'master' of github.com:amarrerod/DBSCAN
amarrerod Apr 1, 2022
695d59d
✨ Reduces complexity with only 2dims
amarrerod Apr 1, 2022
d68f4fb
📝 Updates README
amarrerod Apr 1, 2022
4c16b98
👷 Working on deploy
amarrerod Apr 1, 2022
ddecebe
🚚 Moving stuff
amarrerod Apr 3, 2022
8017055
💚 Fixing Cmake installation
amarrerod Apr 4, 2022
ca690b5
🚧 Working on the lib
amarrerod Apr 4, 2022
76c74c2
🚧 Working on shared lib
amarrerod Apr 5, 2022
6f50381
Update dbscan.pc.in
amarrerod Apr 5, 2022
c38c27c
🐛 Fix an installation bug
amarrerod Apr 5, 2022
fe7d2e0
Merge branch 'master' of github.com:amarrerod/DBSCAN
amarrerod Apr 5, 2022
a29cfe6
💚 Working on build
amarrerod Apr 5, 2022
bf93bb0
✨ Introduces cluster counter
amarrerod Apr 6, 2022
59b93d0
🧐 Includes data samples
amarrerod Apr 6, 2022
ae288c8
♻️ Includes return in run method
amarrerod Apr 6, 2022
346a13d
✨ Introduces new constructor
amarrerod Apr 7, 2022
f4add23
✨ Includes the cluster class
amarrerod Apr 25, 2022
05c2d58
🐛 Fixes a bug in the DBSCAN code
amarrerod May 2, 2022
e5cecaf
🐛 Fixes the algorithm an cluster generation
amarrerod May 2, 2022
48c0bd8
👷 Updates installation configuration
amarrerod Oct 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
🚚 Moving stuff
  • Loading branch information
amarrerod committed Apr 3, 2022
commit ddecebecdca40b2af93332bc028464710fc27721
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -lstdc++fs -O3 -ffast-math -Wall -march=native -mtune=native")


add_library(${PROJECT_NAME} include/dbscan.h)
add_library(${PROJECT_NAME} include/dbscan/dbscan.h src/dbscan/dbscan.cpp)
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} LINKER_LANGUAGE CXX)
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 1)
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER include/dbscan.h)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE src)

include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
Expand Down
150 changes: 0 additions & 150 deletions include/dbscan.h

This file was deleted.

52 changes: 52 additions & 0 deletions include/dbscan/dbscan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef DBSCAN_H
#define DBSCAN_H

#include <iostream>
#include <utility>
#include <vector>

#define UNCLASSIFIED -1
#define CORE_POINT 1
#define BORDER_POINT 2
#define NOISE -2
#define SUCCESS 0
#define FAILURE -3

using namespace std;

typedef struct Point_ {
float x, y; // X, Y position
int clusterID; // clustered ID
Point_(const float& _x, const float& _y, const int& _c)
: x(_x), y(_y), clusterID(_c) {}

friend ostream& operator<<(std::ostream& os, const Point_& p) {
return os << "(" << p.x << ", " << p.y << ") - " << p.clusterID;
}
} Point;

class DBSCAN {
public:
DBSCAN(const unsigned int& minPts, const float& eps,
const vector<Point>& points);
~DBSCAN() = default;

int run();
vector<int> calculateCluster(Point point);
int expandCluster(Point point, int clusterID);
inline double calculateDistance(const Point& pointCore,
const Point& pointTarget);

int getTotalPointSize() { return m_pointSize; }
int getMinimumClusterSize() { return m_minPoints; }
int getEpsilonSize() { return m_epsilon; }
const vector<Point>& getPoints() { return m_points; }

private:
unsigned int m_minPoints;
float m_epsilon;
unsigned int m_pointSize;
vector<Point> m_points;
};

#endif // DBSCAN_H
Binary file modified lib/libdbscan.a
Binary file not shown.
112 changes: 112 additions & 0 deletions src/dbscan/dbscan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @file dbscan.cpp
* @author Alejandro Marrero ([email protected])
* @brief
* @version 0.1
* @date 2022-04-03
*
* @copyright Copyright (c) 2022
*
*/

#include <dbscan/dbscan.h>

DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps,
const vector<Point>& points)
: m_minPoints(minPts), m_epsilon(eps) {
m_pointSize = points.size();
m_points = points;
}

int DBSCAN::run() {
int clusterID = 1;
typename vector<Point>::iterator iter;
for (iter = m_points.begin(); iter != m_points.end(); ++iter) {
if (iter->clusterID == UNCLASSIFIED) {
if (expandCluster(*iter, clusterID) != FAILURE) {
clusterID += 1;
}
}
}
return 0;
}

int DBSCAN::expandCluster(Point point, int clusterID) {
vector<int> clusterSeeds = calculateCluster(point);

if (clusterSeeds.size() < m_minPoints) {
point.clusterID = NOISE;
return FAILURE;
} else {
int index = 0, indexCorePoint = 0;
vector<int>::iterator iterSeeds;
for (iterSeeds = clusterSeeds.begin(); iterSeeds != clusterSeeds.end();
++iterSeeds) {
m_points.at(*iterSeeds).clusterID = clusterID;
if (m_points.at(*iterSeeds).x == point.x &&
m_points.at(*iterSeeds).y == point.y) {
indexCorePoint = index;
}
++index;
}
clusterSeeds.erase(clusterSeeds.begin() + indexCorePoint);

for (vector<int>::size_type i = 0, n = clusterSeeds.size(); i < n;
++i) {
vector<int> clusterNeighors =
calculateCluster(m_points.at(clusterSeeds[i]));

if (clusterNeighors.size() >= m_minPoints) {
vector<int>::iterator iterNeighors;
for (iterNeighors = clusterNeighors.begin();
iterNeighors != clusterNeighors.end(); ++iterNeighors) {
if (m_points.at(*iterNeighors).clusterID == UNCLASSIFIED ||
m_points.at(*iterNeighors).clusterID == NOISE) {
if (m_points.at(*iterNeighors).clusterID ==
UNCLASSIFIED) {
clusterSeeds.push_back(*iterNeighors);
n = clusterSeeds.size();
}
m_points.at(*iterNeighors).clusterID = clusterID;
}
}
}
}

return SUCCESS;
}
}

/**
* @brief Calculates the clusters in the points
*
* @param point
* @return vector<int>
*/

vector<int> DBSCAN::calculateCluster(Point point) {
int index = 0;
typename vector<Point>::iterator iter;
vector<int> clusterIndex;
for (iter = m_points.begin(); iter != m_points.end(); ++iter) {
if (calculateDistance(point, *iter) <= m_epsilon) {
clusterIndex.push_back(index);
}
index++;
}
return clusterIndex;
}

/**
* @brief Calculates the distance between two 3d points
*
* @param pointCore
* @param pointTarget
* @return double
*/

inline double DBSCAN::calculateDistance(const Point& pointCore,
const Point& pointTarget) {
return ((pointCore.x - pointTarget.x) * (pointCore.x - pointTarget.x)) +
((pointCore.y - pointTarget.y) * (pointCore.y - pointTarget.y));
}