From 11ba7e6cf6fa8554384d75c4b1ad3b0da7c2af58 Mon Sep 17 00:00:00 2001 From: Alejandro Marrero Date: Fri, 1 Apr 2022 13:00:04 +0100 Subject: [PATCH 01/23] =?UTF-8?q?=F0=9F=9A=A7=20Updating=20the=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 10 ++++ dbscan.cpp | 92 ----------------------------- dbscan.h | 156 ++++++++++++++++++++++++++++++++++++++++--------- main.cpp | 55 ++++++++--------- 4 files changed, 163 insertions(+), 150 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 dbscan.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..696743b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.0.0) +project(DBSCAN LANGUAGES C CXX VERSION 0.1.0) + +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(DBSCAN DBSCAN.cpp) + +add_executable(example main.cpp) diff --git a/dbscan.cpp b/dbscan.cpp deleted file mode 100644 index eea77f8..0000000 --- a/dbscan.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "dbscan.h" - -int DBSCAN::run() -{ - int clusterID = 1; - vector::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 clusterSeeds = calculateCluster(point); - - if ( clusterSeeds.size() < m_minPoints ) - { - point.clusterID = NOISE; - return FAILURE; - } - else - { - int index = 0, indexCorePoint = 0; - vector::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 && m_points.at(*iterSeeds).z == point.z ) - { - indexCorePoint = index; - } - ++index; - } - clusterSeeds.erase(clusterSeeds.begin()+indexCorePoint); - - for( vector::size_type i = 0, n = clusterSeeds.size(); i < n; ++i ) - { - vector clusterNeighors = calculateCluster(m_points.at(clusterSeeds[i])); - - if ( clusterNeighors.size() >= m_minPoints ) - { - vector::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; - } -} - -vector DBSCAN::calculateCluster(Point point) -{ - int index = 0; - vector::iterator iter; - vector clusterIndex; - for( iter = m_points.begin(); iter != m_points.end(); ++iter) - { - if ( calculateDistance(point, *iter) <= m_epsilon ) - { - clusterIndex.push_back(index); - } - index++; - } - return clusterIndex; -} - -inline double DBSCAN::calculateDistance(const Point& pointCore, const Point& pointTarget ) -{ - return pow(pointCore.x - pointTarget.x,2)+pow(pointCore.y - pointTarget.y,2)+pow(pointCore.z - pointTarget.z,2); -} - - diff --git a/dbscan.h b/dbscan.h index c0a75a1..11106cc 100644 --- a/dbscan.h +++ b/dbscan.h @@ -1,8 +1,8 @@ #ifndef DBSCAN_H #define DBSCAN_H -#include #include +#include #define UNCLASSIFIED -1 #define CORE_POINT 1 @@ -13,38 +13,140 @@ using namespace std; -typedef struct Point_ -{ - float x, y, z; // X, Y, Z position +template +struct Point { + T x, y, z; // X, Y, Z position int clusterID; // clustered ID -}Point; +}; +template class DBSCAN { -public: - DBSCAN(unsigned int minPts, float eps, vector points){ - m_minPoints = minPts; - m_epsilon = eps; - m_points = points; - m_pointSize = points.size(); - } - ~DBSCAN(){} + public: + DBSCAN(const unsigned int& minPts, const float& eps, + const vector>& points); + ~DBSCAN() = default; int run(); - vector 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;} - -public: - vector m_points; - -private: - unsigned int m_pointSize; + vector 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>& getPoints() { return m_points; } + + private: unsigned int m_minPoints; float m_epsilon; + unsigned int m_pointSize; + vector> m_points; }; -#endif // DBSCAN_H +template +DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, + const vector>& points) + : m_minPoints(minPts), m_epsilon(eps) { + m_pointSize = points.size(); + m_points = points; +} + +template +int DBSCAN::run() { + int clusterID = 1; + vector>::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; +} + +template +int DBSCAN::expandCluster(Point point, int clusterID) { + vector clusterSeeds = calculateCluster(point); + + if (clusterSeeds.size() < m_minPoints) { + point.clusterID = NOISE; + return FAILURE; + } else { + int index = 0, indexCorePoint = 0; + vector::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 && + m_points.at(*iterSeeds).z == point.z) { + indexCorePoint = index; + } + ++index; + } + clusterSeeds.erase(clusterSeeds.begin() + indexCorePoint); + + for (vector::size_type i = 0, n = clusterSeeds.size(); i < n; + ++i) { + vector clusterNeighors = + calculateCluster(m_points.at(clusterSeeds[i])); + + if (clusterNeighors.size() >= m_minPoints) { + vector::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 + */ +template +vector DBSCAN::calculateCluster(Point point) { + int index = 0; + vector>::iterator iter; + vector 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 + */ +template +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)) + + ((pointCore.z - pointTarget.z) * (pointCore.z - pointTarget.z)); +} + +#endif // DBSCAN_H diff --git a/main.cpp b/main.cpp index 1e9ec0f..12ee669 100644 --- a/main.cpp +++ b/main.cpp @@ -1,66 +1,59 @@ #include + #include + #include "dbscan.h" -#define MINIMUM_POINTS 4 // minimum number of cluster -#define EPSILON (0.75*0.75) // distance for clustering, metre^2 +#define MINIMUM_POINTS 4 // minimum number of cluster +#define EPSILON (0.75 * 0.75) // distance for clustering, metre^2 -void readBenchmarkData(vector& points) -{ +void readBenchmarkData(vector &points) { // load point cloud FILE *stream; - stream = fopen ("benchmark_hepta.dat","ra"); + stream = fopen("benchmark_hepta.dat", "ra"); unsigned int minpts, num_points, cluster, i = 0; double epsilon; fscanf(stream, "%u\n", &num_points); - Point *p = (Point *)calloc(num_points, sizeof(Point)); + Point *p = (Point *)calloc(num_points, sizeof(Point)); - while (i < num_points) - { - fscanf(stream, "%f,%f,%f,%d\n", &(p[i].x), &(p[i].y), &(p[i].z), &cluster); - p[i].clusterID = UNCLASSIFIED; - points.push_back(p[i]); - ++i; + while (i < num_points) { + fscanf(stream, "%f,%f,%f,%d\n", &(p[i].x), &(p[i].y), &(p[i].z), + &cluster); + p[i].clusterID = UNCLASSIFIED; + points.push_back(p[i]); + ++i; } free(p); fclose(stream); } -void printResults(vector& points, int num_points) -{ +void printResults(vector &points, int num_points) { int i = 0; - printf("Number of points: %u\n" + printf( + "Number of points: %u\n" " x y z cluster_id\n" - "-----------------------------\n" - , num_points); - while (i < num_points) - { - printf("%5.2lf %5.2lf %5.2lf: %d\n", - points[i].x, - points[i].y, points[i].z, - points[i].clusterID); - ++i; + "-----------------------------\n", + num_points); + while (i < num_points) { + printf("%5.2lf %5.2lf %5.2lf: %d\n", points[i].x, points[i].y, + points[i].z, points[i].clusterID); + ++i; } } -int main() -{ +int main() { vector points; - // read point data readBenchmarkData(points); - // constructor DBSCAN ds(MINIMUM_POINTS, EPSILON, points); - // main loop ds.run(); - // result of DBSCAN algorithm - printResults(ds.m_points, ds.getTotalPointSize()); + printResults(ds.m_points, ds.getTotalPointSize()); return 0; } From 6ea7265d5ed0a647e9ae15440afc8486b8230dd4 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 15:07:17 +0200 Subject: [PATCH 02/23] =?UTF-8?q?=F0=9F=94=96=20Initial=20version=20works?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + CMakeLists.txt | 9 ++- dbscan.h | 199 ++++++++++++++++++++++++------------------------- main.cpp | 87 ++++++++++----------- 4 files changed, 150 insertions(+), 147 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5697ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +bin/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 696743b..10a0a8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,17 @@ cmake_minimum_required(VERSION 3.0.0) project(DBSCAN LANGUAGES C CXX VERSION 0.1.0) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) +set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE ON) + 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(DBSCAN DBSCAN.cpp) +add_library(DBSCAN INTERFACE) add_executable(example main.cpp) +target_link_libraries(example PRIVATE DBSCAN) \ No newline at end of file diff --git a/dbscan.h b/dbscan.h index 11106cc..0181ff1 100644 --- a/dbscan.h +++ b/dbscan.h @@ -13,105 +13,98 @@ using namespace std; -template -struct Point { - T x, y, z; // X, Y, Z position - int clusterID; // clustered ID -}; +typedef struct Point_ { + float x, y, z; // X, Y, Z position + int clusterID; // clustered ID +} Point; -template class DBSCAN { - public: - DBSCAN(const unsigned int& minPts, const float& eps, - const vector>& points); - ~DBSCAN() = default; - - int run(); - vector 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>& getPoints() { return m_points; } - - private: - unsigned int m_minPoints; - float m_epsilon; - unsigned int m_pointSize; - vector> m_points; + public: + DBSCAN(const unsigned int& minPts, const float& eps, + const vector& points); + ~DBSCAN() = default; + + int run(); + vector 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& getPoints() { return m_points; } + + private: + unsigned int m_minPoints; + float m_epsilon; + unsigned int m_pointSize; + vector m_points; }; -template -DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, - const vector>& points) +DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, + const vector& points) : m_minPoints(minPts), m_epsilon(eps) { - m_pointSize = points.size(); - m_points = points; + m_pointSize = points.size(); + m_points = points; } -template -int DBSCAN::run() { - int clusterID = 1; - vector>::iterator iter; - for (iter = m_points.begin(); iter != m_points.end(); ++iter) { - if (iter->clusterID == UNCLASSIFIED) { - if (expandCluster(*iter, clusterID) != FAILURE) { - clusterID += 1; - } - } +int DBSCAN::run() { + int clusterID = 1; + typename vector::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; + } + return 0; } -template -int DBSCAN::expandCluster(Point point, int clusterID) { - vector clusterSeeds = calculateCluster(point); - - if (clusterSeeds.size() < m_minPoints) { - point.clusterID = NOISE; - return FAILURE; - } else { - int index = 0, indexCorePoint = 0; - vector::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 && - m_points.at(*iterSeeds).z == point.z) { - indexCorePoint = index; - } - ++index; - } - clusterSeeds.erase(clusterSeeds.begin() + indexCorePoint); - - for (vector::size_type i = 0, n = clusterSeeds.size(); i < n; - ++i) { - vector clusterNeighors = - calculateCluster(m_points.at(clusterSeeds[i])); - - if (clusterNeighors.size() >= m_minPoints) { - vector::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; - } - } +int DBSCAN::expandCluster(Point point, int clusterID) { + vector clusterSeeds = calculateCluster(point); + + if (clusterSeeds.size() < m_minPoints) { + point.clusterID = NOISE; + return FAILURE; + } else { + int index = 0, indexCorePoint = 0; + vector::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 && + m_points.at(*iterSeeds).z == point.z) { + indexCorePoint = index; + } + ++index; + } + clusterSeeds.erase(clusterSeeds.begin() + indexCorePoint); + + for (vector::size_type i = 0, n = clusterSeeds.size(); i < n; ++i) { + vector clusterNeighors = + calculateCluster(m_points.at(clusterSeeds[i])); + + if (clusterNeighors.size() >= m_minPoints) { + vector::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; + } } + + return SUCCESS; + } } /** @@ -120,18 +113,18 @@ int DBSCAN::expandCluster(Point point, int clusterID) { * @param point * @return vector */ -template -vector DBSCAN::calculateCluster(Point point) { - int index = 0; - vector>::iterator iter; - vector clusterIndex; - for (iter = m_points.begin(); iter != m_points.end(); ++iter) { - if (calculateDistance(point, *iter) <= m_epsilon) { - clusterIndex.push_back(index); - } - index++; + +vector DBSCAN::calculateCluster(Point point) { + int index = 0; + typename vector::iterator iter; + vector clusterIndex; + for (iter = m_points.begin(); iter != m_points.end(); ++iter) { + if (calculateDistance(point, *iter) <= m_epsilon) { + clusterIndex.push_back(index); } - return clusterIndex; + index++; + } + return clusterIndex; } /** @@ -141,12 +134,12 @@ vector DBSCAN::calculateCluster(Point point) { * @param pointTarget * @return double */ -template -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)) + - ((pointCore.z - pointTarget.z) * (pointCore.z - pointTarget.z)); + +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)) + + ((pointCore.z - pointTarget.z) * (pointCore.z - pointTarget.z)); } #endif // DBSCAN_H diff --git a/main.cpp b/main.cpp index 12ee669..fb2e666 100644 --- a/main.cpp +++ b/main.cpp @@ -8,52 +8,53 @@ #define EPSILON (0.75 * 0.75) // distance for clustering, metre^2 void readBenchmarkData(vector &points) { - // load point cloud - FILE *stream; - stream = fopen("benchmark_hepta.dat", "ra"); - - unsigned int minpts, num_points, cluster, i = 0; - double epsilon; - fscanf(stream, "%u\n", &num_points); - - Point *p = (Point *)calloc(num_points, sizeof(Point)); - - while (i < num_points) { - fscanf(stream, "%f,%f,%f,%d\n", &(p[i].x), &(p[i].y), &(p[i].z), - &cluster); - p[i].clusterID = UNCLASSIFIED; - points.push_back(p[i]); - ++i; - } - - free(p); - fclose(stream); + // load point cloud + FILE *stream; + stream = fopen("benchmark_hepta.dat", "ra"); + + unsigned int minpts, num_points, cluster, i = 0; + double epsilon; + fscanf(stream, "%u\n", &num_points); + + Point *p = (Point *)calloc(num_points, sizeof(Point)); + + while (i < num_points) { + fscanf(stream, "%f,%f,%f,%d\n", &(p[i].x), &(p[i].y), &(p[i].z), &cluster); + p[i].clusterID = UNCLASSIFIED; + points.push_back(p[i]); + ++i; + } + + free(p); + fclose(stream); } -void printResults(vector &points, int num_points) { - int i = 0; - printf( - "Number of points: %u\n" - " x y z cluster_id\n" - "-----------------------------\n", - num_points); - while (i < num_points) { - printf("%5.2lf %5.2lf %5.2lf: %d\n", points[i].x, points[i].y, - points[i].z, points[i].clusterID); - ++i; - } +void printResults(const vector &points, int num_points) { + int i = 0; + printf( + "Number of points: %u\n" + " x y z cluster_id\n" + "-----------------------------\n", + num_points); + while (i < num_points) { + printf("%5.2lf %5.2lf %5.2lf: %d\n", points[i].x, points[i].y, points[i].z, + points[i].clusterID); + ++i; + } } int main() { - vector points; - // read point data - readBenchmarkData(points); - // constructor - DBSCAN ds(MINIMUM_POINTS, EPSILON, points); - // main loop - ds.run(); - // result of DBSCAN algorithm - printResults(ds.m_points, ds.getTotalPointSize()); - - return 0; + vector points; + // read point data + readBenchmarkData(points); + std::cout << "Done" << std::endl; + + // constructor + DBSCAN ds(MINIMUM_POINTS, EPSILON, points); + // main loop + ds.run(); + // result of DBSCAN algorithm + printResults(ds.getPoints(), ds.getTotalPointSize()); + + return 0; } From 4ce74a7ded62bd42086b2cdd051da42ea8d52eec Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 15:44:09 +0200 Subject: [PATCH 03/23] =?UTF-8?q?=F0=9F=90=9B=20Includes=20working=20examp?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/tasks.json | 28 +++ CMakeLists.txt | 12 +- benchmark_hepta.dat | 424 +++++++++++++++++------------------ dbscan.h => include/dbscan.h | 11 +- lib/libdbscan.a | 1 + main | Bin 0 -> 169312 bytes main.cpp | 21 +- 7 files changed, 270 insertions(+), 227 deletions(-) create mode 100644 .vscode/tasks.json rename dbscan.h => include/dbscan.h (88%) create mode 100644 lib/libdbscan.a create mode 100755 main diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..560fb8c --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++ compilar archivo activo", + "command": "/usr/bin/g++", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Tarea generada por el depurador." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 10a0a8d..f5c19a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.0.0) -project(DBSCAN LANGUAGES C CXX VERSION 0.1.0) +project(dbscan LANGUAGES C CXX VERSION 0.1.0) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) @@ -11,7 +11,13 @@ 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(DBSCAN INTERFACE) +add_library(${PROJECT_NAME} include/dbscan.h) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} LINKER_LANGUAGE CXX) +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + PRIVATE src) + add_executable(example main.cpp) -target_link_libraries(example PRIVATE DBSCAN) \ No newline at end of file +target_link_libraries(example PRIVATE dbscan) \ No newline at end of file diff --git a/benchmark_hepta.dat b/benchmark_hepta.dat index 2e1376e..4216260 100644 --- a/benchmark_hepta.dat +++ b/benchmark_hepta.dat @@ -1,213 +1,213 @@ 212 --0.063274,0.027734,0.022683,1 --0.000731,0.048211,0.069198,1 --0.060767,-0.00908,0.053085,1 -0.013252,-0.011876,0.055324,1 --0.054508,-0.003813,0.001738,1 -0.02418,0.068275,0.033462,1 --0.029308,0.059849,-0.06326,1 --0.016453,0.013881,-0.013236,1 --0.042361,-0.059942,-0.026487,1 --0.01631,-0.036612,0.047928,1 -0.03536,-0.04495,0.041474,1 --0.000287,-0.049496,-0.06343,1 --0.065931,-0.005381,-0.064899,1 -0.009049,0.027976,0.01198,1 --0.005335,0.062592,-0.057507,1 --0.004175,0.064646,0.040856,1 -0.091024,-0.031446,-0.014774,1 --0.077068,-0.035324,-0.03906,1 -0.05515,-0.007045,0.078495,1 --0.033779,0.049066,0.026958,1 -0.044954,-0.033716,0.011894,1 -0.008785,0.016895,-0.09079,1 --0.061655,-0.023085,0.007996,1 --0.051274,0.054634,0.032257,1 -0.04421,-0.062217,-0.018733,1 --0.003343,0.069586,0.069452,1 --0.064487,0.012217,0.040873,1 -0.042168,-0.009972,0.047962,1 --0.061495,0.059835,0.025843,1 -0.071795,-0.01526,-0.023346,1 -0.058733,-0.029135,-0.011721,1 -0.078178,-0.014786,-0.00032,1 -2.418463,0.490127,0.033581,2 -2.805184,0.769746,-0.557435,2 -2.983722,-0.983118,-0.165216,2 -3.055291,-0.477796,0.370524,2 -3.015527,-0.666039,0.126169,2 -2.449981,0.175666,-0.531892,2 -3.199806,0.201051,0.58676,2 -3.266405,0.012518,-0.761892,2 -3.74771,-0.41696,0.148884,2 -3.411849,0.516665,-0.702665,2 -3.733854,0.184758,0.482416,2 -3.59214,-0.371411,-0.673235,2 -3.59351,0.125884,0.277346,2 -2.387269,0.784515,-0.011033,2 -3.423791,-0.039296,0.066654,2 -2.425059,-0.206822,-0.263965,2 -2.407337,-0.015134,0.097093,2 -2.923991,-0.262388,-0.672982,2 -3.188203,-0.476377,0.051427,2 -2.377023,0.498033,-0.382225,2 -2.610067,0.787375,0.046041,2 -2.918826,-0.8296,-0.198249,2 -2.932853,0.719728,-0.347704,2 -3.47194,0.322667,0.25302,2 -3.266172,0.207763,0.078446,2 -2.916963,-0.636281,-0.459655,2 -3.020822,-0.491739,0.382338,2 -2.844004,-0.078753,-0.660588,2 -2.826876,-0.241459,-0.143806,2 -2.771511,0.362751,-0.669945,2 --2.69712,0.342837,0.296855,3 --2.57583,-0.752408,-0.225828,3 --3.308062,0.919403,-0.091698,3 --3.970394,-0.017968,0.097194,3 --3.332026,-0.22133,-0.410873,3 --2.679173,0.521163,0.033068,3 --2.186732,-0.536953,-0.08933,3 --3.013009,-0.082401,-0.750346,3 --3.464085,0.458797,-0.745681,3 --2.632916,0.683901,-0.153258,3 --3.315788,0.017903,0.703027,3 --2.833584,-0.684569,0.298511,3 --2.722148,-0.502344,0.245003,3 --2.608905,0.443179,0.447541,3 --2.853364,-0.788934,-0.276868,3 --2.809655,-0.092462,0.719525,3 --3.538035,0.777137,0.091226,3 --2.457811,-0.601538,0.548791,3 --2.762541,-0.540911,0.251193,3 --2.929594,-0.162338,0.427959,3 --3.054864,-0.220749,0.858853,3 --3.632051,-0.045369,0.497112,3 --3.595796,-0.25031,-0.26069,3 --2.285053,0.111547,0.652847,3 --2.664311,-0.035719,0.357768,3 --3.163578,0.286805,-0.843201,3 --2.599157,0.438496,0.094013,3 --3.381994,0.308228,-0.689706,3 --3.961031,-0.111044,0.022821,3 --2.827045,-0.074139,0.54136,3 -0.498135,2.895371,0.786843,4 -0.218436,3.067538,0.030236,4 -0.135451,2.12925,0.320246,4 -0.420118,3.055572,0.230617,4 -0.659865,3.446317,-0.101455,4 -0.619487,3.285343,0.278274,4 --0.294208,3.296888,-0.174357,4 --0.362217,2.657112,0.01996,4 --0.561919,3.334167,0.068536,4 -0.186843,3.706688,-0.259004,4 -0.450086,2.844335,0.073905,4 --0.047549,3.634562,0.613045,4 -0.432449,3.774495,0.096256,4 -0.444504,3.491508,-0.745843,4 --0.116409,2.618886,0.576378,4 --0.601582,3.548497,0.101766,4 -0.268449,3.662073,-0.103739,4 --0.007967,2.91813,0.390422,4 --0.811876,2.976918,-0.40471,4 --0.003684,2.460306,0.323449,4 -0.27221,2.287469,-0.243128,4 --0.003839,3.107724,-0.876719,4 -0.175357,3.715249,0.344842,4 --0.350178,2.515348,0.695052,4 -0.016665,2.986915,-0.265349,4 -0.394178,2.772903,0.583035,4 -0.715985,3.467443,-0.171137,4 -0.28994,2.60696,0.767379,4 -0.854454,2.895231,-0.335877,4 -0.308424,3.293211,-0.383773,4 --0.154151,-2.382802,-0.552876,5 -0.042376,-3.013402,0.26318,5 -0.76406,-2.974825,0.304909,5 -0.273431,-3.549045,0.602433,5 -0.109072,-2.872739,-0.972276,5 --0.609027,-2.316553,0.05604,5 -0.563714,-2.668933,0.272222,5 -0.053112,-3.69483,-0.446254,5 -0.374246,-3.881493,-0.178669,5 --0.25541,-2.573785,-0.369218,5 --0.05833,-3.539877,0.156878,5 -0.436804,-2.849058,-0.705822,5 --0.185927,-2.83419,-0.871306,5 --0.15729,-3.035242,-0.447355,5 --0.253287,-2.355499,0.53801,5 -0.856338,-2.928918,-0.105247,5 --0.448767,-2.892567,0.036684,5 --0.763126,-3.121529,0.012815,5 -0.50729,-3.69845,-0.126832,5 --0.262387,-2.7936,0.893868,5 -0.638189,-2.885896,-0.535134,5 --0.715655,-3.174318,-0.415442,5 --0.148243,-2.348742,-0.198939,5 --0.436461,-3.189614,-0.874082,5 --0.015747,-3.601469,0.678772,5 --0.380327,-2.120669,-0.201018,5 --0.078679,-2.969195,-0.085163,5 -0.725907,-2.642703,-0.392598,5 --0.118512,-2.391662,-0.116857,5 -0.378156,-3.742474,0.42604,5 --0.646687,-0.257803,2.879026,6 -0.862612,-0.257097,3.339622,6 -0.58395,0.25262,3.164447,6 --0.106313,0.539686,3.36243,6 --0.447773,-0.165269,2.395462,6 -0.278688,-0.67851,3.019065,6 --0.499959,-0.102398,2.918835,6 -0.628733,-0.136098,2.961669,6 --0.550777,0.820583,2.888145,6 -0.280057,-0.332023,2.280202,6 --0.68149,-0.388565,2.852309,6 --0.150402,0.774676,3.236697,6 --0.175775,0.816718,2.810907,6 -0.40849,-0.752991,2.708342,6 --0.687687,0.5331,2.864252,6 -0.187892,0.099277,3.3971,6 -0.40274,0.309218,2.184721,6 --0.333692,0.726125,2.755337,6 --0.073884,0.856673,3.449364,6 -0.074276,-0.44986,2.289555,6 --0.234023,0.508787,2.627695,6 -0.33853,-0.722352,2.402052,6 -0.777033,0.217745,2.671151,6 -0.093523,0.595698,3.532532,6 -0.215945,-0.323846,2.195408,6 --0.031152,0.385966,3.106696,6 -0.26075,0.391448,2.176698,6 --0.542543,0.386463,2.917456,6 --0.306005,-0.915958,2.884296,6 --0.114414,0.026251,3.899389,6 --0.749873,0.616942,-2.862605,7 --0.108157,-0.083104,-3.909294,7 --0.410898,0.467216,-3.64399,7 -0.662499,-0.378195,-2.900845,7 --0.057589,0.548771,-3.072026,7 -0.64518,-0.276585,-2.877792,7 -0.257191,0.114881,-2.929682,7 --0.169119,0.400328,-2.853299,7 -0.228327,-0.513736,-3.600658,7 --0.512238,0.372109,-3.357134,7 --0.510091,-0.617806,-3.543896,7 --0.001328,0.275274,-2.367165,7 --0.086874,0.138084,-3.152736,7 --0.558094,-0.138533,-2.731829,7 -0.640575,-0.52869,-2.882579,7 -0.033866,0.301424,-2.949164,7 --0.530334,0.571733,-3.122279,7 -0.488731,0.68226,-3.026392,7 --0.320178,-0.530404,-2.430535,7 -0.143306,0.578726,-3.657507,7 --0.36578,-0.491918,-2.483666,7 -0.660425,-0.259537,-3.671958,7 -0.647696,0.44422,-2.807808,7 --0.110876,0.163359,-3.038903,7 --0.694187,0.258777,-2.411717,7 -0.175738,-0.053478,-2.733752,7 -0.396046,-0.858377,-3.126866,7 --0.406362,-0.334541,-2.885598,7 --0.299275,0.071281,-3.642585,7 --0.506192,0.433538,-2.608597,7 +-0.063274 0.027734 0.022683 1 +-0.000731 0.048211 0.069198 1 +-0.060767 -0.00908 0.053085 1 +0.013252 -0.011876 0.055324 1 +-0.054508 -0.003813 0.001738 1 +0.02418 0.068275 0.033462 1 +-0.029308 0.059849 -0.06326 1 +-0.016453 0.013881 -0.013236 1 +-0.042361 -0.059942 -0.026487 1 +-0.01631 -0.036612 0.047928 1 +0.03536 -0.04495 0.041474 1 +-0.000287 -0.049496 -0.06343 1 +-0.065931 -0.005381 -0.064899 1 +0.009049 0.027976 0.01198 1 +-0.005335 0.062592 -0.057507 1 +-0.004175 0.064646 0.040856 1 +0.091024 -0.031446 -0.014774 1 +-0.077068 -0.035324 -0.03906 1 +0.05515 -0.007045 0.078495 1 +-0.033779 0.049066 0.026958 1 +0.044954 -0.033716 0.011894 1 +0.008785 0.016895 -0.09079 1 +-0.061655 -0.023085 0.007996 1 +-0.051274 0.054634 0.032257 1 +0.04421 -0.062217 -0.018733 1 +-0.003343 0.069586 0.069452 1 +-0.064487 0.012217 0.040873 1 +0.042168 -0.009972 0.047962 1 +-0.061495 0.059835 0.025843 1 +0.071795 -0.01526 -0.023346 1 +0.058733 -0.029135 -0.011721 1 +0.078178 -0.014786 -0.00032 1 +2.418463 0.490127 0.033581 2 +2.805184 0.769746 -0.557435 2 +2.983722 -0.983118 -0.165216 2 +3.055291 -0.477796 0.370524 2 +3.015527 -0.666039 0.126169 2 +2.449981 0.175666 -0.531892 2 +3.199806 0.201051 0.58676 2 +3.266405 0.012518 -0.761892 2 +3.74771 -0.41696 0.148884 2 +3.411849 0.516665 -0.702665 2 +3.733854 0.184758 0.482416 2 +3.59214 -0.371411 -0.673235 2 +3.59351 0.125884 0.277346 2 +2.387269 0.784515 -0.011033 2 +3.423791 -0.039296 0.066654 2 +2.425059 -0.206822 -0.263965 2 +2.407337 -0.015134 0.097093 2 +2.923991 -0.262388 -0.672982 2 +3.188203 -0.476377 0.051427 2 +2.377023 0.498033 -0.382225 2 +2.610067 0.787375 0.046041 2 +2.918826 -0.8296 -0.198249 2 +2.932853 0.719728 -0.347704 2 +3.47194 0.322667 0.25302 2 +3.266172 0.207763 0.078446 2 +2.916963 -0.636281 -0.459655 2 +3.020822 -0.491739 0.382338 2 +2.844004 -0.078753 -0.660588 2 +2.826876 -0.241459 -0.143806 2 +2.771511 0.362751 -0.669945 2 +-2.69712 0.342837 0.296855 3 +-2.57583 -0.752408 -0.225828 3 +-3.308062 0.919403 -0.091698 3 +-3.970394 -0.017968 0.097194 3 +-3.332026 -0.22133 -0.410873 3 +-2.679173 0.521163 0.033068 3 +-2.186732 -0.536953 -0.08933 3 +-3.013009 -0.082401 -0.750346 3 +-3.464085 0.458797 -0.745681 3 +-2.632916 0.683901 -0.153258 3 +-3.315788 0.017903 0.703027 3 +-2.833584 -0.684569 0.298511 3 +-2.722148 -0.502344 0.245003 3 +-2.608905 0.443179 0.447541 3 +-2.853364 -0.788934 -0.276868 3 +-2.809655 -0.092462 0.719525 3 +-3.538035 0.777137 0.091226 3 +-2.457811 -0.601538 0.548791 3 +-2.762541 -0.540911 0.251193 3 +-2.929594 -0.162338 0.427959 3 +-3.054864 -0.220749 0.858853 3 +-3.632051 -0.045369 0.497112 3 +-3.595796 -0.25031 -0.26069 3 +-2.285053 0.111547 0.652847 3 +-2.664311 -0.035719 0.357768 3 +-3.163578 0.286805 -0.843201 3 +-2.599157 0.438496 0.094013 3 +-3.381994 0.308228 -0.689706 3 +-3.961031 -0.111044 0.022821 3 +-2.827045 -0.074139 0.54136 3 +0.498135 2.895371 0.786843 4 +0.218436 3.067538 0.030236 4 +0.135451 2.12925 0.320246 4 +0.420118 3.055572 0.230617 4 +0.659865 3.446317 -0.101455 4 +0.619487 3.285343 0.278274 4 +-0.294208 3.296888 -0.174357 4 +-0.362217 2.657112 0.01996 4 +-0.561919 3.334167 0.068536 4 +0.186843 3.706688 -0.259004 4 +0.450086 2.844335 0.073905 4 +-0.047549 3.634562 0.613045 4 +0.432449 3.774495 0.096256 4 +0.444504 3.491508 -0.745843 4 +-0.116409 2.618886 0.576378 4 +-0.601582 3.548497 0.101766 4 +0.268449 3.662073 -0.103739 4 +-0.007967 2.91813 0.390422 4 +-0.811876 2.976918 -0.40471 4 +-0.003684 2.460306 0.323449 4 +0.27221 2.287469 -0.243128 4 +-0.003839 3.107724 -0.876719 4 +0.175357 3.715249 0.344842 4 +-0.350178 2.515348 0.695052 4 +0.016665 2.986915 -0.265349 4 +0.394178 2.772903 0.583035 4 +0.715985 3.467443 -0.171137 4 +0.28994 2.60696 0.767379 4 +0.854454 2.895231 -0.335877 4 +0.308424 3.293211 -0.383773 4 +-0.154151 -2.382802 -0.552876 5 +0.042376 -3.013402 0.26318 5 +0.76406 -2.974825 0.304909 5 +0.273431 -3.549045 0.602433 5 +0.109072 -2.872739 -0.972276 5 +-0.609027 -2.316553 0.05604 5 +0.563714 -2.668933 0.272222 5 +0.053112 -3.69483 -0.446254 5 +0.374246 -3.881493 -0.178669 5 +-0.25541 -2.573785 -0.369218 5 +-0.05833 -3.539877 0.156878 5 +0.436804 -2.849058 -0.705822 5 +-0.185927 -2.83419 -0.871306 5 +-0.15729 -3.035242 -0.447355 5 +-0.253287 -2.355499 0.53801 5 +0.856338 -2.928918 -0.105247 5 +-0.448767 -2.892567 0.036684 5 +-0.763126 -3.121529 0.012815 5 +0.50729 -3.69845 -0.126832 5 +-0.262387 -2.7936 0.893868 5 +0.638189 -2.885896 -0.535134 5 +-0.715655 -3.174318 -0.415442 5 +-0.148243 -2.348742 -0.198939 5 +-0.436461 -3.189614 -0.874082 5 +-0.015747 -3.601469 0.678772 5 +-0.380327 -2.120669 -0.201018 5 +-0.078679 -2.969195 -0.085163 5 +0.725907 -2.642703 -0.392598 5 +-0.118512 -2.391662 -0.116857 5 +0.378156 -3.742474 0.42604 5 +-0.646687 -0.257803 2.879026 6 +0.862612 -0.257097 3.339622 6 +0.58395 0.25262 3.164447 6 +-0.106313 0.539686 3.36243 6 +-0.447773 -0.165269 2.395462 6 +0.278688 -0.67851 3.019065 6 +-0.499959 -0.102398 2.918835 6 +0.628733 -0.136098 2.961669 6 +-0.550777 0.820583 2.888145 6 +0.280057 -0.332023 2.280202 6 +-0.68149 -0.388565 2.852309 6 +-0.150402 0.774676 3.236697 6 +-0.175775 0.816718 2.810907 6 +0.40849 -0.752991 2.708342 6 +-0.687687 0.5331 2.864252 6 +0.187892 0.099277 3.3971 6 +0.40274 0.309218 2.184721 6 +-0.333692 0.726125 2.755337 6 +-0.073884 0.856673 3.449364 6 +0.074276 -0.44986 2.289555 6 +-0.234023 0.508787 2.627695 6 +0.33853 -0.722352 2.402052 6 +0.777033 0.217745 2.671151 6 +0.093523 0.595698 3.532532 6 +0.215945 -0.323846 2.195408 6 +-0.031152 0.385966 3.106696 6 +0.26075 0.391448 2.176698 6 +-0.542543 0.386463 2.917456 6 +-0.306005 -0.915958 2.884296 6 +-0.114414 0.026251 3.899389 6 +-0.749873 0.616942 -2.862605 7 +-0.108157 -0.083104 -3.909294 7 +-0.410898 0.467216 -3.64399 7 +0.662499 -0.378195 -2.900845 7 +-0.057589 0.548771 -3.072026 7 +0.64518 -0.276585 -2.877792 7 +0.257191 0.114881 -2.929682 7 +-0.169119 0.400328 -2.853299 7 +0.228327 -0.513736 -3.600658 7 +-0.512238 0.372109 -3.357134 7 +-0.510091 -0.617806 -3.543896 7 +-0.001328 0.275274 -2.367165 7 +-0.086874 0.138084 -3.152736 7 +-0.558094 -0.138533 -2.731829 7 +0.640575 -0.52869 -2.882579 7 +0.033866 0.301424 -2.949164 7 +-0.530334 0.571733 -3.122279 7 +0.488731 0.68226 -3.026392 7 +-0.320178 -0.530404 -2.430535 7 +0.143306 0.578726 -3.657507 7 +-0.36578 -0.491918 -2.483666 7 +0.660425 -0.259537 -3.671958 7 +0.647696 0.44422 -2.807808 7 +-0.110876 0.163359 -3.038903 7 +-0.694187 0.258777 -2.411717 7 +0.175738 -0.053478 -2.733752 7 +0.396046 -0.858377 -3.126866 7 +-0.406362 -0.334541 -2.885598 7 +-0.299275 0.071281 -3.642585 7 +-0.506192 0.433538 -2.608597 7 diff --git a/dbscan.h b/include/dbscan.h similarity index 88% rename from dbscan.h rename to include/dbscan.h index 0181ff1..0834f74 100644 --- a/dbscan.h +++ b/include/dbscan.h @@ -1,7 +1,7 @@ #ifndef DBSCAN_H #define DBSCAN_H -#include +#include #include #define UNCLASSIFIED -1 @@ -16,8 +16,17 @@ using namespace std; typedef struct Point_ { float x, y, z; // X, Y, Z position int clusterID; // clustered ID + Point_(const float& _x, const float& _y, const float& _z, const int& _c) + : x(_x), y(_y), z(_z), clusterID(_c) {} + + friend ostream& operator<<(std::ostream& os, const Point_& p) { + return os << "(" << p.x << ", " << p.y << ", " << p.z << ") - " + << p.clusterID; + } } Point; +using coords = std::pair; + class DBSCAN { public: DBSCAN(const unsigned int& minPts, const float& eps, diff --git a/lib/libdbscan.a b/lib/libdbscan.a new file mode 100644 index 0000000..8b277f0 --- /dev/null +++ b/lib/libdbscan.a @@ -0,0 +1 @@ +! diff --git a/main b/main new file mode 100755 index 0000000000000000000000000000000000000000..27b67cd25ecb5227558d0706d31fa0379f84f8c1 GIT binary patch literal 169312 zcmeFa34ByV_CI=WcbePj8?vw)wq_3?kg$e5EP)0BLRXyI#qT1rnxRXW0*_VHT80712p0`#-(wQ_|!E2Iv4Zwk*1|;(fDkmwbp8ZkK!^y z2ulm0RZ_L0UPd*|4NCP=U7{e>mBtr}HW9^|qRK*|9*GH(COJX#iUg}DEaw8MN46eb z!7S)>zECuc48m(88O1L@f0B7r@1(4EQr1&6UfQpy>L010cb3GnTxsBlPa`6&vZ-n| z^Yh|abe%MY#X!^eLeUsQlq;(0U50vO=O2B=OTlrny-0qs$468kKhmp9{@j^8yLZW- z)hT~&!Qy3|mZkRW)U$i%q6MA1a=%GG$qpYgfy8;dr7M_Ez^5PYrg&e1cSF4E;N1*w z!W!Y7hw!(j49 z&DVGoge&hKp*%N&p1((s-wcbx>7NjxydXk3jZru~fe7WdL?}NR!TuK_w0kZ>d1(aw zLnFvfiy)sE!JecD<*o?jA4Vvj5TX3e2=?rXApd0q`OhQBQ!M-OuK9W#1vHMCv1uXD zDCkMR%uTy~I+u$`*R)mApJ{UaP?au~<*RCxYse!-#j|occBI_VQ_IetGk-xrc2V(+ z!s6^~E&Gb`#a)xLvy1Zz7c9-r&n=i!oR^(jSh%1tb5st{G2`bJ7Nw7yZC}o{FXz$a zsPV`AIe9Y*vx^I7%q>PidV0>1ndwU)Ix9bO$$YN8AipSG zsH7{Qk*)|GU)(*nU{-!uP2-@wn`mr7QE_4JjQJz7va^!2)5rIuu8aZPUD`5R;^7P$ zl9G0`!|d6~n;jbAW6JDsge z>7~3jbH=Rf8Tt7Oa?r`_oMkhzXXehCTacYIqc|sz{Jm^h_QKr4q6Gyr^5+&`oxLRa zzc5v{KfXA>Xhay-hH*$v7TnPzTMS>pQsMC8&|bj-%GSbM9(wLl*Y2uI3l~b))AKTMMUCiPEJmC5pgM6_Jo3^ zbD?-#ZqefTxg?efKn4vSk)6`HTj$;m##u{TXLs$~wQ~=eYc8xr_P;23 zElNG$YGG9~KwY42tY~yatCyR3TEBGdUKFW(klFTXEU{kgXA;9p$7+bF%=mQBg;iUD z7+STgvxxaxS}Yb+(sA`0kE6avYbyD-9={69X_VGM^2P0M#j@(wde8!l7qx#t>LPw| z;#@5ME^Uy+E3cbQ#k|JS{y@E|9ObkxP%o9AXbq<|SiKspn$DNB2cZ6_m)}t?yUb9M zqgY1t#~tOgcU7;Gj&j<= zs#nlaPWxT;s&tgoo=LsFk8Ad8pyaGKQ0BR;(60s7loz|Ij|NI!@E%ekOsjhg23*}{ zC_dwwr{RkDJi<<&tj4QNAL1#*PakEzEAbTCr^}h|K)jpyUCg&6oOnRgLSp?Z2c^S>?vPoa1^llkw6rw}}y#{8GWQ|O&eX8u#+ zDdbN3nLj~1h1%(O=HDcqLhQ80{42y$Xq~S79R+QkCqAC|lg#fUoJmcRaMCZ&~ugI^B}9ISE&^p^r}{9c@3X)vUQn)O%pkH&awiyKY|lztvui2-=Y z^D}y+PZg3i<wUXf1c2>3cZ$S#C6s&O5m6evYIjetXj*wNfRTj@O4rkr z3zXg+04d#^Ma=s2je)W!xx8#Ml?Te!%X*dtxkv{r2y0eQU&}U=NLiiIHv_$o#@$MW z)vH*Ofieo|XU^l}^cm!oiuAMOKjp@X^tHq)RTD{7Y5H2l=L>!p+=w^Ig&S9*cy)Q) z>P8rnK-n5EFK!BvM;o9ZCTk%mC659Ifg15dnpFb zczAH(;aX+sXAyWM>1Qbb;GK%#Unv0g!{-$EImc1Fk&4eF9m27P!5qs%uvgUNsBK0?73n9@wlz{~g~HBr+rye_I}4@TL9lMWq$ z&_1@O#@DZ>^?_rYW-3>eVU9?DJxCkT!1^^T1cU2Slc8~T8{#Z(^=ardSylMG z=4i&PzMcH*@Sv?Eh@9nU^$f9&w2@-byu6_FUKpDL!>Bm9No5}Rz3%gRR}JJ@38Gyzn+a$Z;)PR^MyQq`0Ek|UOoK2-YOX=cca`c~DjEE2>?C09gm!%&QPMHc7 zmPtp+zO|O@EyOB^?E!=Jrf>SOxb;uc(4?OYhI@Z5LR)wDvM9*CjFBvLy&+Hp<}tQVWchtJVQJKoc(8`+wW9)#mC8xZu^ zg>q6@d=|3X$^WCt>GJwL$8~!w8kFLMR43wiq0K{lsD#K0ZsJ%H4JX4!B*%^-5i)!g zV3iqpLc~Bu4)}rZX~0z%(1ZBW73WG9SCy1-?|V$=^<1>waHdBaxFD8*;}KU4LGVD#GIiivQo?w<#(qi<&kI$ z0wYq-yW_NuW;rts#dRdPiIK1}K9XUqy@ArBf%b=S!i=JIgmj{eRr68D?`Y{PGHj%l zI+L7Iz$YdsLJ2Er?ohHw1OlJ!RJ4`xK{3=C5q`YWmX|bBq`wAD95i827G)4W0uU=Z z_9e8P=$n2xZuLpb-{1i>LyOo^nqK?ClvL{23}BN8F~spxh%3ihzkpdz7Z2kSk~R1G zvrrQaVTVtmycL*$7#JCkT@Yy3K>KfLFLdx%`0*W4<_na5Cq3{U_61z20`{oOG}u^FK{vdKyHY|OR&u_l0FCe<*06&o zqXN2Ut28tIG(7;J>^Mp*JN0V|`c*tv6+Z)IBT8RTteXuL=)|6Lua0sQ zFBqQ$OETj4#IT4pKIeJD{fF_PFh>7q9!4G?H5$A(!A&);!twPWw-Hiw3Psikh~B6e z;&48Rh^p=XoJQp^9U8PsG>f+zPycO&O++9GXn;nU=!i6~W__e@YKxlFLEh zxWpHN;UgPPxZkn-?!mQVas;tf%8}xGTQX9^`tm_i(>whrFE7Qu1CL{iAAIZ!SR>s? zPli|majScX6wV&5O?MP94#5&$my3sRoibVl*tzpbcPYFtRej9K9G!&w%NEiE1Vv`0 zEpSD!5YlIIMIqdTl3TgH7*NW`6~R?pf&o;)z)RfCHQHIq?TBHPH+tNu7wZR0Jnc zF~*Pjj$3HuNccR*f|Eb3vGcijzL7DHu(ad-{D0odRE6$kPBV*HeLT<}DYMFTVO%0) zRl2VTK2A3`dF@X>`W#X@0<Z!gL^10k&jH$hR0Qd;!hT26w4-t#*Q z3@==|)uu2Hd1D7Wu^owc8x-u==NprzSuU8*+OaGF;l+-U3SH7t%BMe6t_Y5#TWh8G zUTQsm83kqRDcnYagep*6oH zR&F9_S0HMNV?}!K%mP&{CA8W;u2!?b&EXpS`L_^LSA}ixN?9}54ZRk3C0eScpJD~@ z)@Vct1rodGF)9`A#wd-84|K$SlU%;r}AYMF}|!>T2Un?X1j_Yr$2 zIGic0uL$PTrE^MPhReHDLogoWBavf7Wtyx`2m zfr0NiI7ML^g|7B3g<`qdfAc<%1txgNYCjTngC!q`v3Q0lkHty4w8tW3bt4-aaZjwH z90wPACXO`y(4UhuqDSc)zfy`aV0^+sAaZEDAifKvD%kt*Zi-{{45pW;yNT=4Mjk*# zaMU+sBjpOP>L$xxx?e2Jv{pa0C9S!9vUft#XsTo3RUyL57e<{&j{|*(b9GhccB|vC zz9a4H>82?HresBxR@_zD+=>&Yv-|K0cfTPa>=nwJnO>F6TIM=hEQ+bAOZ z%3{>uTUE5)*4U!^NJeeZpF2Zet`%Eb^pvm34C|}+Pb zP9uTd;zKv5N8B2qWW_eNDXj_5+vo`2GP#i3vc5n;m0j3zc zir}ks$%#N^Fn>roqPVw=uaxusr#JWx0Z$Z~HrQd==_A>hnr4!(I% z5nM`J#IgwBYzjpOSi{r{_DQK1Hp81iN)-6c$(k9J;+_NF$F*-_B-yoVbn-u>iVN&$ zdVwYkSf#a-3h@{a3=ADq;Q7AkCyP7aitUXe*OXFNAg=gnYx=VsG2=?otK!cbAxY_0 z+v3RMY99pEz&1S^I#$j;b+VqC4wB}wf!ddW>nl&&N zG5&TGwI+M*aS5yTf`Dm+N;T$(?0y#;k&dE12DsaZnTXx4F;zrFog?Sdok4o0px6`K z@GqKQP{%XABKSLaVMe&UyZ9Rd3}i*{-?$m#h=F&(I%423v)F~uy|sfP8iJds?F$Cp z3OJlclm9>>IbgXz;tsYse>+8oiIcR2rSCX`3r>)MSP9*Mvhm(PsU9f3%)8N%2P5ui zuj4Z-Y2%L9p?fPA+0o`7VUG$Y(fQln(Z0*<1v}afd<(4Rj`m>^4%yNEM7c0zM|%n- ze`rVB{4^QWNO+_o7|$%`h1}6%U2|@Tlbplg+-v?OHwJQRbe7pLd(HW@!dogau#PDh zaxDKFju&$K7S8{Nd0Qj)|0;c4gDME!-r_WfuS38)BJT}eVEH@W{e;NJj91Y$?NrX} zf)g-fslOsm{L7?M%RO+NU3dp!$N(Zb6aWA*MVsPYYd?#CIr=tI4V2o{G$S{j^bHRekPhr@p z@}ZAaxc@oFFIqhPS8};TJeL(L(|VUO0)np4jUvah0|G=VJyO z!pDs9>^=vIP|%OcVEYeK?}EH`3SZ!bkJAq5n?tF(DbZZ+oohA}+9&x(jdAst)(A`LbqE%<-Zv(?U?QA(@gJA$Pgca=1H3;C2!r#P|Y7w%m~+YHJ> zkcgqYRx0=X9H@J+rI8EeMV8a?Xd7QasntpPiuQ>A@u|ItvG%5O&6ly(5~sn7#@fY4 z$&NgGgo-aVLdOq97@^P{Dl;AZ<%ozNnmkF)tO*D61e(da1S?sOXO{98f?egW=~Nh! zuNqmZWRl-usbQ`B2WOb@o67Ba)@aG~^)FndBDfJ$7#VJ(Ez_(IJ#j2Czj3m&tUe3Y zK4@j|rq_9sye~Bsy4u(gp`LSbmT;N~9XjH~0UC!_{>x_id+0%vMwGrgXyS;{pYYsv z>G?rf8SC48knGnc1lD&t1v);XJ^iJxH@LMN19$MeySRDE`*F=z!5|zBf6XZUX=v#; zgR1L&5GXmM2YP?F_)FO7y>hB}`gKtDp^f(6PxIejqaIPxNs@=a>-@VKxR{w+kdrrm zM&VW2dASRVXLO!5qgWfWc>c`XLjQu<{>%mV)sUh-er;KFboAADFUMPJ)1!0O{Mr5x z(#PKhPYEr_%_&|`*r!inZc%O_ep$pS$Q~_!4J9WpH|MH8{_N}mf6~&txjA|Mxkdgq z%NMuz59seN&YN4*X+Y83<+(}iYrr9za{2dSvga0{m11-vexTmi-IsoI>?F8t2db+x zah-Rtx|*Jj+y>eYbma5Z)yr@*@Kez3pbubPoCKXsdl-DfbF=u= z9Eblw`-9Stn`MCdK_`QzfqwcP`VCs|1a7c`b_cy5G!yg%(3PO4KyLz#iqo`m(AJ=@ zfer<&0-Xg~3t#)L22BLLA9Nt-3!t+>Pl4V98iix-F3{GXCqRdSF2or!AC$fl-U#|R z=q}LY58*e^nV>&_t^%!xzbM`S+8y*R&@9lGK#M`&1lI1MLp_1L$hd zdiceM`$4;dz6_cL>c#fH81w+>Hqa{2y`aWP#2IKE&??Y3@%)h=zYy^?Xc}k}Jk&NF zbO7io&_$rzLGJ@C2R#gW5_B4#X7l2gB=SL%Kx^T9stnKs(0tH=pzAEY6Z9w0qoB3Eh2KGwK;s*0+IY}p&=sJWppSzt1U&}25!CY?;uW+x=uyy- zpp~HOK;!YFJl}wJ2R#p(1=<;Zp;rugE$BATp+CUype3LmfW8AtKT>oK)DK$xBm4$> z1L!PJ`uoq-px=Pr58C7>_#LzZ=qXToj4TR2QnL}XH7I=tG8FVT&{?1Zenx%J4AA>Q zH-NqX`Wuiuzha*G zHLWgachD)IS)fmY7K2uRZUX%QbPs6kZ>SI267&bqWYBsoH0?If?x1u?$pU>1v>3Dv zb`+aH$AInuEdV_RdL8HwpmbZWUQ759v^!|e^QaG+30e$#C+IfNw?OxT{s?*;lzyk> z9B3hE6RbZap#4B^0i6Q61GF5pQ8oP2TH_a{C%^RN<1~F)yxus*@NU$_Z(d<2wbXsp z)m=zps1c78rX}N@g)-b8ml{zli3+O;eAui{bl0ZIB&UlJTODoD7(6ZHsPB#3*w;Z%JExwRHl7Ong$Ta!qfR{RC{^mTr0>}eV%6H<-ltL$F|JIhuQc^;8kcN98SK+PuQ`)8bHp{ zKWc+}ebhQnNiBCRH&l^7k|6iyVf-u=)lqYIy4_9y_;KLvo%k#pr(fdw1bAO34xcZQ z`qu)ddxCx^ex+T1hr}bz{lmb&M*VO&=_Eg%1U?kkQBQ^Ubqpo7m&4C1(s2qp$VML1 zeGVOROvz7~(9sq;TH)IAlViLV0`CAkk{>q$PX->zkGp{P1|G?eM}cPn_dDBn__0#r z;rvAQ$Kz|TVW^+#tY2i0Lo)Dbzy~_< z2l7!B@Rh)OIO{L8>(hC36L1`xZ2LyoIGs~(0N%lg=i2yW;Oj0@e;M%Qz;V2=^^dXZ zZv$Qcyp0ogvw%k$?80FPw< zVW~fo{XyWVs6W=(f0vl_WS_pu`XPA{Vwdj zbw4HcS>%g)F*rNF9)2ApygTp*fJe$bS-|%IZwXl|=BL{ICQ9D^q<=cDqx_D(xI}PL8!te|*N}-67pH)K z1U%B*iNd6LA9$qP(Hc12I|Q-)AlCvviiQF>0eqelAHL3A66NBZ57|h+#pQn^d_M_a z3%o7xNNwx@P!IUU+BgE4DvqWtG4m0DiazE{~Ud z4zCxFT>WPFTt;nl2R;vYr1_f#d@T)K<~hhjnpb;)KLmWR zQ^yK>ULFTdk6?Ci;*R}E74Wx#hqICT*eC(_*MYZp)_3etQ-OaAJW{Mp2JXUl#o=Os z^e+QmiTdGkJ>{@W*ylt2{gkU)7lq_7_Y-!mE{C4&Z%4M{B=CO#$FSQm>DcSie~NIi z`hMV4KT^!60jK-^k?`rj9|7LU*?yiqPOE_L1wO!uUv1;tfxiPhlKthtUj!b>&nJOD zagp{lY(UF_L(KM%ScVKMuUBv%X_3TLt_};Nk4| zqt13&|6+OX1;{jeC$bHvfX4!lv>r#{CSW}9j!qkA+hfogcw^v^=F(8$ZGcDW<1FC4 zfQMVJ$%m_f_XD2dY~OKKx*zyx;JBr2kCC`7$oc98;KPAOvi}tDalpgn3O`gv)kjVO zp5xRn)~`wA1+p;-GEYDz+&B>)0DcefaDDItr(fRQ4SY1NL-rCwgr7-f9b`U$%*Ar^ zF37BUH+*g;9Y=xx4fuFmhqU9!tv^8KHOPcpV@O9md}neD_|lp>9C1tE!z3M#><{{W zhQ7CpH1Fwqo7TWX_REg@2-|=Uxk&xJz%wt>{&C;~fRCur2fDRJ<5dNG4)92Ms}a8c znRSu&Q-Lo69w~2427WW}a4|>iF9W_Cc%*pR27G&j`hL{k3;cQD7mL{sAme&3@)~vy zxCuO5%#w{w@EukY;F0ECKj003V|v-KHr9^kDZqWe7ddg-@5~W0w9ci%hDngwiR-A0 zqO_2hy;sPQEjys=1IR_nvxkAd3Ov$%u^{k&1NTFh)rRAI=f(GJgeN$0$9D@!z~2QP zDV_qrwG;R~N@snSIAD|g^vn7EfkztewZJ<9k2GI)08a%TX)F!{?+QHJSWx>x;B7C` zz88w=`}2@^65Dr?|A0@rNc{ltbl{Qfr~fHn9PmjY{u##uO!ln>UJ5+PiRU=RANZ}n z{Z8C5eupIkM z{~6&J@QdyJ*Fokt$fP=TV7}1NnA+G0yzcwq*Kum&2=MyAFSb{p?{%j@CX%1%``$4Z z!IOd0a}kmJlnJ~O@JRcqg}{G%D16?eK5PVj$;0?g3D?#<%@lD!MMLr41DTWXQ!W(@ zi;ch8l^)w@gF8LezdkBGHffzF5Sx5stw3yQi7`AjtspjaP;By`*rdU+{=u=02FJz^ zj`i~Y>2nTxys*_ndgQCRT92OZDc08OCG{$%a8H!} z4(TcJw7B1+?Y=-yTt`olzCrigrfc`umasX0e*EcyKRxiL2mbWHpC0(r1AltpPY?X* zf&be)urNN2b$#Ag&@{=5ov_*w+m!xBi(U$+|MSzy)BnLqFMN&0uWhx{nAR4o78osf z9FO^>{vUN5llX<(@ciO)9j=bAn9e+o4*c>;8YSs6R~lda_1uOJl0a zcS&CLBOt`IXh~K3cyyHe6EEfQ2r2W*j!MbD7A^G4>i=s*{Xh0K8+@m>u;<^B{v>Iw zSW(_U(zcTJlysP+6D6H3=@LnAlyr-v4@mlyq%TSOj->yV^e0Jc#mV+1Z7XR{Nry=~ zQPSCxE|K&`No)2O{~>Q5e-i$;`u6@*{CB%4{;tU>y;D-UrudV_<<9a4W)zF^PCeSw zf8MKPQ<6KUbWVmcibIZhOsL_5TI=2NdUs7h*+$u(q8G^J{6V>*KPZ>`2j%`hW*^O? z5dY0cv3z$x`Y@b~!W6y0zYB#w6s~AwPSQH0qrS>pvYfL`T!`L|_&?8cuFB5IpHY;D`&A)Whn(5j z3kw$%2Kq=oVv&vhD{^5T` z&!0P|fQloHRk;BF{%_}i2yqqChl|D4|Fr%E zIq3ff>!ONZMZ?VrHD8{%$h=YWWrCa!8E_^$o)#Fq3gsDMt=v@qD$f>_-{}?8B#kNV zu=8uSF+Li-W&kASMq+A!uR%)zee%{+NSYU zJIUutUggwc$*b{MC3*h)1Jv;)iTWwBem}|kB|k;-%74ow-&x`hNM7mRE%_c24@y2( z@;^zwgXI0~)A&l^oh7gKeuE{i#$%4;+sgVIB(KJAcMbXDl2`t9br9`sk@dGpew5@t zlf1I8c1Izv@X3-_{<=x>O=bNZl2`qCss{gpf+SSi0r^0!OAb2ou2dwWY> z*)vD-Ry;|5x~%`TKFm%JK}#@&Vf6e*t}d1cQPlAkB>7bLIR`?7|7RSo%>Jwo;0 zCV5r=Y00bp1SPNRtJPD~SN7DCyo%>+$t!(pYRGSre1B>Go02~)`8#?E{VJYLNM4O+ z?NouQ@f;}m@v{D{l2_w%x8w&){A0Ix0mv{l2_xgMe?fu_e);I_eYYa zXJzSiSHCo-s{X$uug3p_8hGvgLSFg1Lk)hod8PlLKiV3rN2<}gC)L4@;Q=kI7rl2{b?h4rGKL2)p~!wCU z4;J+YN_~$=Ud89{l2`Mi^$;PyRLb8adDZ^Il2_w>T=GhP!=a+S!iP#;)gLGM5mNu1 zl5Z;cy*288E_oGCt_DN9s=;ChDvCG(_^spT&|_CZH{%$fN zjU|=+JteQ~A1QfNf3oD2f1as74;yj|-BqJYZCD|usJMpx4?0#9P<|MQs|QMa_HV5L~xSe34+6CutUnGBL_^+cmk3;IVUY zomB5MuA`6RqbSOQdx2Us6?m_OZFSo>pk}?v=xN=Km(9=sRpix*P-UUS;KK15bYiwgX=A9mN#VyuD3QOnON^r_=G?1 zhCia|dbqbf)8(G{SXV9|>r_b*NY`&LBT% zzVFduy?UP4Q6owlL+a>zxHg1OjYrdv#HCe`0+Hf6fa?9TLda}d)z%si%dnj4tjWj@06 zZu4EHe>J~ny502Uke++ZOPSthj$nGfnalJ6a~;!%%tx8-G~Z(SnE3R?q&Lnd7SC9W);)@W+Oyo zRN`~yP^JgWY^Ddz>zN)h?`Hafxu5Ba=0{9lGOL+Zn9b)<{ljKYrZ1b5n7(2zWBRIj zJJTcPKBoUN-(>ol`K6@Mc~t*(GfC3nOpltgC0)bx4fB3U4>5hy{8Z9fbMe^6xl^jPw8o5a?7EV;K$Vv-&!s<+o;MfDDP zELERUnT9`Z>QVcE7x%Tk!?m|@ruh#rzQq9m<7(5?(Uua@I4hq1T%>`aX)W+}-G%Bp z!AyvrU?KgQcL8#F?L;4b01QpgfAvED z$&Bk>sMY-3;0)u{GPJQ4#T%@O0?IL-Dh6~PiXT&uzQe9M+n~SN)eixC&B8xKzohDU z#u~)0{u!{ZE&MU6-|V$jFl?#u8q((;>LUFs(oa~&A{nD z5ELG|x)5p4%R}IwE*h4fO(}}D| zq^(?&C_NEN80-R?-4FZKrg^^F*>wiv;#ptqrkyeTdfas}Lw)$;4kL>85pmbY^Z_@X zHVya|hC2EEbX+w(n_ZoJnXKiY+o_mz-l&Y1&fu5LU& zACxS_s%=*lHke(p&up<&HuvC|jAkV7AucA>FtZ<*X|u3l$#KjWU-ga8np?!*0`u->krx zX;Ce^nB8DYRLf*@Ak!3c6w|KeB&OZX@0s>6=`V4jTJ|)}tBCe88#3)}-p1v9%)c@1 zYd*rXpZQOw1I(*fZlF1y=^!(Q%Lkham<}c3~PY`!XG24re;b zJj8Mt=IcyHo9{CnV}8Lj(_G4Omzmi_TlFwYnD#VZ&L_T?c?vYK6%IB{JbDv4VMKed zxOlxdGBh34iBd5G$Z=eQ4bZvB87P zqj2>yC9`xqWULSEy5APF%*WSC9kXbvS|6~j^>t=f1a4I8RpxA_H=3_8Ej7Ply3X_# z5We1Q#&m<(o$1ZyNT#=#ir|DWidhRw`G2L#aGriBe zoax`q*-RfWuV(t7c?Z)S=02tmnJ1V&Vt&hXr&(tq>8osT2iy5$gN#h#e`?T~%c~lU zWco{k?M#1dFrDdd4OTHd*WekVZDyKuR*GtqW6};fs!gu>4wuh1PcxlkRx`~r8z3n~ zwV7*nVmi+p!t^Th3a0tywM^%mcQajN?qynNe#Erc{GI7yvpI5pRGTH{Ag0UA$xN>{ z7cgCEUdyz^yqW20^Y2X8nB`3WV!p+6t$BuNnVEn*9MxvM*_7$cW;f7P`kg-fx#Gu( z^=^&FF<=uhpCr}`(8qNs(E@}m!qxS9_QbAQyD{~$@V*lT69#p_k8C91B&DCoM6@Jb z=`!`%;1h^V%61v)l&jx|=qGr)#-ceb;XT5pyNnKFf&EP7sKJ=ns|?}FIWA)kGN7(s z0<^V~&?k_J68*JR&@szZyL1^&(D7}6`T3wdPwED8vleTHS;sHlr+~>j}p5U z{UkUos{J@~K59p`A8*cJnk7y;?WdU6F`sMR!8Ff&lIdLYRnQ4HqINkNvock$_E^nZ zn9%86)eg4<*0;DH@M`^qE;yw3uX6x|1s+ zM$t`RW}tiy-mVuhu{8nRW^BO->er(9FACC+5}rdI_H3*3^NsjP2+9QdJrLL#Dl{tv zyA;p8#$==*eZRuQC~DEvt)!OC0r|G-G2QARt@+zvufJWdO=-m(5(nm0-Dr!Q+Xs-1 zt_#r*sIA7h(h^_p4EzqgHtC5bFmdT>lsvB2rsYdie@{2gEE3g6hg8>z)e`GdgAeJo zU6}YO(_pRdjBdoX#O}qCrlv)U=Dk@EXzntuxdj6Pfh{ETDJ;^=!8mRBI=hUn{e_|b zu%JZRqx$aFYyVP&26J&k%=et`C8JYjtppS2a@~Sasze1(_JoBRiHUBK7qk@mflc3U zy31UpY3=JdggVVY{9l5S_Eg1DNB;>?uetY4$6qO<8ElHdH*#mioJR~b{T=2sa$gx6 zL`~n{;C}a1-&eTSe6Jwr+|!ux`nF={;Lc_y{!*&rp5gi>8Mi(lx&d$355=e>klC(X zQ#I{gls>8uy_(_4SiIcxU4Lz*X$Juvv0x8Y6K&!o#GiYyYtwBQA`3DJ(xTH);H7|Y zUmo3dJPdyZ-fHAt75h?s?D@E3T}Vc|lmK^$OM_5bV3*?UN+2ZyS?k)=N7K?!I!YmW z6C1wS^)do18_+xpZfV1}xhk>STM4Mtf|G1`t83vV{HPS5M?+wpRpjo2X-6>O_bE^Y zzxSO~*gUEJB-k8H9ZKy^uBeCo(LDTK;$p-D3V)(n-N8t>k#4NL0SiA$=#*0*Z`VMA zc`mpU^aeZ^s66!s?AP2)bYmPUP(d2r!>kG;o3#e)*NvS^5IIv&K9ewRt1V+~bfXv( zY$=LwP>?>78WVU2-B`Uu)3yS;*TQ*+EATG5(W(=6fWRt3aG^vP&>h?0%`o6YNCYjZ zOuLm--7q0=9+(%w%LeM~e$h%_-S}nq+ zMt?>j145us35mfPb!ZasEWO?@6m6+#NK5WXx{+6+X*6$chcx|Qxv))m;7Vi?_cYy@ zG88{l4eVtLry4p7CA^2kOFz!wxleDSWjXa{GGAVr$XjHUVixNf|PWrY^LyhbpuVJt8K?bVHs zAWl#TLG;Uo+Uz%csP(LFJP;$G`aDhlrnl$bnY%C|?iY2V`D*-ZC2GAvHR;0fF_GNQ z4JGnaxI^zk(;%8;g@Plxu?Yc0_39uOIqI@1R>0<%H^5%^8@llwLY=UF5yZ72GvO8Y z7rHS58D7`NL+*0CT~lC;)}6s`bz}c^02iQqxx(~0Bv79g9QVU|B26+qnov>acirfU z^;EwPB~Ms&=t@?kb;-R$Po!bhqX|gh#(XX#H3>x@pyb=oiu1`oqFGu$+<(;@^1={J za-w#7mvPtikV;I%2;uJ;2v+>*GOB!r5AE@NUYB&GtKZwZhJ z(RN!lbA-##aKqpR2yC^4NDB*zQ52G+UB+fOhkpP5U>HdrF3~dfelZiE;a!M*aiOTR zZ;{LRXdHesU6v5pq$SXa+WnQwxE^b^ zz8m24mH>wXjjEJNbQ|MvTF{R};xkK%)ztry)`I)={(Sl}qU(d}=r*2QE+lmmdx!+Q zMcmf^B?CB4)=!Z?g>-kfaZRBR(tAU4AW5&G#{1+J%))-rZTyV&f!ftC2bOJV6ZkN< z(RQ?~e>Je{torr8BHJF+lfTExtQ!ZTz>ReqjlDuhe-M(7TH5M=LDCQCJ*sT!$!=qA zsu0rOhUEK}Ze!Oike=Z-Qn4SRCiNfj@f+bhLj^w1ZPYbn{rcDeHO5=?&G3?^irq#- zP;!vo16W@h{{j0K_X@Xhs;9&!0K3x0%c(avx{a(QQvYIL*Vy>uWZ%thqhhSYHv_xV z##_w-zQt_}K>Ix2PXc?!#%cfPzSC_Co+|OTfxU0x3HM9}{*c>v6=SD=i}G`XQQvh^ zrwM`mZsW1dD5}#8|H}d1wtz0;Yx}KG^P$@q4RiHWNDNR?no-mR*uUMzF{~?W;$&dc z2QaZ{~o<-S8Qx_ z!|efAH_EsHp-YnbOZa%BMwR!d%DsB80d|!(Q3mZtNK*d=A5mDQ*g)xrI3z81=P2W| z?kG^Kd3CqxSEMG74$I z8-nsNs;-O`7I-4cShNZPvj8rz1U4e>w1kiALBq>Y2K^Vu`Wk>`N&q)^F}sZ$Jh6Z{ zmD~?#kAiicfgF(r3A$^0jB*SyOTGrFk3uE6IU(81V-!u3l2wrMwooI-Iyp%S$zC4A z57)BJmXPWdDrqNOBR?A^Z1EVI=1K9(AUY*PToXe7@EB7jN}(kXxG_YCyQL-2_a*Mb z9wP+@9Q`gxJZMSL5~3w!jf21mk1+(fO5YFgkP^@mo?Hj4cP--`nhEcr{ItS2zU9zt zMFw^csbw@YAyo|t9|qA8zzLo5;eK8Byoca(`2i+d0=&}@*&slJbYA!Dy9rXmAaSK7 z#cs2GlrXj@L~~r8^{XMe2x8Y-qMUz>yOCLp$6cO(7KrTN+5&;Ql#pip?Q-B*x~HV0 z@Sp1`U@s|LM1&aU$F4)?-l=7*gLPzv>m;Nq!%21<2FVX<8QoTjjOFrSz!UMd6M|0P zXKNYjFbUjW)G`uFrDR`736JtlD&yr25U8wWw5TfuCXv7v9^Npv+`zW(G zl!(>oLo4tXvwtQ?%1Od&jH_5?72Jkt=kfa_tJ$rm;njt z=uajJrsM4zw-ol$l}<8RGHs_i_7ZyiTw!p+?wNpZ0K8V!(3;U=-*LFHW;0e{s(lYW z9wc}&6l%?A*Vb{A(LP2rqn87E$$}@*Hmu`VW8?q{e+=kz3-)BE^L-#KnsVLXAHDc^ zXC01ywGaw?^c&Yz9_!xdB`CGU~UP*->{RWT4T^+J`F!0ezMmWnl`rU#36${OQK%phX{<4mKMT4c#ItXmF zgvciQ=+|QcntBxAeoKJEfkxFn`t_mn>RXWb$dY0;*3nOcLGmz%qu*zNM*`M0gvw&SeIL`v>=ogI<=laFKmRt3$ zqu;3B)S5c_%}*0T`n{0cVQI6Dewns3j(*E(2_gL`B;T=gTSvc!*GO%Zz<#o{Sw}yA zXIVcUMmE4(^vyc@eTPjG+nx-pr;V$l-wEt18P5bZ(ZozNEoTVmtt=r_(M z@r}T?*tk0SmGu{iK;H%IDH~Tuzd16-0tfOD*^&++FMZm7MaCP)M zidn92K=JJa*%n$yzh|z1fOYh%lO-hegAhMbql!BERoGQ<^rJ7eNmBm-AJtTa43vIQ zN55hDD6bD^`0;iKsH0!r8rg1d;6q8qHdP({>c`85rUK6k)ngs~zQnGQx~ks*fwfAJ zee|n~eIZ+WFR&d-iGB3@8)h2Ue;(LjyS_U5Eu1dve+n#U*H=fsV*%)?Gfp3X@)4@8j1_hCn^6w}*#PHR0?RmAsiWWG^$=JE z@J1zI9sTGDWlkl31N69pb)I1yk=D`AS0E+nF6w)slH8ni^t&fPN`4P1cNaBstdomR@lDqKW_7-x0#dk@Pgnc;dLQfIBk-$nGFLm_Gy$TicP+mk$aJry9rFHa6m?#aVL+e&c zhWcO~{Z1jda;J6yFAtH?SLPo9{o-&(X?M7;Dg!1A{G+6sgeY7 z^qW5fU>8UX#G8+P#I(N#rpQXvvd%nzsdO3upRH&+t3{v3xua?ST!=J(Glq)1Z({{) z{!T}Ju!z3fY5s0Uy8Gm%yL-)#cYKUA_k5r)YT$u_#BRtfKTblCt{x~zLlEe@p=mGP zu1A*wQx6n;iV@QPh2rB1()SXs9w^8`27C?$y8aym&W8%A2MW$NhCnRZW!>^S)o3z3 zX&+*pA1I(>j`ctRJq=+!P*93g)CrZZz*~QT+RDe3{XhZfi6$`o0|m1HQ}w@wRM&}( z@Ib-+22#8wO?5?!)&m76mg6}Y6n{a`E94IAfr1tNgrP2UM?lsC1vHG-0|jJs%D%A( z6+BST46!u`75ISy5)<7dFK8*d2SNxB6dc5vdAU=FLuVdJMCjOcMCkC>kkpLUbXyc1 zL$hM&F-+@$g5Ed*ss{?_G-y3gK#cW30WsDC1?PHUEkJ`GxcHxe7 zAsOp|f+05|4MNKb()0^A{|wr7uXRn!#F~uKyA+~FQ6>@38{F(VIRSs+0q7YE_Sx`l zu0iAR1Tdfz794NGTV2Cp+t+}84}o=7!4DMN3IP)~vrRJi)dK}5fkjh?tOpA2UWkn{ z^bbNI-4Sp#p~eJ^2MWHwT+_(->40Vv+>T)DfdZZjRBk;`&%X*+-f{7gvir-R@-jy1&9w>Mkb%VgZw{Tj_B#s9PhI=uBy%2hMvuge( zT_~|0DERSe7|Q7G zyA1;OSwhqmU9_YgDER9FWIzbe9T{#(43_mk!AOj-{XoH{LHMQyC0|0CZsyoM)Y_^C z3ciL1eW@59yai4*YCKTz3T>H_A<@^8Vn15B-=4|QlqGxiK#0(NwPDzlsQYTXrBwIT zrbAKq`)bR9SohTy`~^E;6zrvTS1*HMbfuGwbzhD3s{3kNW&=I}_$1z3!@93_08^MM z>c8NFeudw4(=w=0_tnnV5zXk0U~@CP1+4C?9bYBkUV!>rFx^+9bf`tsMshIrm)cNjzCLT{r&>caH}6>PPO_yh-jI5={WX8}_zKzddF^1y9_J-kpW&@9=gtqhYa9!DX9(d9iz~i#KCBUD>ICRN1NEdQ2X|^}hHR zL{-|8Ix7{JSa0oA@Ls79(&s{Qfi104fzYi|!OlfONZ$&{yDe!e70`2Z-O-x2d>yKZQvpXvG<72BOf2Lm6d}u*CGTy2`)z=3-hyf{M90V5T>=dY8tvc zm#$t!Cg-PP+y|SX1~z3{($6zw^ZT96lkKdr-AWQ_#H%*a)u&FOY-OWZ+M}mR8~dRd zGYgZIY^;NjB5lo3$Qmgr>Aaod5B8E}qaMyi^F1B9M(Unsmk3?C&}F$;zmsw)t1-Vs zmWum9_xy}5Q%PxvppfY^9m=Y8&lb3VN?w7C-M%M##0W0-WRDdW_8%NM8u4D^^?Wi) zDEK<05gKpk$8p~KuE&#y2qcd;93m~|6!ZIXSWF+9S&7BjOm=y8r3+^lYI7spW1y%^1$v<@G=bsB~7^MDFpf7%*KR(OW{Mb{otIw+D@2YanXaGB@PWX$hw&)XP&5~x(w zh_R}1)3i%)c%9V=*Z&(UqB%tOtjdK0uEfIz!%+9x62ZU$3s|+zUl>v~&3q+*k6(1p zRWO=La!}*H83^-AteoCmQJ#-)6$&;|le8&gyT2{O*tCJU)TGw!0k{CuV{Sv7b0HTx zBzsZPo(}?INcghxC)oGbPVxMNj7C2Gx3ikgBIXyE5EM*X&;-e}8}8@>8bNZQVxHJM zPN5%~x#&ir;1G@pgymhRfKt1yphmVgKgM9iOwc_Yk*P_+qfqc)$Ia+?j+^e-E|8AT zl#Yw<&yJxMX7*2YaYF#BRxOMtyOowOo!2q*95#3qTCa=~nnywAzqW2DPGjc3J>OwA zrD72-Qte>NfaHe~{?N>wFeC;ccn%qdLSV0IEF}EdL|&9a=YcNbxHBe!w{b1c9Z0Gq z@VRP@s`PprYXDc{5N`YgJYfFr>4`8SJ8F-R9;j*ARshCHZ zXGrLWX1d#ng|6QJ;q6P{t17Pl?|nCuye#Ae5=cS<2_fu|Jt07VutW)qAfQI7eT3wN zM6)${VR0ASYF)skT8&GswzZ-^yH~7jwHwxMw*6UuU944XYwf>3t9JQWm;d*iGjs2K zO9<`n|M^F`_sz_iGc#w-oO9;Pa>449HUtFB>Mo#_`GF!7045=6IG%ysfdq5De zkTbu10{}7bhEOX?`<1^osKmHTn}!ifV)o**1%UnNGzH$tZCLjr z7?KARV0pmR;=SXNqZbsXYW-=EU>!ydmq=2r6Ay)FFa$^*d;?7-l=u3p<&ZoGU?}rp zVJq|SSpuAbp-X6gV1Oy$0rO6;qHSP3$kmPLXF}|N3z&;fJQJCY$vl+yx@)jS05;2P zY)OM8jsj3$;li;3klq`0`PMgyo<)NPS}Y zUGy|+fXW8uVkJmwY(jLEyTnKK}HA5sms z;@AUnxC+J7BUaIeFJ%JXQzm5SBse-Y%G9P7&<~$!K|w3?I?_29R@JBw#XNv)aU4U@ zp74ytVr5P|O@`I0rGnsTD%VWwWwg{jkJ3^7Cu*?c*;Jpo)_qu+$7`h`UtA{qU9l;l zBE%|O5zgjKS}AB{&Oc8o^5+t4#{lG3AmEC)fL7)iQ-xQq#5kvh@aiiOiC|m{!Q&M- ztI&-tgzC-N=(nW-MSA8*D&*)+ZMRW6ADWddbhV#=y^41KHWf0E026z`Dmt`x+x%g!24Gh_)EKj`|fAwVxQM=y+R1L;kHvnB;VXUu$ zQXbQ2d41PqLX|(CD^z)yvL&#NN0nF>&?D$Jupe3FHJ}Os9Op`oCkLzT9;xoZX|VV= z>*`X6dd0a+qD$)CEhYVUiEzqk$i`!cdTUJnsO|-YGnxZxA2jqZm6X_RR#5|${OzNctEEgL>QUTr<%Ft-Hv=b~fpD^&^K?uf7S7B}DLs%r(#ejC8*bd>c8;IiqLRYmUH^yaBN z9IBp!m`-0QJ9Z`a&a~Io!3haayAh8yZf^QzRnfMi^i@-NjyIi-nWyhg>$yod)b0Vu ze#$^iv+0*jr^99WBYjy3@2@DOv*PLd(q4vuw(kVYLv9Xk1ZA_P)26TV8`3KC1f%^e z#D0$esU=p^J(T=d+LN$U3H~Mg`-7WWN{7SK?+6S~7tprfiTLNv3Z-&XlvPRx#M5sH z+>1W6R{-cVKOj$xC|2+4=0*>^e`s8g8 zjKoo?OX`1xD)PEX>Wcb5fLcN7`qY*6f5z`=XTXNGQ}<@~QHC}&KXu=#uK|Nc6jvHp zOP)*zQ1Ct{^RtjAn|K}L0Y}y`0ux_@Ef)NuGqsdD>oY+2DE-|jyY*omq6P81Mv4L%K)L{{no+%aB2n_n*EVKaMB*$ zBtZ5Y@YEvw6KL@_{=`WOK}21E{Pw9x+eGPHIZ6KoPMn=3Qq$gzv>}u3_eZ|yq z(!`riTJ`~5ZVE^r!auIOWJx>sGLZfsPTHyHX)b&o0O|AI4_Xjz6xpAQ94)7WuHYzXRGLw zNc*fwk7J)l&elkt0l>2c$YY6gboFLC48 zoelQsgjV9puL00$l!YoUSzPvsLfUfS-2fOSAflHB;*~A1&s`8zjOls++#ZL?u+L7V zF?|jIPsCv|?DJ#TmvEYS<`(Xc)BK|FCXcX}j2pv1W4T22+ z0+;Ot1te)}T4yzqY7o8LB-tO~bghV;4Tym_vKN4iOtPxl&o`J1r{rvw$e>If~t}t zrWqh9;Qh7oUaH>@={IdFt1Q98RmAhB!(9)e*X{rY-dblA@e4PD|0$LnGGgT$Mf}~V zv5NS782zkxwIco^w2@yCZ|RR!#7AM-QMysYv|BCxZj@ydF>QJ?iulJU-YDYd@O#>| zs4^+yzflIQh(o~O5rq{owaQxZLyRw$q)SmpSCVoMc#?D@#I0Qm+AYDqz@dG}=qlpb zFw^bLh~Ht-c;&;Bq!%m!fUAf<+bxjx0f1jaSw2qaTt(c^&___pSYl;Qh zm88GA5Z5Chzx`vRJxA$WIaiY2hjey5y^gehn)EnHddSg8CWGsX@J}P*g+VCd0;DsN zdZaa*^f*bn3*AK&uy+6;LO|3mn|^tc)VDAQN%~xtF86u>-A-Ak@{+}sqzC5e!aoOq zCkV*H>nh^)^EIZQ1K_1NOh%H@=0tABI{-*SZ~HMBN&0^KS%xTvd?eO!}bk`|CmX$pCABN5g&+ef!Ukp}+X1k{0C|e|)1?|o6ls^5^f>le3=5pw^)Ue4Pe9Zzn|^uh za|<`lDB@$Yb-CXM(9bCgQC70J?9&Dz#Vz;?0Nx=W53kEUueWMUQ_zVs@XwFQuun;m z#Q`HO%>$_T=}r8D95Vp(rbezM@$p!_dkvt^sq8t z!BC}kTzG@D<35vPtTL{#Z_bx2b8nO^uIDdVBdqzQ&gECY9g>sMS&vsr%2nvy^cPXg z{9sBML=IA>;T3%N7R+t(@-IQHf(tRCD^e%Z9ro#T33+z#bwsCAD{?+o0-acFhu#K? zC5RBt&B+1VSN=S}(OW2*9>_>@-kf|&d@C?l;@0`d* z$nuKdqkGM5iWTUb0#vo~pMfkw@FYd^Ll<}j z6f3NpvjAM#Cy8`jdQ9R(YR21ffXx*!x^`VCLMQEgusIjOPN^)nxuFjb6g_}q5~0XD8;Pe2if3IE{L5b) z;mqkGYW_~DNVmEBsks7Tpz=?WMmM~3nw8UjI-*Y#N-U&k?lZf7(wTzPOneMr4U*2|jy>q2m84lSkaUof=puZt zx>n)mVF*^9#RwmZLl_~1k2Bl-EH+ophc_Z=jl*egyV=~Hv?&fWzbgXM){gdBja6wJ z$aoqGrYb${RU}&(biHR)1_x3y9xFy5lLNtwNf`)aaUd(>8?be&CU77ps4+V{Xz#2 zd*o~)h)eA37Xd-vE0Ej_Q5Zr;RsI)Ol0ISJt0brAOri86_C%uH3o&`M=(}+f06r@> zozq7TJmdmUXsrUk)m(M@7=o_^CS%U=tFL+Q%Hl+!l;mbmxv6T~|mVCo5xe;*m&%Z7-R?OlNBL;R&Y#+pY!d&UvklnG*8CoRREJ6>`A95eOzFEPTEr)^iqo; zx#kCQ4r8`5KPBhA83aLh=6}Tg4xZy|1qG!x;+Hhz_rk(P`h5+^S-Yr^tdHO~38td3 zn|}ZLFn(7TE~MXAT#4T`Q`ge(njHMDoq7)ap1T;o>!wEO_r(y!wM(ablFDsE-D;b1 zNq_`jrm~jH?>8}UYFEhbiwOSIg6jzWEP`(>s;A#C5&U}j{RY8r(D4x7wP#7*-_q|L z62CMJzax_`qq5FC6~DWtT!-J&R-x~9*3|~-O7@I-D5g$6fMjJ{Gamu@08%i+0&~`_ z;I9r6ylbWJC?Rh-Oao+9}D8Ralr@W5n>>yo$A3T7O zQ(rpaRS+RN80>==+CDYdu*|tI8*GSR#;qu*p(&jJtd&ENKC59l2U76yFu*jdP#FL_ zHK$>Xb7m#vottNEHt~|q)4~CK6^o9CH=LqYNS;j&UF%INq*Bglxg;}mp3NLUp6>&u zVT&39*wka_)P`A3=<^6<2Oq=pdTt=yh|g|J@nz-&&ZRse`(L3ndLRdV@#F?O^R{v% zpAncuZ)zG{pf4bWQSeYhg!MFCr!SN%+)uIHY(><0v6oQn`K)#6s(pdYx%gJZRy*0( z0x{jZ@70S1s60MN^|_H3iW^RMvWeDoJHPZ6Q#)tE*}$_mz&-h(hkhO;O~W=PM5Lw* z{B5E$KdhW>M5@~yt|wjU@6AE1oa<3w!+l~5(nbFw*WHPSm2*4hcMW$)=9x(Vn!gRc z0dGv8&jRpAf#Tb9$i9OJ+Z&ibUkngQ-u6}}qP{IALi3vx_^v&Hz93*xUi}j0FN@2=|ck^fD}-;4nPfG;E%Y_2MFTRa}HdJ^a;`~`Z56n zSUFimh<-rmK_4m*!;baUJgQg@eMO+*ZplZ>|DKg^<;*MEQlbWyE1OomuFyU2--<^VH6}}7-6#gf(2z@s}VsmyvjuyTv1BO1Mprd!)gy{Dr zn&_c%l(r)J7mQ<#8=LckGZ6cl^z;rddI{)J_*=oT$3)xo3q4GqbjUgLOh7CZPN#1( z2&HKhm^zmN;BVQ~fUi(G^9VhxoKICC>AC=0uJj#;c*c}Q|04%b?=S-T$b*MKxAXoC zq~kyym02>R%axHuQC7|e76IUQ0lpkHXjE^5TvmjU9-0p?TsV1&l}Ln6wbgeU`U zblZ9=@C`jG9)s_zaDp@8MoQ;q6)xC54Kq0<1C44 zDFcm5DUEzLTUvIcUUT-ZWukvqT}Kt}M(_8zZvFso{(+TP(-s2Vu z{vJp}>|+bo+yV@f9R|4^AlX6MI+9L1OJIR+r3iYa(ALfDy4^lI_%582=_?t!417_+X`$e=uphF6w2w9Y98SEZkg~te z&%c3~6`UC2XLgWc(&>)Xir`-u#?}uL1I>_!poQ z`xJUG<@vVmo9&sakTlJCeJ0}VKLYNr23FQ(&l-Y$4wR&w`av-RY!bqG_{aFH>G`Sn zSsHq&NAJvEgrr83Y*Qy$)AwfrW=2{^t447;(%WNTL`_Z426UioVofJ*rbDmW7Xav5 z7jPrhogUWopPmlDS!v(=fX4U<06k~`t?6&|BYAe(-q||&DI^{9k{29A@|?84H0k8u zBI);D@*8lU2j&*s2veT#BezgwD*j1}Gge{L1{UP7X3m%nIT2XM!yzSO@nHlOaY``b z2h$O#m`L54gYF##S<|TtLP1PB@Vp+R!Phd;nb|?QRT3@^@LM{q1c!p>aU$*aNvFLe zAx_H<()w&VE#HQMv>cxuq%oFG-tcUWNT)^R5XWW*Y0Wa7E{0yGiLArk;{Z|05;Gdx&U8)h{-`PRBE+C!mp$G+MHV_C!R0Qd^hY&xrgLIrf zy?7s?qPscL=`x2pL*=rAv@n}ai+&+a%MQ|dNII?cgo4xB z34+$%(rGm&#A*0OE)khl-9o{mO!e2#LIiEW2yq(5^e|T9B5J5VfSIiFnqZvQxR3eZf_7?kQbo#aEtXu7mpysa>Asv5{`3bHb{iyw5A+9jg z@yNn|_ULWaE-0TTa3 zX?wIDu@mTf50xk$1zN>ZmO+sq_8MIXGz|aQqwNNEf`-kavwrbkv9?E_2AsPE+~%FN zR1@A=OFvRWsc6*ucD~fFE%lRN6oktqye0L|=y`;zB)rbbqVt0P+|bPRD3j`-(R7;6 zr5HCFM+6s8|4~Ci-0fL(Qt+EPYonXB^+KJM6xXD1cpse{tRjSg!)*xfw}Q{Bc@o}Y zWzkW>_^*50qn`p2ZXFdF*Se}ewp2v7t}0L@Vcoi_z#P-MeAp#(+-|JkE-`q140A>_Tso{|qTqB%m|d+hlV))lzNUaTuHrxX*= z%um~SlfX|xIXcBrPRAl&*F|}pHe`yTEwMAg(AE<+Hd6VNGm8#I#(zfL9(~H>p^?eE zTOL4+Y%>LlK^zL>!?&pHs_fnw1+?EZa2S?C@!DmucL4iQT@Q~L|BP5BjbX-Ox@KVl zjJiDay1Q`QLxZV>Ght>ObLI_zexOTVz2PSBz?|RMto*9sIy!F4=H8YggJ9Gqf zd=dB~yFeP-Eo1aY_ACkS6cP9%yIR6+=%m}1qLb*L>~D2xUMHnqraOr?xtlRbRp3tA zh(5kT=Q-DH&G{w|jY(HzklpPU84~tH28qkS;dKcjBa2SpF4KjezxdA{ecWFN5B$3k zBL{Dj4SbR*GVrILX<5Gj?0k*W8~DFREO*yyq9U#0Ucjba4u_kDEw$v&9;M9^4EqZW zi+Rae;HFQ9ajn*=%?t*q!GHGXZb0+!r&hcB4^rvd#n{!*Ovs2f-v+^gt5TLoc#Bm` zJMnKs;x{zLkc;sl#JVDYD{?!xu$vp7en&{?xzoy;umU$w==?|A{8J8~A~eWjj-tsR z-#(in(HSzxx37?3vkdYx_=JRW_$!x|{gwpGSw_HGS#%ouzEhgHkPo><-D8TPD!B)Z zJh8=sgoc|KKc>a5FP()~ilFXGgIj$6j?7ksNalKYHmLuE$$Wf#hhjis^jA z*HG*Yx-xlgWu8GSlj}htmz7V4CjN-nsD|~1<=^9Bv*_6N8Vy(N;%q;tX_-V|UOY!6 zWSh|P;*}EIBDB1uNJinhvIXlw%0rXrd(wf!16B#$JTd^hfvfPyBQvTT8fJMo++zhN ztC@V|$O0;OdIa+wyr=4F&2y`D6tTIC<8XKGJ_N|h%c4``UutP)s16sl`U>3ys*fx4 z-9v>UVc&CRXrUo}^q#Xs!dk+RkhUtOd*f~faF<5mNvV4cibZ-bX3@=?GZTvX6X00R;`s&*l)lSh$a-oT6(DPDJjlI=3futFF@8z_qq=5hF+IlL=i?8Z30n=}`V!jnC`1 zPCq^%7{Y=4DUt~mADzh0*LgfjeII#TND#~HAk2=$$ampa~?DJ$Oz2HEV>ckGdiDF$3f(at0M`1Hsq;Tw~nF& zy*f%bv5v)0K)2iotfRUtkA|bBjz(!^tpSskYdF-K|LoDUYtZuv=Shvgr>U<`;7f3P zf&WY{<_xQwxro{Pq$%S@6y@qBv1>wssr1oQj0l7W>3Yy+-5*vK9aeovBiZI6p$&$K zCq3h|#u@fv-HjrV&a{gptR>P}Hs79xmWf1avkS!dZHC!HK9wxm5ZS8>_c}iR!+Mwy zwm5zLv6PimH&avvFCN;50ri!#&cb0x4v z5gxV>t|W&xDc3n?uEmevrcQd20ots5I(zpJ(447}Z*r0U46!c3*%%@?nFaZ5gEp}Z zZs7xC7?-QkZ<(fNMC(8bx?5tF#_cILy8B@)L*e2%Vi~x~O@gj+lfFn$ZWX~ft7vjS z$>nq#MZPZ8e z$>bHcS1ggRr^6(yIR-k+a7_M|)1it#f}?4==+$n~d_4pyY0n5_9Y!ZA{W>fZY(k!L zx+mjQjbwp~l6C!z1Y5c&+WT>`Xa+Q$WWotl(}en5X%F0SQ|3M zbOh)yVyA0ZZwBx%7kS1YFUiLlP=h!t6cUnxS0=P#xU6XAQqFVBntX##Nr^9w)ITdJ z`XNdRzBDlkJYSlG^~?>vGzqVRTLWp5W z--6i0cJ0%?y`3x-()Z04JF(3wuR@uf8jDA!r>S@n21E`sDb{b$hOQmV)|oKb<3D?} z_C`H6Vnm5imRf+A*^!nX{@D=}PVD3ez6H9}<(=itT*4$N2*YBKN+N@duoTc?PU39i zn-$ck=AFp=Bb|AXoB4TUjC;!=_ z6At+*={i6(QmcGBAU~%wd4yk0nTYVTm{C9vv`oLzBDz&3sxx_3^&!fXaF2{@RckD+ zRju1$WzqdJrzX(nAHWtzpCon|=o4dyfj%*In2$bLbZgCgUCuO@J`LzUw-Y^cfp{G^ z)|{eiZDrAwH4_qYM@?=jH8Ho?Vz7tl4x3*!HFK%eZrLwT?lJ7Ti|0sYS3gT|JpEk0 z4;}ggU6R+Kxi_ICqgD+|>Gw`6|Eklm2?`*i2~|87u|6|IyD0YYgdQ^03}jK3FmyuY z*k_15FD#M9J`s@C+M^{mYcDS)`|O)tFshuxw_loCvKfc89>Q9;`ygt9AhT`(_XDv{Je~J z>@01pwUP1k>T(zobXCzubvfQ}eVog|{ed)1W9q_@PK9FtT3K{aQAFqQ*l7MOnvKYW zb9KFWx8d39RnJI#`?H_ei;H_bARpDg-z-UMB&*G*TUSm~x`?V=ca?pb?bj6L_P-4tWb z{luQE?Kvx-K0EjTF#Te2GdHN#Z5ACiW06y~k4P+boO70Z{hZh*#0$h(Sv#?GsdKM% zb5FSqL`n3Lu)7x1KSJ)G{z(|qKl*-5J@Wpfp_y?Vb1@Dhmg^&i-8!}_Y5K>XfjQCi z@2j963bXR*#P?@_<`#_{`GmNCs8KcP9;F15V(;jR4hxB;yQf1Tj%k-09!eawogU8!3*Ho)#3$^x?nid zm1KDu34ZFPJ<3Sn;~{%7&NMwekS$iEHcd|t6iHZ{rl$wyNO+x9OeZgY1YD`Q1g~ko zLM#*M>3!0i5;|`CN5lr~kLkho6(otodd!*6=WJ^zTYDb}2ADt8H*7h-)9&U)(;* z>Q1n<8fTWN0lq#U%5E}q+%(7uPLs?N-gtY?%yie%^LPS_ZeVC0Fbrn`WyL_?+m`a~7Y`19!-%Rd6>4H^M5@Si;z zx=W9LvLQ*TXAA(Nl~y9g!Irgm>ntdq|8BF%C*TCqa>RAlZCP1#*WPXo=kd^1ppG3u z7>%0m3=c^VJhUU%vX*ERo^ZGuC|u#-nHrFt5Ds*&lwUZA>CtAD?B9Zm4UjYNB|Nwf z$S-Bp5Vrd}@wFqoD|A_zx>@$DkjD&YARc`w020_7Mxd9okU>mkTxzjzgJn>7PPYHn!{&w zk)Hdi@E%=NvWDG@4be5?zLIW)T%J^j8wqso8n?nD$nBatQj)exVeUv+Tct2}bWOy4 z1#?GRrB?oB`REQ{>eBdYUHqR#EYo2rGjXE1lmGZM%la{(*6O^T&*|4DuXv`rt&(ro zVL=43fxqIx?DNuI6jeiz88FKW?uAIycsy2}f!JKm2KFhr3yrTtOkfEfjN|i!V*x>J zTnzsg-fvemBMQ=qpX4Nr+zT9>jaZPrH+M5)mR2-d^!E*S9ysUYnguD@XXvblsEL^e z(l_VadEmDITtF5~>^x8`EN>nt=B76fl(07sB>0$lAOXb81GT|wm9IlerLMg<&^Dm< zt~2s{`mS}UhVkTD)+%(u?-w!YBq`i|_D|TAeUlulVwv}$? zZTEp1q>gA)7`roQpQr3~fbmSY{l>F|VLVS+fcYQteqUqs#@?lfjHTcs({bM! zVvlIpQn&QS4Xj86JrZ(LibW#8PmxlB2?LXE=!ms62aYVsDRoeR$Y z1THYrd9&TTGZD*m{1lT6BY-absYYyI9UeRaK8hq)5z;nHtA?^|It8~q;a#PXVx;n) zJ$eyha~TH|;Zg)h5$4lpx$Z>Z?FG#YS1;h;j$?@BN_exLLCg7|J&nH4Wi$oC^XU3W znpBj~)m+aJ;#cwDO47tKuc;Sem(bP_%0KQxXWtL)s|)lvc`{;iIX}%X>raCvrD43; z^7(*qZBmx@uL3bkLtF-HtWy@u2pjWMFDIa{=Qd!!EO2~DWAu|0w|~eLYt>M;<@2zl{{SkXk$U}8jM!Ypf&Tdg z;X?mp(bcwX8Wuy0|LoC^0G16dQWdUMkZ5pe`@l80w1FVIV6fbxHI3_F$)YQ9C+Olf zxW&DS;>KDW#|~1Bg-gNJxG}4y2x~ikos~s*<-R<>nelpky7H5{4P=_ewt@Oo3|7%_ z)Ta{Osp||aN!RJ#uCaP`z6)5n&SYf9naQZLn4WsFhdN7GPxeq}VCBnng|w5=1Tw@ zM(pP_>?{|yHy*Zl1%%y45PO4$o$12f9t(>hNEZ(8)^M|3xL*U#HIh>cV4~o*;c41f zPVKyv!!_Dyw(>tU11lBCvO1x1>7R}v8&);wy5b5Am+KZ-4>)avyT-Ux{I|*2|BaMV z4eyQQc7wNNga#2BLf0GrZEiDT^!V<}fE#1%5a0R74)L8HJ1*Z9(-Q4-!0`u-*{i|J zrUu%AvhwfGM^zp~7irjfw{?|>m zmQc1s%@5=KNnK#3Ti`{A&E@REEy$$;pdMUQdDVvz*VTOh3e|0sVIg%Dod%m(6bG5fsdTa&M618aYvbJXh`Wz#z0xNptVD*0Yg01Pa}gDLzzX_N(J2>$vOP#NzPI@=sKTNh$;IU6XP zPajgh5;0HBYG#NFUAX%Y%M=z1jVKH%eIjKheRG?%Q1Pc0VkHky_vyT)Zr&FX^I|>= z6G?oLpfG*K{9QoR>Ad}J-l<1o%3a3`F3v|)F?|>v+gPj;y1uL$P=R%LxObH?0X#R_ zQ%(svO|1ol?~4$AQM@yBY4hCDuJohGWvpZfA(jmxy8Q2c1in|^%vn4e^hv}rdBhs? zHg541gV?y0KMPjii-5XG=WTQgeb?mm7!c%Ho08{Rf!(m|iXR38>bw)(yz>z2D;I-= zZeLu7*qs`-)P+66z>-%)WDSG57}=O>xke3XkUrgZ)n(3#!mCVn+z=3tjs+3 z?F6ib^O)yFz`4FpZ*AFZJdfGP2Ig@$vaN)D@;>sOqcM8Sll7=>kqi$o&tE{}1&D3X zupaX?Ccstz_AJDfmNZ-RH^t!>TJ&WS3E7cJSam>5;QM$mGE((EWCR}GjI$>P4gcAr|3GXm=O<*7CS&UMIUviygOTNT8S0xZ>?MFL`w>)p%EBphVirneS?92oQkg;LX33XhmCzyP>i`$H z2M?~rs#r-tNP-ta{^9-lG${fCpa1O9XAqmq`B9yZ+3(k*u<5A?;O7O!ZJFU zpOVMbb`FnTXx(YkG3*;cZ=rHEnqp5-z3~TY<_ntNiOvu=Q@%R^?;9HE2sTvllv9@B zeWMPxS!dI!@ck2-k?V#j&5UEROVR87xM*NcslE=m_b;Rq;;7rDWq*QKH*kR_>GrY* z_91v-Ic@0x^~=gz@V+QSPNfu@m{}!@!D)8_Yv2Jqm>o!#TMMY9PhW-e-gr;ZZ2}Vh zvqzsrY%XUb#-@+R{{}IESMgvRq^Yb01a%(jm-R(BT#B1HuZLqYVskkgaGXtt-CI-x z;(j<$Aiti%89+hnOFjxZhmTz%t!|kit$y^9DSTH#%R=HR=kT{KDSHFbCvXb4(>Z+E zr8@|dkY*#_DMSn~?-syp%o9#*D=VSkrXq2A{^ODzRmcL43GA35rrnlhIKaPSt_0TY z*hv`Yo{c;o$R%<*hhMy8?U(YJ5skZebcdBSMgb5m5v0!(6XMJC@6`kRvh0ayRiGRX zrWhHxKDk0oPThcgS$MyYK)Nl6&E@<=I=X70QGEz;8JcvSL>NUZ3tM5nbR{%EsC?FWIZ+I|?>tY6~c3W$OI3sK$b@>5XHmdM~RelMX55C&*`2Wn=~__h{M zad%)U_8#6tIn9WIuY#XE626RT6Kc56a=*myExAwedtL4i`3)nusSpMMAOnl>;POcu zSPM!JY{SUkf%j7hBG2*JZwoFdf{Be25!cKD@oTLw7>ue~xfk(!OYYVD zUT589pN^qpKQiO~4}m7g|8`L`o>+?GC*dm)7pm-KvmaSSP&6sQ=P|5S^l*S)bs(!# zX*t;xlM=L+W-iNIl39R<r#?Qx%dCua;!C=90chtFTuVny7x{tjTOD?98lEF5ZW2`^pK93|Th9Wb zB_$TRg)_X=XsRD47L)uiL_dKl_T#-x+CMGVcCs@wrB{eV)8q4c%`1`orI`d*8Vlz^ z&Co<}n^RWj>l|vr%qpgNG1^}4b%?IeEM^f9hgf8`TL>chvkeo>(HLEZnd`O!QB=Em zmCP6O%h8W3GM#M5j0(Ftw?8|MtP9-&P+hNpMOPoNK^MYQv0Af2Wie0^Z&mqOkUFs1 zMWSm-`D$Xz)2*v@L3McqTIWV`ej;UuX7~CE$R)$@(vz5E1mgN^v5YVJm~>+-F6w$2 zI7{42nnX((QnPF9AX^6dQi9usO)gfhwug1OpX1@oLGM~CF&N$4M6hNzH;NWkTy+fy zEG0lf2EY%bF4p(~Wng{8&XoGE#f`5RxDbPW{=$8tX6Q@joSJJJZtmy)Tep-%4hklI zYLz~uPFo*aR#Tx{(guwYc?9RiSWpp1)Nz|)Aqnkiw%y8tYV!=ROC@5q6ymc!O`-T!7HH*v_>Ev8mQ)P}d3F&UCAy`KJ@0|b zDo5;$0~nemQ9bJ0^SmHjGZmIkZ(w5Tg)y)#tIsduEUTYLEJW+f6>&M>7xI=hIMJS! zoeRNKlzm42L^}tB|Bx%gxcni~MR0~|2^NHZFyCcus^EwxhHxtfx``QpQufA@$de}f zViSb2M%3(2mPnMmAU5G@8x*EuE{u(*Vz`$q>molnnhJ|Eh)XV}abU(KzURd~Ky`Nc z0pGZYM+pa`tvL{27&cV!=H^{({A z3Rhg^E1t@}TG09in-JrggyM*&K5U~?gQn4x|5|$)$biKxlyoY>*V(fnGOxEMYq4>I z4RaOOd~)SAb*Ltk_fSk3Za*AmRHRsMvKO=3yV(O|F%i@9TeywXVj3!R2U7)VR9EPl zMc7V{{4r5f`fZfYtq~P>drUE{u?EY>ViNnaUG#+Oj=03QymulwRz_*{IqFN0adp=i zn0Q!Pv*y7HwT@#3YTN(Jo`9!KQ#$;!D@TThDtiYy+IuT^cXTYOuBxc6sH*Jg@8})r zj8t|kSWqcZR%Q1Y7GMm52`hn9At>!3e7Aiyxye&t045^2%J!K#w47T@ZSU+vUL@918 zRU6IZ-o;O-H7YKK1RYeH{wQJWU`~nfPsDeP334Gg6Ixu%OYeY?nQ^`h>`dh$t~@b-(boRHo^FVoZmSnA;7INPAI3!R=L3|)VwY=yGzYGpo)VBRp_Y7KCJBEZZ&TKUeBo9 zZk6`9Dj!kP52^+$kYWd$)NK8p05D`IY*MOAP2Hdhj;aO0V=Apnj8DmtQ^E;V_B%DP9T->dSXs%S*bJE+!E0dGioZ>VWO zBpp$?N7b|nHSd_3aaa``QTa#Jj0!cAAdjgEdaYMg^g5_!&?{J~3g`_;dI6eVu{qi# z$K^0KAvs2sfOreL0g6jC5YU)|4V3SJgR$0#e^-4XaDxHirwV+E? zzM+-}E7Xj@>^!ynfLcS@-%yL6R}DwhVk9&kS0#a2d1}^iRd$3(RdP_(KCEg8E_k*o z;&+9b8+=+7A5lfe)!Yg-|Cn0aq~@L-8$$#}t?^8Ws!Y66(S-R|sOd-4wBu@ig<5z_ zH8iOSU24t-H4Ee@e?`rHOHDnZ3XiMV6{_Z#TI}pUq|#qjjmRC?t`xmqLX-0DR&`EW zo3fqxM^&TKyB@*w(D4Wd52;!w9aIP`$R)N29aPgFPvDH1!F$xy<7y!qj1B|QrfpCe zggsa#jB%aI7{OmDdqzr%n(JJB>D_7(0CK>T6Gqe&u;av6R9^6ARTw;i%yudoF`a)j z5iSZ+{|8bj=pcw!N^rf(Pd%t6b%CEJsr)X)*{QnsQ=3#Vg()(C$Xb3kF>3_6IOyE1 zW<9OuMAhWL+(}Z&;F&6Pjw%NAf=5)w(`u13RH`zZ?Bnz+NL0dIoT~YID(y{`GlH%w zRm+a4oTpXQah3HwmG@ONWxd+COr3^TW}8}hOs$e%=z==>1r7=<%2Up%%05?R?NQY? zscBEB3CGmJs7j{_2luGZS5-!!JWnljE@)HLUq-2rNDGPks^6tR@KD!t1e)5FlA{V! zoxDRJs_pa!k2S3iio75}Vm#*wg2b#wBnT3-)Da^{)&P}R*Kuxuc%1U4ntebO98e8W zb;<$NctFitucmBJvk$3)LmYWXH6EhK^{r~k#^mwqHYodWAkCApX0gpFh78MMA zSrc^N`cS!FRVl#{k+X`0qFHuyK91x$G4j$ZZ#v%(*lOYvBxz?xRp>627QDhQSIwHL z^MJBd@e?ZaG9YgDLzrb;=hie^%{{1AA5b+>wdrmV+o>4J=>f9}?EDUn+|?UYYnwmS zEFC-ljnoAjRE!-ag~~dpR#I25S7r1%u4d8esLG-j zjT9%9Bq+o}5U*6os+`l*q{m4rPd-SaandLT$6htRBT zN5+L$sG>mqWHtHa;7!zx1qW3SV`5a5AYbFdYE@LtJ)$OpyN@bJgR)J4R1*U`@>N|_ zt%<7TN7cmjYWjLL5iX^-+>&p(~Wy5TFT#R%s1o z&1A4y&Sz55dylJ}^{Vo?s?o|<)ZRH|%>;tO{Tk)~jka116J!EjS=LM-mh<(XtqO3> zS#tlq*yqsxlr{X&a=s1m?xEW&*LC?*k_1 zpeokdTT%~mikKZa zC!(#{;d3I|nteqlL0hv`=|r?OTc46s&upr4zKM>^c`I0n;ZW)C8na`|`8$YT_NJ^h^1DTL2!+fhHRsk$8yXwN${T7rq&!~B zgKr4a2&CBx=iG#96+WTLqH4|om9|`JCNO5JopWEht@7Sdl?PPdfSUdRH49G&$ls|{ zWcj+9ya*b#EZ0gYTP z!Bc{ffkB@ZrEy+(4@m<2o^^#<_*arQGd8NyV7JPBS(OLB0in<|g@=0Z7By)D4QdFB ziKD6rVxjzDNR?7mcTg>ls`4XBT_K`e>T9-UI-dh2O5RkHkE=PyO?%0bHTyoD`;(DV zMv2)&>f8vKSbkK^K58%!#mp{M=S4KD5>*S#)D%q@TY0V?NY5j^>VU~gg_~Wu&aa^s z0>PCkZ$#y;XFg;5UD{yw`8qcPYRW-XqFF10<&D{2?7RS#flI)Z0+;%7n|;d8ZLztf zX=c~6^DQ(j=W&&U9%P4`L>3Ex<9U#xG>ZSW|zG4GHN!W5M+f)=~k1kP(e%^QqBOCYh^TLGWE>(7^ua8cRjY$teo0~uWjJ2}rSczFMb8NxMaY|TAkI}Jh@b-8mJ<(| z6D7&H<68?f^CfVHFsC^U<0LYtIhivSb4umRd7tD}H%E+;SKS<5avny*^53G#E>vLg z1_-5DQ~aD{PDq_d=6!#mZt0uJI7xJ~Ip^iv4r!ou^BmUAm^Uw2FTF0p%A6;2K7)Z# z3Sl+n4K)?qkp|fw*r4(Q^|>nTfSQI`DxT|A_9J9ZuyW5(#F6IMoAWkg;Y8RSfk0VI zqs(!+h$?+qIg&8zT#~@fQL^w-p^d6i zoe)THK&{xQLdP*ls-kH$)KA{!YWnX~$-}DtaWw~}tAiL!y=`RFt zrt@w<>}ylX$qQBp-9#dp^OVVjtvRuoC~QTZn3JK-9T-WK7)eJ}o$Jyd%9&%Q&T|-w zlm05UY*eP{>(x?f>2Wm)uRsOQxmApU`&hMRvLA!)`N4f)hY>T7$$B3iW6b$x=TAt@1Gjn_KiI`8{}ERC zPpQfCF}kXzh>jE)U=C3`KO_aF6;uY}HD|efp{DhI~MdR4fWSZg|TeA*L&QKapkYc+)*BZ2(5Uk;ix_VJ=dWURRz zAW_DKxT@yL0q0E`G6z+jCZGs$bMb-m9#TtCE7WmHAf0S=X{otfAxTRGzqzs@Iev3- zL=yZ`eRGF}^A0*;l9LO+M`#PExm(yvDsgkYCJqUuSaM5$nTt6R`%9#?x#T0Bgp!)t zpwY)E8X=Ln*TnfTdS-TTD=Er6zr-`Qr#LqNAoMq=+8XIT;b3zii}MUxSbk8=(H)S^ z;_?<#_RVNoMR21^f%~pPrL0#?$NdJKxs}HGB^W9jaQP4@N7d9W6}Vd!Y*5p`s%qdO zc|*;>(3{kxri`d6cr0i@cd0^p9pzCD4B^g}GAagxW&Hj=8(% z-;*llW+5j*st9kG3y++iL1qPl*MRbMn({J&&8BUox?E^l)F8}tf&UDZBMX7@bk z*r1kd!a3%GDCc_^0L5=&pvO!l%^g+Fw~#y)X17o9kythNT{*X8*lOCFq*-R`368YE zT-KF1JcT>V1z_>qAT| z07N#JTMM0kfIa31m#b5afh+0ejzsSL>NnN&<7#qLHDNlzOB>nnH)1xlT#FxnGbF#c z&C&S^MnE=baP>)^EBmtTus)wv$$Auai;TA(04K>P~^D}T**d&eGfac z?BI9RBE;Hl5^PhUDit{0UwLz9XG|YR2bxPkV><8?(t)Bo%zdNDb%(k2G>PsI*=ep- zbv}mvpZHb5EW_X2&YHv?63UueV4Zi77xE$PIhB64%HB=ZEccCw2XoQv7~;X)b(>5) zkX>YM(oJR;38R{;eG}z_RKQ#l?A#6IGWiLW_BE-V=D%jmIQMskh&`;i%B3N%Ut*zZ<0xNa|!hrBTstH+=A^G zt(S3}RbKFzU+0;Nxc@)syx!HCkSCfUNdq4;pov;Zg!X#|Al@F3ac6FK*W+%J8FxI; zFg+k69JV++n}ZPP0X!XM^#d*_FcPt!5W!Q!DYt;F^*_vW9_ znJ381b^gha31^s(1khsVtb=N}KOJCY15=?U`#Lc}grE zU=?FLSC}vRJXaz*%-3{cgud{O`E<`oxXH~ofllNmH{TeFcasY{o39#;#m<>*-kT3B zId@|Kmhk}0JD^eyswE>TA0Fx8Vd!)ue9I}`DwKg}zAKe%Ad1#7U#W`M z8o~wUTUYU1AlS_(wBl_Jk$&d0Ud}JUBV{m%C&HtSNew%23$YN5RuvvlDyBK+`(cS1 zgX|yk5i{qH7)C|VPL0Nhk|NEw)VLq&gKKH6y8ylv6?|G$zVyENZkzKfxI*FlpNfgl zG}oM?v0=Ud=X?pq`WWj@=8JO9BY>$nh*dKgA=2reTCYdQ7&1(H?{xzeH{%nQFrVog zlO^t9mVmcF(@;9?gBx_waRXaA&3uJ0sWVpSW4?CiJO}zr3FfJCEM;Pi&Rv=#gXN#5 zl(%y*-}$PV7t|D#V$4S!lbB>8#ID(>Yk4=wM?PCkK1ns-nRMb(#Tqo9uS{+YnlEF< z8MD0u{ku!~L7T9!DY9dv7yHZBVrNu)e@Dc^?lSCh+Y<>7_w4Ssh9Y|+L)hD8cF{G3 z!`N#W?%20)=~7%bF)-BE?rpK74Q=xmmSP{%(xtKyk79I$yX%hPR+RF87VWbd*xNB| zg?DU=R@a5Y9Rq{=!+qFR7jCa<-MFi&WlO`B0b~eos}8qpuMTgo3U8|oZ>tF-$7xI4 z%2Y2-s7&jY4JK=}L2AqMX<$fq>Jhb8r6i)#bGS7;Wi8y|B?OG8EoB z)IP{PfvTP`3pd}ZipJH@(?1*;infeP-5#dn)@^lRa0#;PiJ%Jp&6G{d2wuNy0{SS) z)vNaH5Nz#eS=>Jm4MzsLTDETJaT~BU0&)-R54Vr(16NeHw4m!dC9ZY6iW(BT-HaL& z7t|3K;BU|N@U~Sa!%sa4v})<=YtfZ7EM`iJ>rnI@2y3>F3MX)vQxnJGFC*VEE_!g@6h4h&-WcbrcG?0+ePfuO5r2%BPE zMX;uK1Y2x}Vr!sf10?h&!1qGrpPY~o83Ad=qa;z(Hb`fRBu*G!O9n@VyQQUs!IdO> zJ8`^x5xs(nZ;LjDwZv#O`h$l#)Q0K%<;(TBna|_KSGBkiTsIWy?_^2?e_#7P;;R!# z@cNG4Nc#{sXj^o#9-^&VjV@~0ygj^? zD*CCqsxzXKBH+2I@RlA(|8d2LX_qGlecG_EbsVPida4(yQLB!zwUO3eS|4DKIVtw| z4$}&ulyquuw-^C+M3vU9y0R^slhbOuA=PG3&0<0t3kA5^J3FC~h6lQI7q9pi%^0ay zoFyZX3C4`u2C`@@43FLjWD{94wK3KVtF3=S(zk4Da1Ecv@V3PeFbPBc->k0{UW2{) z+hM7M`#RhA6ANJ&RM&^YF-HTcYh!{9Xd`SMa5$cPmO%0uA*w}1eTNx0g0(iLle}Tc z(oS~xV|P9oPrbud*Kj0qzKjBc)^M-ZtBbYCL3Yo!@CYnaqYd<-fu1fP#X*ZEs-o^S zpP|9g)MIG;1q1ysT~08jYpT&^oEK;x>5W4287+>oVY>F?Jc{HVb2P|ci0m6|@9*@9 zS5Hgy^|%D_grMJ8Z8>dQIGK&Rom6K_b$w?~mlh*@3In#&wk6?hYgikx(oSMDfTs1o+nk{B**0Ul8BY+CgfnHHsWI?a3L1avS$JnEB245{1dk`qC zo5Op1IwRrE_GtSFy8|2=+vSvdT=AF8^4SQX*Tn|Byuf)eHWdjbOm(WO$LZkB=qoMp zPQXU2J((=p%HIsD0ll*riY2lej1M7+6GZL((bipTv~h>~EFdky zYuckctt5jQYOQ@ZT3dtegSP1DXO%N-#hi)r>G;^eul3UkGxLMVB`3QEPEJO{>S|)i zG}2GA<47m> z>h(aeWRL*su_k#6su;I?AZ+Xv$s69V@dqPYLL*_!lSTsC}Z??jgH!TePMo9D9_J zyDbd83X>(K-!K?kAlQ0Zpkpvi!>qYBycH%W+%SadwDG1nhM$ufoP)h&aE|mtb$8Yf zHm}VlpH}sH;DPF}SI3f;RV`d44~Zch>;#_l~`Mis&|31FmL zC5wKJGb!MqY%CHhyvjTI7u#~zb~1B_q&+2ObWB%?er3T1nZTpNOms?j4G_zr=e23= za`O1LHC#J!{T$~RFs4AGOB1a;jM=7J9;FF=ImaY2EPN_Cd@)t7%Fi zep_Ng)~jRFh@GpkedBs@lev_~Rd+DreR?IPqH(=g4U-sir)c-kz+Sg+TK;8`0(mrs z2oV$T5^**Q7gUAUm{Z}cx;pD=$_}^VmhIuSgPY0qWrpeu*C!F{L>Hdr`DF}Kvww9= zIbaN&M4`?eKQf4TvOp|=234C*r1>|QpY#t5+AxG!%Rpbay`uwjYIh-kjL?=wlZV{q zXwQ}nP!Sl9;82Yl!ent?Vf4X{lL^5kELIFxbAEu29f!sIZ=X>4_`Wpe$O1Le_o}p&l0| zn{#hTI&EU7t&eStIf_w80v-$>*&P{b>gpY6XAyYlXM^Zz3QYaNMDH6wwe|< z{8k&2W-Tv%VJ0&)B#s}=!jNrSH*}GqMH5% zp}GOa&`@Mo57?CZ1W0HG(MUFuD|W*JyUxSJHryVEZfyS=S=-$MBib=NrgL-&D-1I2 zTYJ`{3ADh&K2lfO@>qM|!C<_4p$1lg}ssrLdUmO~A!K#T-zW#Mlgw zyGcBz@CTqtdf^xCCcJAfmUj;f?T6LZ2lWBo(#QxKRcPGj^iA6B( zI)hIgCyokcKRrDkV=@PldG5saK}hnBAGqOw4D4L5%OquXpiRqt`8E|R{xET9F&QNr;W7*{%;tx zB*tpVi-UE)p#fet0+o`kG@0ILiCb@~4sXGj)LF+Eau7XxjNFmV9s|%fG1LQ+dMz1W znZ6_D7S-nN0~yZ|k;I(wjgvYW6+~gSs!mwjlXk;^KqQ!i=>!-H%nHONh7tn_)>M{-8nD%5z-R=LEW zrf7D_Q}sq@xtYS_+rFZ6s>9+c)$?HArk-k^S|pL`?a}auMtY!sBl|o*%~%40McXAY zn-mPUwXQu$rzF(Ie9RpACA)pXdj@(sMWJB*n zxT4GSX>z5`^L?NFMwA~<4khz6*U;nz6+R982!8_2me8s=7eqBC4(&tO@73OiMQF^C z8^bLSQsQ|4`?fTMWl@P-Y@Pu}n=Z67#n^(z9j*Q2149~sXRbR=(`;B%4adVKOltZ@ z`t)kpHgeI?2;`g~Gk*5Mmc%Pj!>}d6liPoTB!jf%<5!3O#)dXD2MdQ_oN#}5ID)YO zZ|`6`w$7oK$h(-_mx4`89ldCz_Iby3X`ElJr)9C(-h>V$S3wddftldD(@h$rW?oBX z0J#}FS;CW1w)?@gzMTm@C)$(X`kko0V+t{hdfBlimLDWfe@EXS%MV&?pqZ`Z?&V-I zjnj2Wm{}agG2QH8pGXW*=hqn(D!xNJoSnv+k@iOw%}?8zpoT65NI0 z6Nv$CtSk5p!5o7M4y=Q+zMc*xN`!XSd|0k3F(8Z80&MVNt1zL^01cS5m>rjo?tX)bv;*y};lf4DQb9GZZ)Z=>PP z#7tlo?Em7`0<$;H127%rF~l}nV>gQlSPYOo(6ktbt{Y3=$ch+}G0@`-Fzl)}CNUv1 z(`!&dFZg(s(NuCb!JQ)eBU)*r4*ZnVRNo+qt9pH;Z!o&wjFxc;>M9S~LWSkp_Ri$` zzYAN0A}jpUbYd@;uTJQ6bS)PDCUtj0FFUwkp11;Jk!Ry1&4FqA5LLIKSMO~IlU1r` z@ZlafCt%HXw8K2;iSiDs1k%=@+-eslyELl@!Lg9nF@R5l?Aberdr_m<81D6N6Vqm4 zsqA*(8jtP1Cl8D)hPWHNWQZi655f?MF-o*o%_UVSTF(41j&3(hl2ic6=2whz+M95q zU8sIlPEvQwaR9r^>L3FonYuT1F=H)>+GlCcTi(Lk2hG+G;(XVqMBC-rZ-ezPclVNy z2nn{GD<@+FQhZ%V5nurI!m^}&@BgAAV1)&t5qo^&B#Dq*cKWB;32j=eS5_eL^aAgg zT-2!N2eNs!Z_9?{>NH`k{r|D&RJ%=uB>&3l30Q5ciK%a41RiB9Ok;q?ZtZHK<#-vO z+I~0oTzvo6Q~%RSco=hIGD}ES^8g!@*J-_$<`_PS01vyC2`7|`ez#?ux#UX6g{3D% zF}`SpuJ8?ulQkG=Wrh54yv-6#cUR|ly2Gn;tcM{qu%qUDvJ+3Flz0~&gyQaqIQ+>j zKvtfoU<(0d9;cF~qml|RjBTPnuk-N2NesHUVWTm5a+PH~Pxp8$EHtdy>kdYe9YVBU zoqa_$ba}cbkjz}$a7a9h_O$Q}igm`;$S}6DvY|3wk0f)lvioHShA~Oicvm)+?w1I1sB$7#XK=PWE?0Rdc zV}EJKzINZnXf|o7sl3v{b3<^E%uX~L`KqAJsJLx1(xFDa*Wvde^sJ>HgWu|q|8 z@Bm7-8+Z)Wm;9Ru?w$N&TNfuDh2C)j8m!|CIAg4OY()wmEXC^_*iizPj?vA&Ee%Gn z8cV+pGsYN0x(EEkvkP$6SY|Yt4>25Vu#K^(#LCato-sze>wOvD^2C8PIMxl7Umou9RW46*KV^6$B_AgYO{UgI2-SLxWGu1Ym2*c#mVqf@)>&Wtt>Eo_l zU^B}A_B{Dkea#YQoIjn%PEQwh#mN*9!vg$wEUS7w1lEF_c0USN@(tyELmic~8L-L7|oK6FD!QO!rJy#(QD0?)Ltl`G0 z9IcQsXotH8hN7kZ0~ACFoJJrg8|~yBdYS)IuQ=h}kL5 zWDiL57!pB`MA^Zo6q1q3S1iOs>+m+R19+zf`}LnV>K${f zY(9=_$-W)gGOV*KuO?J_+qTI9ShAGp!SeO>!Lsr-P5_RAV{#CX!m2)dIo ze8aSRn&$YjH`4U6-d%{{5o7%&=h%cM$|@*iqIMYy+r*9Bliq40LjoIZ%%1Z&MC|YR zmlo7q5fJ8&sqx_Az1n^`?;lh|bjSf(jfAsbR3PWV&clS`k*ye$MwVe~syR+JmR6%> z9Fiu3yn5iXdy=f*_O$fiEU<4&BdIEONAYHkxZWCTX37pMRu}r#nG+Xk+Cq#7FKXO= zYd$0Le_Q(&Xw8c1%tM19XiFmxdBz4G;nf%J?YF!x-F>02&`nP_YO9c++xO9ZzD4HKQ=mtAEh{9AZ z%eGruXl;p1e<4UkV<~~4<}#Wu)Ct|MaaXXVOwpW)FT{hOr@To9-XV4DjtH1+6FANe;c^DvRQ_E%5vtRm@F(*P!Q9u`ucn-v@DvuiVBQrW zWYjTjpzj=CSe%==(KkXV3q&rzFp_V%adgTggbF)4HMTIZzY`RBtUC?q6oUy0txm#p zca^GJQM#xz2d5!7z-$7pHnA{?UUL0pNn*A+gSUt@saaW?6j~52%%qQ>CRc$fSok1N zcE-!Y=p%1>v$2t0TW2r1)h{=-+@|1BVsMM4^@4{Hi|pt|BH;{=S0kDPxlf30%4HTz z%!tTsqx1of+d?Xjjx5dz?aBSz^F4vC3XZ71fmIfBnrIQRn(o38~b+oQobGA);p`s=-f5)*ge%Ep7Ru&hD` z1%b*hqf5U*QmWK?KhkHiOm7puF~DHEbtin-p%A(bhO--I7e=O>1)E{BK4k3wc*gOb zIWT`VwMZdDw;8L7;jy63TJ8+-)gKiH2gFz?OJ)HX=ZT zL!&vRS0CwRh^epqdW#I9qF?Scz-yNw)%u-#5qklkt zALjU3ZjeSBpJJv-#h0u!iHzhkSj}$|iyzarU=>pZ<1u=K9D27^Gt5G^*hDY03=LmS#ZAcu@=(txd-YWz9xbh)q+9pk%kM+Eamd-H`Q4Y=iXX~7 ztmD-jXC1PJSrP6f2sUWJi|j0i`42M|O88uzzS}r3PiaK#ojI2tg&`=*UXjEEm(b=? z{oF*F7V1p1Zj~`Ax8glQfuOU#eq^(*9+=Ii+EP<%m;-u6s0>W@eqe;2tg>|F9kf_M5 zcB*p+CeU=rZqL7fz1DrtyV~0~M|3yh_mbUnqJp%IIyXyd4Z~&}^^_4$8$_K9Q$2oH2U_xf8jHZC4$mL5ncA*=cpkO1e`{sAI4xx+N1YnMKNv3Wf z;spz~C2YRF_?j*i{sxYfU$4O%e(E zx`&|cD|qSX)tvMk)etU1Q)bmF9E_obuqGZi78E&$IbWbOn!RAa&QP1j50;MdD_2y1 z8i}I}thnXwyMo(jqYvCwc71d1-T_X#)15*(vvZT~*24ANDW#X=r-Jg7-W(t)^BI%^ z*uj=VeXp5Ky*emq~@G3ert+ zYo%NJVs8NkVt)_S12fxWE6kghGUDGB$oBz?u2k!$`$ZvB}?kTc&>H3 z-eGHv!6nkJHkp|%C&5a$A%a-4hh4&fJ=_Un!3^o3UAdF3b}udO_vRcgubzkrqD_)A zb8Iczmv*0loy1JD6L@Lp3>)!hw0!su2U-r(WW2$M$vB2BCj`Cky6i4R-|w+q>sjNE`A%Afrq4dtE=Ya}-)Wn0X~EKXWP$BUv#?slcu%bfL+^wHu<^ zyrIe@Mefe9xurG1<+p_Rv4Xc-LRw@~*#d*%#sz$Hy9l4tJ8UV$o%BFodRXM}2iye) zlT3W!(ifAKwQM$J7CKV{;R>*}Gwo}OP1ne3hOV6im)kcdPh5RZEwm%6(Q2wA_pOI3 z!AjE5l$lB)3N@}qp?ZqoqOg14HV<#su5CWd*jN=)OV@s}H2I`d6rA+3n`(k(tk)dQ zOn(R%E+j-jE{sS?xXCbzg7Xms zuZ?bpp~llog?F9^y~zWCSbf@wH;!Wz&8K8^RBx<%+@lbI^NIBAGQNr*B??E$VAGiC z?46rk+&?+vOISssoBbYG-q} z*GaG0iieu&TW*H&+)=$7Y?f4U#WYekz{A;e>db{_m?71LXHf$<7`2K!W9V%#!jzZA zNQ9x%Fh7$-6Fc8pv()R|ZE|iFyz*C>=Zr4pyag zldK^&D6kT;pO|dQRl8xv3&dqr&KaG96+5{4rS6qjF2V#hX2a#HKKh(MppM|W)H%d6 zDLp1fZsU<_hz{%Qgq^qdl_*fPmUKuNwcoWcep@*7&RI#gbgw=;)1vL}<Am09T2Q2M$4l7%e^3!_fNNh*!m&Al2Qj z>7k3t;M8({L#4B;L)$6O(mp3sOHI7%q53!dG$LLbR{mU<*9>SDGjg(+za1AWPv@cr za4Lwa*r_i_HdPF`uB;Qw88{m_Iga}8*OdtA34K|3cZ^P3=olBw%Z=lV(PJp`XT$7P ztR^!%RbFk98!jv*h>Oa*%_Ok?d*e-Lb!H0nvsbDNusE6 z<$iEwpN!Fsa`<>v$Z7<#7&?TQ`Y|%=F5Z0+4qFu3YigMXP%Wn`^GqP&neVWzbMq69z zlWnB_{%Df~!h@MRL%%n24#c6nEi3Xx);?9Vi?I(RN@HJbCE)kkrV=^{ZH@eH$`j5I z*J8Q~4wWL{Y*_17zP5xt3rv@EucizD-g{bQw64u-p7pyq@=R%RD7Zqzd|lFuE^v2V zl}zYl{mIDGnvGSzYMO@N=w^uRK(+EAuI3(w)b-6JOycT{p%H=CvSkLkb&q#^Sv=;R zk@2Le+UZqP)DNlH7i@)3i4ktv7Gtup2^On2c&&&1#%u%47^11>kaRm36-sUjwI;)H z>h$=mcQ>Mxhug(m;!oSB*&Dn^wlCr`GHjF}ve4u-uASd+H>~kn2?H4zzYV+~oCk>v zl5RevD3MT=D8zmDU>d^p*|tNAWqzeyIn$Y%oL{i3MeC{351|?YkXDGa(wV?r65!s4 z<4hZ~_Cz!g>r4*Ca;WK53k|E~Lh^9`H@eF=PRuGCE<_~Y}{RF>e)rG@20Y~2GgaPFrR~8nhHju9PMy-xuD!*C9 zrLpL6)1C1UAF^3l&CF6d22Uy#p(Rv%QwUNrF*h=b(2je<)=IR5wYMU$=XBQ6H4=N; z2Ygc-Hztf@&)TODI;iq5?LN@$(y=|kEH+9Op*2{&>b$ejQcm#g2NncPen_LBO4lcC0V;6(q71r#K~7FsX4p*cO|doH z6vO@!E>JQDdBmceYpMxc8LXzUM3c2~W-6jQ z&X(I)cBsUUL|s|znTMx`Mbry|W>c=yyr{)8)WlD^t#olIH?)@28k!K(Ng~y$V(}O~ zdDARm6L}ryOK6&^Os*r(v|oGSU}3-E(*k@g;WVK?jQ%<8l#p-B67yfq{I6JI{<#&Q z{GXjwhtEGdqy;CK7CgxGA;Nbi@Z(H>g76{2FA#p4@H>P*CHxuTspo|6pGMeEI6(LV z!Y2t&{FRV@1>t(a4TQT0ZzTL9!jBSuFM-FuIFu)N3e$owW_l&zy7NMQ!Phf=6X9DE z_#o4Q-(_0xhfM#7@aUHe7WO-aaBBibnI0qj4B=-9{~O^q34c!b3&NMZG?XuR3)6yk zGA;OCrhk|4uM&9t%R+f45UwU%L-^4Iet~JhD_$Pnzmjk~feTCv-of;pgvX!H?-O1| zcsb!s2|UR3A;M22@H0$*mhf@He<1ux0#{xTzAxCvwBXfDZz9~Az;`o!H{oXpKTG&1 z;kO8nx-fii8Q}*K_`jJJTz*l=FSwg&!FMqIPQp(T{%gX|CGcUU1)pGA@TW}wjPR0+ z!}l*G+(x*a@TLUb%k-xS|2ly`WLogjRV<(I@dU2y3(o~FVOsDNObh<((vV;9)c%k@ zjc`i>CzuxeAk%_hW?Jw`rUlFF3}u;5^d{gr7*@eM}4f%2lB}!BtH65$;If8<`gTIMafUGA;NE zrUh3GhVKbp%e3Ge(}MRgE%>6V!~23SV_NXlObdRD=|3i%+7#Xwyq9UgrE@7M z@Iy?0nDA2xe3a>L5x!_kcwcY}(}Fvh7W@#?f`87m;A2b+zGNtrFF4Nh1mQvgKgYD- z8P|mO&m`QOzy+oS?`B%?qf85)d~GOC@bgSRNcgn`p0G9K7rc;Z!ONHyd<)Zp|C4FK zA22O=_HZa)a2?ZvuVh+qH`9XuiD|(vF)jELrUkdXGJH>Pk?8}3?@Qn(nHGGKX~CzN z7QFeoQ2wtG9!lU}FfI6VrUlQrKD;mZcBX%u@PmYZKzMHg?`K-@%S;!C^*g#as@SkB z)FgiK=wexMV-|mOaVU#Frr3IPuAJu-cV_X&7Iz+-%YR())#G#c=N2nY$l;GK{xpj} zp?E5be_ru{<+*a6Up$z_FE4)Q#9aOt6kE6D@Fy0#v-lOo`P*~(PbxONDu;hzv2`wo zKe_ngn{Fx6-_gY>#kaEfQ;Y9r@uw9}-jOTkMMZIE4u5*_R2F|mF?d%l|CwnOJ$-a> zRToEH4AwBTRdf?wH!KevHD3YcSxAO13ZaGD{OEiXQw(8J4H z@UI{~rJwCB_=y($9WD3|x8UztMv34Vb1MtfWEGcEY{ zwBYY+!GEI#|5OY9)McUmX+75wpSJgA;?wrN8TcHX+|B%tBpmsp#1AF>;Xe|e*5_|p z@K3bhpLcY=T^G0Dx3=K-wczh+!T&4b)Al|<{Mw|wf7^opDe-CloOVpUpU(w;S+Tr$ zB%#BX5MR)8Xk=`^b;J)Q`0If`syL(A@#b4RpOKCIc00bwSMOjs`;&6s<@uZZ`BT8> z=;Y5l|B1yd>>qvitByaT_!miiz74#!_mi}QUKy%cEPqbGKSuni#JBa^b;y5IaZ<4* zv%ci&`C8;Jist$?<>fTjmqpKia$`Mu8}aG-^+7MEx$gW4@aLhuvV@(*c71_(SuR!+ z|6}51u~q(;92?4!W~}_%fqx<2jlmw~m&Kxw4?jY@EK=7I|9RqNd0R{TQ^ZU1-$eY& zkIR4eO5m-%(zuj=j(BPAyI9WWh?mCt0^+~rqjrOGA+a@F&E}!nKk4e?Yu6(thG!aeSzcEazI$ zhl!WPi>tt z%d(_#d5CyvB9-sG^#&$5U(Ae*Rh;80Dn?Z$>Ajb;&$ejC0q3KapGmEMDzXkHQ;mo^JC_h zrmk^01r@XLdh2{|kSsD6VmQQS5j@z!P2E z&2nTxSj7jA5uftO9}%w|m_FuTg^sm)Y9~S(%OdfzsEVI|oOtb2qFDd^CGhyK@q3c_ zwR5(OIaZt;zAFo*>c5G2S^Upq{#%Jp`S}NdKWW+NMUn7_PcXkMLMvI$_lcLK{0+pP zeM+d0EI=S{|GkEI?W}4X4-u~&0L{nu5ibj``twJ`%c8IEjzi$F{@2c`)~OExpX<** zWBzm;pCJCD*9>~SZwu8gUJk|2%Gb_|=yRHQ?XZX*?jc?~N2>pKh?fOg^4sMQeXRUc z&bfhjS+F&}zeT)u+C=~VhIm9){e$s~w&9vArX}+dO*UjL;9iO2PDQ z=9dL&Kq=$#_Iy&pWYPknx|vLYiC3K_F3X(sTKY);(v5rC`a|V5EI0{tDS)_7UB1L z;`N;*cReti56d73wg}SmtEo#|4LEJB7d$w?_)Ws9QB=+{6B2LA9rr3 zr*;DSi}1UOcn)nYBuN{rci2ot++VN0-UVsJB>22en=iJErw*jAP*L#>>JDH-x zFA=XDB;mhLymo>?mj1gC18v`xXMpHxn0R@jXx@FDc4G8g$4Dmo@F!>t7nm zmj{68a|`kE1W`Tj0N&R9R4;fJ^QZF0y~N9NL-XZCG{oAaoi3HXnRt0HZDBu*5id`H z4-)?o;!`>5G2-P}v6A_Z1tYTWYKLV5@dLzbX9;41|Mn0s4+4$Ly~N9N>jCEfCh_vn zQh)v<@lUKC^qiurH4r><^fL>*)l;4v%Kv`iifzx!k2weurBc^VYPlVGQky?w<| z;e}PeTlv~42Ko7KJMr=$xPth15wD#?_0L1ZYsYPr`7Z%MTKU?!Qu)6@ygUL1nExBZ zr}Td^7Az}AJA#sDt|C6w<6cX=JOR{icN3rTu|Egi_?0{cKfwAt&iwLZK+=C_T@>mg z4+hP@iAU0Ze@MJ`^4~!GFNl{XlIF!F;H##Or+V(?z+3;wqu|vnXBEbI z1;%~%n{Oc|fVVM!s)v4@czLRTT>bX|@!G*w|NkTL@;p#KpMeZkA9*~f{;wfkJD(6^ z{P$bLYe)P_;?I6geq0`9etE>bgY^8g@Gl+o5=8$S`$B!>VE{Jhzc&#t&n3~}=ZKdF zsOIKZfY;wF!olOrpUUkoyCi&9o|ez!OLN4_^F;jQE5yq)RD9!m#HafEv6qJa`PhpF zz2q~==g$G&#y#cF7kGYFA_6x7Z{wB9CvPGCyXOshZuRGvTFQBX`BT1qB0Aj4muG_d ze;fX=c_;h-IO}vX^UH%m{qygLzjsrp&o1Ww8S(PyLehV87*PAJJOed^Jr2dx@84@;1J3Kk@QN`y%oGi+FkJUPk=I>q7bRs8jhj6EDv^@vF}eFOQ9t zEaw}*=i2ps=1=F{G0;z~UGm)0yBC?>$}(fHnfc{$q4DhyFOMtH;k${K2a?9|AuoS< zF}Q8eiw7I@-`AO6o>W?AkAnbX^^`}D@N0>er`m}u=N{ryx$%4mv{sHhnM8*>iI>Ng z+Vw8tQ@!{h;B)=6;uWEMdA1F(K7+)kcJ(ph<#BTo^Zz#S@*ujI_`fG!p2ZM@{kI&1 zl&jChz*~FeS#&1zzmE8nZr@D2JbTm+{{{G!d^ZMPVSai1-oS_dOuRhMRL(V*hx*79 zS@^q&mxrhD4-+rXu}v)h{}L|`(>~%~3_;G?o9@?aCSD%(>bF~fw|=`bneT69etF1) zoc#Am;^p}Z@jLu3nVQ^lNnf9Vb!#peom=Sdn=SfAW@cvhAn3Rq{Oub}(;Yh-m*nZ& zH@lGHEME@aw>UF3dF%Mp?b#RF9`@lnq`8H~{n?jVp7r^aV@XxLTJ;BZ)6(Qd(Cppz3{C&y)05{h=37@3+p_R2jy{ zud6~Q;~cvKbwXPfe_HGMn91y#Qo`_9~oJB$u~72KD@H&oX_Vyx8pbDnql+ zt7rNCuAV1-T|LP4GmaPU8O2Q}i=kV57^^PmB#&$T6Fs!6iW*~6z3Y$dU9f@qg~f>p zOocHVZr+RN0ONCrDbYcM^BIe-(ixlW?46q3gE$3axVUoO&f4MH6@*N~&7Na@m*#W$ zRY^E!KR0qa+PE-xJK{f#OpkZQ7N@6iM@%P5c{6KS?M!*!=za@pv1{S_{*9SSEyJS? zI695k34SU08r=U&A~p}4*PiMG; zBXznT%5DkheLvJSJFnh0)EU~o#X>A~uHF8s&d}CQKyKZ#69*GtyZ!2I!<+HUDpR%& zcO=D#Ft)184cA<=3&#L&yn561Lm?JN6w+gfrzt%s4}*Y>E8taiFw@Vy>YQ@zOlTFN zvn98M)r|@chk*wNuf2YF)8@`V-$38maDX)*9#p3;>z7P=lpP#`v=BWA5^G2G%W$qZ zpvvg(eqSOBFYBB=!MhrDtnLT&U}GNrCpxg(h~AK%kH(4a$+`KVoo`^68X4So_d1ljb9&=4qSr(a-ZN9vQ)*7_VW z4mhFcGMd%nhxUWolbdKlFxipe$srALdrPW3jgzifvT2P_6U7}2v5abGx06v&gQ}zX zI`o`9%8zb}f+kMB5+A^wDu~(S0ZQ!>cRv-~PV}7`@KXJ26)wjj&jjfl>Sl1iJf{Q7WCi-~Uu%J9 zAnDGGhG?0_d^dD(I5HmiO8$^~5$`PHuH zO+LEx$mC&|vduzlw^R(v#7$9k&^c|lKvi_b%vwW_@GdfwiJB5jQg%5g40Q!=0mW%5 zySVPO$rcvjS+2o>?7${dJ`Hke4Q7u~OM}^4$w72vz$Bw5FyQ*NZAPUo=~Y5Oon({7 zbqP9HF^1f1Di^|%>lUpKOTSb_Ps|f)5@)f+O9YZ*=VV&)yxW6 zcA24?SmH4)v7vCoZi5J1=H^sZjs!{HL^Xg~?imOEJ9G}Ub5|`jaXe)-6SeBFSJH~FNJVaP_~gFBBpD*BMY|6N2#MU(xh6ly&O~IRBRIa;avig@QhrmRLQc|6qhi4 zhwK)x5L>;KXDlVKB+Nm(%s5n9tCrRW)hbgd52eDidTw#1r5NcR8Oe)!VsAEDa_y#K zk-tC{tYB(>7}FxPKxdTXQM;yZEi8&n9jqR#}gkbhYD}ox5gtb%xT>iBwK?%#v=maC<5Y*nU;x{QT@hX-Gxw zZ6!*^I5)?$w^f!G#MktEPM&q6(OnMJU}bG1+0vnYL2}u7-FC3>VMIrUl@g5@pRo%` zv1K#7dwvcigDVUWj~;>Pr^kmOpF#f^Lj4cebtg7MhStI2i*WwnL}8p-mU2|9X>j$m zdgwqeu8wT3>6Ru}w3F7yxRp1D0Eqqh$0qPMb_d(c$ZRVk>!+(RtaExp3kmS)() zx->NwP!nF6xoWp2j%TNxs#Ml7URyz8(EdVE?qXWo>n@0CcE*zY!q%7mK;JgQh)&_oRHauRL zgcUjbS5xK^RR;Wf%Z;N`b?oTW*uupAPUugVLmHh8(WXueqFxF4__Wcgnw8v<*Giw< z*@;FWJL57kdYET2zSd3P1HK#V4k@y1f}w^rl@)hp6K{8tn|Jjc(4e}`95#%jnzvAZ zj8$X?Uhkg1Szep&+H2*fW8wm3yT&9@mGRjn3KbgJa^lpun~N9D-ORi+awst`8Fe>o z_WeDtS;~xW(82o6a%o$eQo@pTTRf?4t?QUCg1OYq@ou8l-Kvc6TW$|k8&u`h%grf* ziDjKkubs%&BJTxEAiPzlRI|3WXdbcDkdW47-9ZOD$tGvK%;jcLrjsiMT6??kxjNHC zD@tdsgL5PMkLVTTw`c~k)X}NB_m>c(fz*xhx7b3>8#K8<4 zv7tGD;DQ8!%Q0}9&@cpHF$K)*q23o3$HVQyvO1_*TdlbqE(~gqxPO>ltNH$5_U>lVy%>(4#&^W|iRqKl@7J=WR9h0g3m2Yx|&$2$|# z3((Pjy{5_a4ZsIDBhV+KtlIUWLcLbfbj(BdFQ|zdAdSK6Wqy3kFdS?#emTdN7J`eU z#HCR+Hri9$ZRJW$|KsLRXP8Fs0oJ8B#_(2S5b6~SJ1}+MQFU0b4;XcTM8F;(R=|f* zKBTSQdOavEXNib4EZ+w;e&pZWWUg3|-(>8I*6TxRM>X*AcZ{K!xqU+@9?b;NweY20 zUn=#7{HI(jjM`(=9SOs#XR1}rj6->e7=*O3cDVvRSk7`_x!PefH$y_k=RFUe<#x-! zJ(_!EhqF*0L0^He&~`InnFC&B%GyGW168fB)FxA2I#jYgn@T}AsXV)@eseu~dVJbQ zJ+(_ml{HOCBT)@wY$H2jl_}gIi9-V!C$P@mLx(#1$LHo}XK=t^;r7mfOVib-V(qFQ zDJ61=4p*`FW||U!Bl45jmfwb`mcD0p`(NACD*L?ThZ@6YZ>n>ib5TiES9WS?h<6iX z&Tm4@U#nlRbjNed1u(S;GY#_>EXU^Ut7dR7)>vof`26CuQQ_vzI0RtJTzEa&g@x#< zDGEI_Z#9M4FV;A8-XT9r#GEqT1J#;i$9KxwNO81-1R}Zai-F0Y@mt-FA6TmfI^A@; zXjW#ep{i3gO=AuM_Js~~2i{%<R+o_Hp>g_rllwa@F zZrg>W2>r<*o*ffAtxP->w`f{$>RTYeaiLrO zQogg#CY~aivs5RHq!I`8ONS220bK>s4IT7^eU!C9m22g{8%9U=kBow8yZ+#(>|DEr z58~uZW2r$Mvql7)%uwDt^X8D~&MIV7<$$@MFQO;!FU{JOmz^g1P?t>)XwSUTyMtTQ z?Lt9Q$L-8nH<1L41;&3D*hlw`kKP)*Z+i*es!!E_vE<#N?&kC>HNBee(Xw2X6K((4 z0iG_sP+I9iPbZAs)yM3Jw2fblwEfgjZ}M(miEI14b+yD^s_9Dg2B@P*BLgD~K2l3^ zjM2Nz$>v-N;_D8WHj2La+ou;s_5d!-1-MUtnY;KLj#$skE{ylV%Y79tg)aK`&Mfxr z8=2o%^o`vxuy}ka#u7Jjo%37j>XIM-|>;?X{e+mc0T`%f`e*ymX^{Q`f){nRJ zjql_6&wXQfS1A-aI@;lxIMj7&Jd_a*Plht|H$F8oJ&Dumd+jJX{^|2ihT@^g7JWFO zI*o&;p{9ElC#S~xMiv(4Cig5Z;8bhh*!Z4By9e4PNtv9SnZSW~KH9SfH(o0>H93RY zgeT}f{mIvL!2X%Rv+%lw&|&zP@?MV(M4X)z&u}{>*5U;m7rlSuvO%N@+ymmE5gXx{ zfG+<<*pI?uTDdF;>UGOcnf9>`CA`O8_oulqziPCcF>%!&UL zM?>!uT_7AoVX=Ai{+&k;`lCCKc3_uD`0rT!Yi-y2rw4Sg8PKwn?;ktpPwuoA@Y|+x zLek6NpAN3WzrT#?uX{|sdVI(=7(m&6eMfLNo5^C!vFfd-hU%-*01cY@}89sEC&)l zqtE!KaTo3Y{)pe#eJl_1{YUI!^jpEd1@A&SeqV75e}@56{ypMa#6P_!+}rU-{J!pY z*}5&{U^SH8`?^fvk9XsLdtd#pdti3+{YT==_*?xa^uNR(@%y?j=KSp;$MbD+M!&TG zK89!U`?^hteE6#~t#-Hi;|84TV?w{E@7v5WGg-5^i`=7@%i)o^1qB#Fwd{cNS z?QeZw@XN?%L#6k1pUt=UzVe0As`?B6C?05TSRUPb^Id(P10(v>d#cxW@s2f7-`D*( zPu>9}e##e8&F?>k2l4ymJvw)WH=fdqg!;bV6TrvsD?Z#)cZL_*zR%){f5IPDmg=uK zfzQ1w^569S@YY%P$8R_Du5Nk%;Equ0JIDuBO8Tv ABLDyZ literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp index fb2e666..f33e024 100644 --- a/main.cpp +++ b/main.cpp @@ -1,14 +1,16 @@ #include +#include #include +#include -#include "dbscan.h" - +#include "include/dbscan.h" #define MINIMUM_POINTS 4 // minimum number of cluster #define EPSILON (0.75 * 0.75) // distance for clustering, metre^2 -void readBenchmarkData(vector &points) { +std::vector readBenchmarkData() { // load point cloud + std::vector points; FILE *stream; stream = fopen("benchmark_hepta.dat", "ra"); @@ -27,15 +29,14 @@ void readBenchmarkData(vector &points) { free(p); fclose(stream); + return points; } void printResults(const vector &points, int num_points) { int i = 0; - printf( - "Number of points: %u\n" - " x y z cluster_id\n" - "-----------------------------\n", - num_points); + std::cout << "Number of Points: " << num_points << std::endl; + std::cout << "x\t\t\ty\t\t\tz\t\t\t" << std::endl; + while (i < num_points) { printf("%5.2lf %5.2lf %5.2lf: %d\n", points[i].x, points[i].y, points[i].z, points[i].clusterID); @@ -44,10 +45,8 @@ void printResults(const vector &points, int num_points) { } int main() { - vector points; // read point data - readBenchmarkData(points); - std::cout << "Done" << std::endl; + std::vector points = readBenchmarkData(); // constructor DBSCAN ds(MINIMUM_POINTS, EPSILON, points); From 5f18ad639224cc65172def3915fd0757d244912d Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 15:46:26 +0200 Subject: [PATCH 04/23] =?UTF-8?q?=E2=9C=A8=20Example=20completed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- main.cpp => example/simpleExample.cpp | 3 +-- include/dbscan.h | 1 + main | Bin 169312 -> 0 bytes 4 files changed, 3 insertions(+), 3 deletions(-) rename main.cpp => example/simpleExample.cpp (94%) delete mode 100755 main diff --git a/CMakeLists.txt b/CMakeLists.txt index f5c19a5..8cbb5c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,5 +19,5 @@ target_include_directories(${PROJECT_NAME} PUBLIC PRIVATE src) -add_executable(example main.cpp) +add_executable(example example/simpleExample.cpp) target_link_libraries(example PRIVATE dbscan) \ No newline at end of file diff --git a/main.cpp b/example/simpleExample.cpp similarity index 94% rename from main.cpp rename to example/simpleExample.cpp index f33e024..bfe716f 100644 --- a/main.cpp +++ b/example/simpleExample.cpp @@ -1,10 +1,9 @@ +#include #include #include #include #include - -#include "include/dbscan.h" #define MINIMUM_POINTS 4 // minimum number of cluster #define EPSILON (0.75 * 0.75) // distance for clustering, metre^2 diff --git a/include/dbscan.h b/include/dbscan.h index 0834f74..588c53d 100644 --- a/include/dbscan.h +++ b/include/dbscan.h @@ -1,6 +1,7 @@ #ifndef DBSCAN_H #define DBSCAN_H +#include #include #include diff --git a/main b/main deleted file mode 100755 index 27b67cd25ecb5227558d0706d31fa0379f84f8c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169312 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 ABLDyZ From c424e642d64cd6e24985a46f51f213be46921564 Mon Sep 17 00:00:00 2001 From: Alejandro Marrero Date: Fri, 1 Apr 2022 14:46:46 +0100 Subject: [PATCH 05/23] Create c-cpp.yml --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 0000000..19c9d58 --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From 695d59dfdf5bb101fde7fb27d52a4831ebc277af Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 15:56:06 +0200 Subject: [PATCH 06/23] =?UTF-8?q?=E2=9C=A8=20Reduces=20complexity=20with?= =?UTF-8?q?=20only=202dims?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/c-cpp.yml | 17 +- benchmark_hepta.dat | 424 ++++++++++++++++++------------------ example/simpleExample.cpp | 8 +- include/dbscan.h | 17 +- 4 files changed, 230 insertions(+), 236 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 19c9d58..62cd36c 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -13,11 +13,12 @@ jobs: steps: - uses: actions/checkout@v3 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck + - uses: egor-tensin/setup-gcc@v1 + with: + version: 10 + platform: x64 + - name: Configure + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release + - name: Build + run: cmake --build ${{github.workspace}}/build --config Release --target all -- -j 14 + \ No newline at end of file diff --git a/benchmark_hepta.dat b/benchmark_hepta.dat index 4216260..8cd4a76 100644 --- a/benchmark_hepta.dat +++ b/benchmark_hepta.dat @@ -1,213 +1,213 @@ 212 --0.063274 0.027734 0.022683 1 --0.000731 0.048211 0.069198 1 --0.060767 -0.00908 0.053085 1 -0.013252 -0.011876 0.055324 1 --0.054508 -0.003813 0.001738 1 -0.02418 0.068275 0.033462 1 --0.029308 0.059849 -0.06326 1 --0.016453 0.013881 -0.013236 1 --0.042361 -0.059942 -0.026487 1 --0.01631 -0.036612 0.047928 1 -0.03536 -0.04495 0.041474 1 --0.000287 -0.049496 -0.06343 1 --0.065931 -0.005381 -0.064899 1 -0.009049 0.027976 0.01198 1 --0.005335 0.062592 -0.057507 1 --0.004175 0.064646 0.040856 1 -0.091024 -0.031446 -0.014774 1 --0.077068 -0.035324 -0.03906 1 -0.05515 -0.007045 0.078495 1 --0.033779 0.049066 0.026958 1 -0.044954 -0.033716 0.011894 1 -0.008785 0.016895 -0.09079 1 --0.061655 -0.023085 0.007996 1 --0.051274 0.054634 0.032257 1 -0.04421 -0.062217 -0.018733 1 --0.003343 0.069586 0.069452 1 --0.064487 0.012217 0.040873 1 -0.042168 -0.009972 0.047962 1 --0.061495 0.059835 0.025843 1 -0.071795 -0.01526 -0.023346 1 -0.058733 -0.029135 -0.011721 1 -0.078178 -0.014786 -0.00032 1 -2.418463 0.490127 0.033581 2 -2.805184 0.769746 -0.557435 2 -2.983722 -0.983118 -0.165216 2 -3.055291 -0.477796 0.370524 2 -3.015527 -0.666039 0.126169 2 -2.449981 0.175666 -0.531892 2 -3.199806 0.201051 0.58676 2 -3.266405 0.012518 -0.761892 2 -3.74771 -0.41696 0.148884 2 -3.411849 0.516665 -0.702665 2 -3.733854 0.184758 0.482416 2 -3.59214 -0.371411 -0.673235 2 -3.59351 0.125884 0.277346 2 -2.387269 0.784515 -0.011033 2 -3.423791 -0.039296 0.066654 2 -2.425059 -0.206822 -0.263965 2 -2.407337 -0.015134 0.097093 2 -2.923991 -0.262388 -0.672982 2 -3.188203 -0.476377 0.051427 2 -2.377023 0.498033 -0.382225 2 -2.610067 0.787375 0.046041 2 -2.918826 -0.8296 -0.198249 2 -2.932853 0.719728 -0.347704 2 -3.47194 0.322667 0.25302 2 -3.266172 0.207763 0.078446 2 -2.916963 -0.636281 -0.459655 2 -3.020822 -0.491739 0.382338 2 -2.844004 -0.078753 -0.660588 2 -2.826876 -0.241459 -0.143806 2 -2.771511 0.362751 -0.669945 2 --2.69712 0.342837 0.296855 3 --2.57583 -0.752408 -0.225828 3 --3.308062 0.919403 -0.091698 3 --3.970394 -0.017968 0.097194 3 --3.332026 -0.22133 -0.410873 3 --2.679173 0.521163 0.033068 3 --2.186732 -0.536953 -0.08933 3 --3.013009 -0.082401 -0.750346 3 --3.464085 0.458797 -0.745681 3 --2.632916 0.683901 -0.153258 3 --3.315788 0.017903 0.703027 3 --2.833584 -0.684569 0.298511 3 --2.722148 -0.502344 0.245003 3 --2.608905 0.443179 0.447541 3 --2.853364 -0.788934 -0.276868 3 --2.809655 -0.092462 0.719525 3 --3.538035 0.777137 0.091226 3 --2.457811 -0.601538 0.548791 3 --2.762541 -0.540911 0.251193 3 --2.929594 -0.162338 0.427959 3 --3.054864 -0.220749 0.858853 3 --3.632051 -0.045369 0.497112 3 --3.595796 -0.25031 -0.26069 3 --2.285053 0.111547 0.652847 3 --2.664311 -0.035719 0.357768 3 --3.163578 0.286805 -0.843201 3 --2.599157 0.438496 0.094013 3 --3.381994 0.308228 -0.689706 3 --3.961031 -0.111044 0.022821 3 --2.827045 -0.074139 0.54136 3 -0.498135 2.895371 0.786843 4 -0.218436 3.067538 0.030236 4 -0.135451 2.12925 0.320246 4 -0.420118 3.055572 0.230617 4 -0.659865 3.446317 -0.101455 4 -0.619487 3.285343 0.278274 4 --0.294208 3.296888 -0.174357 4 --0.362217 2.657112 0.01996 4 --0.561919 3.334167 0.068536 4 -0.186843 3.706688 -0.259004 4 -0.450086 2.844335 0.073905 4 --0.047549 3.634562 0.613045 4 -0.432449 3.774495 0.096256 4 -0.444504 3.491508 -0.745843 4 --0.116409 2.618886 0.576378 4 --0.601582 3.548497 0.101766 4 -0.268449 3.662073 -0.103739 4 --0.007967 2.91813 0.390422 4 --0.811876 2.976918 -0.40471 4 --0.003684 2.460306 0.323449 4 -0.27221 2.287469 -0.243128 4 --0.003839 3.107724 -0.876719 4 -0.175357 3.715249 0.344842 4 --0.350178 2.515348 0.695052 4 -0.016665 2.986915 -0.265349 4 -0.394178 2.772903 0.583035 4 -0.715985 3.467443 -0.171137 4 -0.28994 2.60696 0.767379 4 -0.854454 2.895231 -0.335877 4 -0.308424 3.293211 -0.383773 4 --0.154151 -2.382802 -0.552876 5 -0.042376 -3.013402 0.26318 5 -0.76406 -2.974825 0.304909 5 -0.273431 -3.549045 0.602433 5 -0.109072 -2.872739 -0.972276 5 --0.609027 -2.316553 0.05604 5 -0.563714 -2.668933 0.272222 5 -0.053112 -3.69483 -0.446254 5 -0.374246 -3.881493 -0.178669 5 --0.25541 -2.573785 -0.369218 5 --0.05833 -3.539877 0.156878 5 -0.436804 -2.849058 -0.705822 5 --0.185927 -2.83419 -0.871306 5 --0.15729 -3.035242 -0.447355 5 --0.253287 -2.355499 0.53801 5 -0.856338 -2.928918 -0.105247 5 --0.448767 -2.892567 0.036684 5 --0.763126 -3.121529 0.012815 5 -0.50729 -3.69845 -0.126832 5 --0.262387 -2.7936 0.893868 5 -0.638189 -2.885896 -0.535134 5 --0.715655 -3.174318 -0.415442 5 --0.148243 -2.348742 -0.198939 5 --0.436461 -3.189614 -0.874082 5 --0.015747 -3.601469 0.678772 5 --0.380327 -2.120669 -0.201018 5 --0.078679 -2.969195 -0.085163 5 -0.725907 -2.642703 -0.392598 5 --0.118512 -2.391662 -0.116857 5 -0.378156 -3.742474 0.42604 5 --0.646687 -0.257803 2.879026 6 -0.862612 -0.257097 3.339622 6 -0.58395 0.25262 3.164447 6 --0.106313 0.539686 3.36243 6 --0.447773 -0.165269 2.395462 6 -0.278688 -0.67851 3.019065 6 --0.499959 -0.102398 2.918835 6 -0.628733 -0.136098 2.961669 6 --0.550777 0.820583 2.888145 6 -0.280057 -0.332023 2.280202 6 --0.68149 -0.388565 2.852309 6 --0.150402 0.774676 3.236697 6 --0.175775 0.816718 2.810907 6 -0.40849 -0.752991 2.708342 6 --0.687687 0.5331 2.864252 6 -0.187892 0.099277 3.3971 6 -0.40274 0.309218 2.184721 6 --0.333692 0.726125 2.755337 6 --0.073884 0.856673 3.449364 6 -0.074276 -0.44986 2.289555 6 --0.234023 0.508787 2.627695 6 -0.33853 -0.722352 2.402052 6 -0.777033 0.217745 2.671151 6 -0.093523 0.595698 3.532532 6 -0.215945 -0.323846 2.195408 6 --0.031152 0.385966 3.106696 6 -0.26075 0.391448 2.176698 6 --0.542543 0.386463 2.917456 6 --0.306005 -0.915958 2.884296 6 --0.114414 0.026251 3.899389 6 --0.749873 0.616942 -2.862605 7 --0.108157 -0.083104 -3.909294 7 --0.410898 0.467216 -3.64399 7 -0.662499 -0.378195 -2.900845 7 --0.057589 0.548771 -3.072026 7 -0.64518 -0.276585 -2.877792 7 -0.257191 0.114881 -2.929682 7 --0.169119 0.400328 -2.853299 7 -0.228327 -0.513736 -3.600658 7 --0.512238 0.372109 -3.357134 7 --0.510091 -0.617806 -3.543896 7 --0.001328 0.275274 -2.367165 7 --0.086874 0.138084 -3.152736 7 --0.558094 -0.138533 -2.731829 7 -0.640575 -0.52869 -2.882579 7 -0.033866 0.301424 -2.949164 7 --0.530334 0.571733 -3.122279 7 -0.488731 0.68226 -3.026392 7 --0.320178 -0.530404 -2.430535 7 -0.143306 0.578726 -3.657507 7 --0.36578 -0.491918 -2.483666 7 -0.660425 -0.259537 -3.671958 7 -0.647696 0.44422 -2.807808 7 --0.110876 0.163359 -3.038903 7 --0.694187 0.258777 -2.411717 7 -0.175738 -0.053478 -2.733752 7 -0.396046 -0.858377 -3.126866 7 --0.406362 -0.334541 -2.885598 7 --0.299275 0.071281 -3.642585 7 --0.506192 0.433538 -2.608597 7 +-0.063274 0.027734 1 +-0.000731 0.048211 1 +-0.060767 -0.00908 1 +0.013252 -0.011876 1 +-0.054508 -0.003813 1 +0.02418 0.068275 1 +-0.029308 0.059849 1 +-0.016453 0.013881 1 +-0.042361 -0.059942 1 +-0.01631 -0.036612 1 +0.03536 -0.04495 1 +-0.000287 -0.049496 1 +-0.065931 -0.005381 1 +0.009049 0.027976 1 +-0.005335 0.062592 1 +-0.004175 0.064646 1 +0.091024 -0.031446 1 +-0.077068 -0.035324 1 +0.05515 -0.007045 1 +-0.033779 0.049066 1 +0.044954 -0.033716 1 +0.008785 0.016895 1 +-0.061655 -0.023085 1 +-0.051274 0.054634 1 +0.04421 -0.062217 1 +-0.003343 0.069586 1 +-0.064487 0.012217 1 +0.042168 -0.009972 1 +-0.061495 0.059835 1 +0.071795 -0.01526 1 +0.058733 -0.029135 1 +0.078178 -0.014786 1 +2.418463 0.490127 2 +2.805184 0.769746 2 +2.983722 -0.983118 2 +3.055291 -0.477796 2 +3.015527 -0.666039 2 +2.449981 0.175666 2 +3.199806 0.201051 2 +3.266405 0.012518 2 +3.74771 -0.41696 2 +3.411849 0.516665 2 +3.733854 0.184758 2 +3.59214 -0.371411 2 +3.59351 0.125884 2 +2.387269 0.784515 2 +3.423791 -0.039296 2 +2.425059 -0.206822 2 +2.407337 -0.015134 2 +2.923991 -0.262388 2 +3.188203 -0.476377 2 +2.377023 0.498033 2 +2.610067 0.787375 2 +2.918826 -0.8296 2 +2.932853 0.719728 2 +3.47194 0.322667 2 +3.266172 0.207763 2 +2.916963 -0.636281 2 +3.020822 -0.491739 2 +2.844004 -0.078753 2 +2.826876 -0.241459 2 +2.771511 0.362751 2 +-2.69712 0.342837 3 +-2.57583 -0.752408 3 +-3.308062 0.919403 3 +-3.970394 -0.017968 3 +-3.332026 -0.22133 3 +-2.679173 0.521163 3 +-2.186732 -0.536953 3 +-3.013009 -0.082401 3 +-3.464085 0.458797 3 +-2.632916 0.683901 3 +-3.315788 0.017903 3 +-2.833584 -0.684569 3 +-2.722148 -0.502344 3 +-2.608905 0.443179 3 +-2.853364 -0.788934 3 +-2.809655 -0.092462 3 +-3.538035 0.777137 3 +-2.457811 -0.601538 3 +-2.762541 -0.540911 3 +-2.929594 -0.162338 3 +-3.054864 -0.220749 3 +-3.632051 -0.045369 3 +-3.595796 -0.25031 3 +-2.285053 0.111547 3 +-2.664311 -0.035719 3 +-3.163578 0.286805 3 +-2.599157 0.438496 3 +-3.381994 0.308228 3 +-3.961031 -0.111044 3 +-2.827045 -0.074139 3 +2.895371 0.786843 4 +3.067538 0.030236 4 +2.12925 0.320246 4 +3.055572 0.230617 4 +3.446317 -0.101455 4 +3.285343 0.278274 4 +3.296888 -0.174357 4 +2.657112 0.01996 4 +3.334167 0.068536 4 +3.706688 -0.259004 4 +2.844335 0.073905 4 +3.634562 0.613045 4 +3.774495 0.096256 4 +3.491508 -0.745843 4 +2.618886 0.576378 4 +3.548497 0.101766 4 +3.662073 -0.103739 4 +2.91813 0.390422 4 +2.976918 -0.40471 4 +2.460306 0.323449 4 +2.287469 -0.243128 4 +3.107724 -0.876719 4 +3.715249 0.344842 4 +2.515348 0.695052 4 +2.986915 -0.265349 4 +2.772903 0.583035 4 +3.467443 -0.171137 4 +2.60696 0.767379 4 +2.895231 -0.335877 4 +3.293211 -0.383773 4 +-0.154151 -2.382802 5 +0.042376 -3.013402 5 +0.76406 -2.974825 5 +0.273431 -3.549045 5 +0.109072 -2.872739 5 +-0.609027 -2.316553 5 +0.563714 -2.668933 5 +0.053112 -3.69483 5 +0.374246 -3.881493 5 +-0.25541 -2.573785 5 +-0.05833 -3.539877 5 +0.436804 -2.849058 5 +-0.185927 -2.83419 5 +-0.15729 -3.035242 5 +-0.253287 -2.355499 5 +0.856338 -2.928918 5 +-0.448767 -2.892567 5 +-0.763126 -3.121529 5 +0.50729 -3.69845 5 +-0.262387 -2.7936 5 +0.638189 -2.885896 5 +-0.715655 -3.174318 5 +-0.148243 -2.348742 5 +-0.436461 -3.189614 5 +-0.015747 -3.601469 5 +-0.380327 -2.120669 5 +-0.078679 -2.969195 5 +0.725907 -2.642703 5 +-0.118512 -2.391662 5 +0.378156 -3.742474 5 +-0.646687 2.879026 6 +0.862612 3.339622 6 +0.58395 3.164447 6 +-0.106313 3.36243 6 +-0.447773 2.395462 6 +0.278688 3.019065 6 +-0.499959 2.918835 6 +0.628733 2.961669 6 +-0.550777 2.888145 6 +0.280057 2.280202 6 +-0.68149 2.852309 6 +-0.150402 3.236697 6 +-0.175775 2.810907 6 +0.40849 2.708342 6 +-0.687687 2.864252 6 +0.187892 3.3971 6 +0.40274 2.184721 6 +-0.333692 2.755337 6 +-0.073884 3.449364 6 +0.074276 2.289555 6 +-0.234023 2.627695 6 +0.33853 2.402052 6 +0.777033 2.671151 6 +0.093523 3.532532 6 +0.215945 2.195408 6 +-0.031152 3.106696 6 +0.26075 2.176698 6 +-0.542543 2.917456 6 +-0.306005 2.884296 6 +-0.114414 3.899389 6 +-0.749873 0.616942 7 +-0.108157 -0.083104 7 +-0.410898 0.467216 7 +0.662499 -0.378195 7 +-0.057589 0.548771 7 +0.64518 -0.276585 7 +0.257191 0.114881 7 +-0.169119 0.400328 7 +0.228327 -0.513736 7 +-0.512238 0.372109 7 +-0.510091 -0.617806 7 +-0.001328 0.275274 7 +-0.086874 0.138084 7 +-0.558094 -0.138533 7 +0.640575 -0.52869 7 +0.033866 0.301424 7 +-0.530334 0.571733 7 +0.488731 0.68226 7 +-0.320178 -0.530404 7 +0.143306 0.578726 7 +-0.36578 -0.491918 7 +0.660425 -0.259537 7 +0.647696 0.44422 7 +-0.110876 0.163359 7 +-0.694187 0.258777 7 +0.175738 -0.053478 7 +0.396046 -0.858377 7 +-0.406362 -0.334541 7 +-0.299275 0.071281 7 +-0.506192 0.433538 7 diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index bfe716f..ec86f64 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -14,13 +14,12 @@ std::vector readBenchmarkData() { stream = fopen("benchmark_hepta.dat", "ra"); unsigned int minpts, num_points, cluster, i = 0; - double epsilon; fscanf(stream, "%u\n", &num_points); Point *p = (Point *)calloc(num_points, sizeof(Point)); while (i < num_points) { - fscanf(stream, "%f,%f,%f,%d\n", &(p[i].x), &(p[i].y), &(p[i].z), &cluster); + fscanf(stream, "%f,%f,%d\n", &(p[i].x), &(p[i].y), &cluster); p[i].clusterID = UNCLASSIFIED; points.push_back(p[i]); ++i; @@ -34,11 +33,10 @@ std::vector readBenchmarkData() { void printResults(const vector &points, int num_points) { int i = 0; std::cout << "Number of Points: " << num_points << std::endl; - std::cout << "x\t\t\ty\t\t\tz\t\t\t" << std::endl; + std::cout << "x\t\t\ty\t\t\t" << std::endl; while (i < num_points) { - printf("%5.2lf %5.2lf %5.2lf: %d\n", points[i].x, points[i].y, points[i].z, - points[i].clusterID); + std::cout << points[i] << std::endl; ++i; } } diff --git a/include/dbscan.h b/include/dbscan.h index 588c53d..e8bb481 100644 --- a/include/dbscan.h +++ b/include/dbscan.h @@ -15,19 +15,16 @@ using namespace std; typedef struct Point_ { - float x, y, z; // X, Y, Z position + float x, y; // X, Y position int clusterID; // clustered ID - Point_(const float& _x, const float& _y, const float& _z, const int& _c) - : x(_x), y(_y), z(_z), clusterID(_c) {} + 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.z << ") - " - << p.clusterID; + return os << "(" << p.x << ", " << p.y << ") - " << p.clusterID; } } Point; -using coords = std::pair; - class DBSCAN { public: DBSCAN(const unsigned int& minPts, const float& eps, @@ -85,8 +82,7 @@ int DBSCAN::expandCluster(Point point, int clusterID) { ++iterSeeds) { m_points.at(*iterSeeds).clusterID = clusterID; if (m_points.at(*iterSeeds).x == point.x && - m_points.at(*iterSeeds).y == point.y && - m_points.at(*iterSeeds).z == point.z) { + m_points.at(*iterSeeds).y == point.y) { indexCorePoint = index; } ++index; @@ -148,8 +144,7 @@ vector DBSCAN::calculateCluster(Point point) { 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)) + - ((pointCore.z - pointTarget.z) * (pointCore.z - pointTarget.z)); + ((pointCore.y - pointTarget.y) * (pointCore.y - pointTarget.y)); } #endif // DBSCAN_H From d68f4fb51c9d65ce32f59a7c3be990dba7308cb6 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 15:57:00 +0200 Subject: [PATCH 07/23] =?UTF-8?q?=F0=9F=93=9D=20Updates=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3c03b33..45684a4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # DBSCAN +[![C/C++ CI](https://github.com/amarrerod/DBSCAN/actions/workflows/c-cpp.yml/badge.svg?branch=master)](https://github.com/amarrerod/DBSCAN/actions/workflows/c-cpp.yml) + DBSCAN (Density-Based Spatial Clustering of Applications with Noise) is a data clustering algorithm proposed by Martin Ester, Hans-Peter Kriegel, Jörg Sander and Xiaowei Xu in 1996. The algorithm had implemented with pseudocode described in [wiki](https://en.wikipedia.org/wiki/DBSCAN), but it is not optimised.   # Example From 4c16b9862877b3a997995f5f0c41e1a6a856e775 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Fri, 1 Apr 2022 19:00:27 +0100 Subject: [PATCH 08/23] =?UTF-8?q?=F0=9F=91=B7=20Working=20on=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cbb5c2..8ff6c61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.0.0) -project(dbscan LANGUAGES C CXX VERSION 0.1.0) +project(dbscan LANGUAGES C CXX VERSION 0.1.0 DESCRIPTION "DBSCAN algorithm") + set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) @@ -13,11 +14,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -lstdc++fs -O3 -ffast-math -W add_library(${PROJECT_NAME} include/dbscan.h) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} LINKER_LANGUAGE CXX) -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - PRIVATE src) - +set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 1) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER include/dbscan.h) -add_executable(example example/simpleExample.cpp) -target_link_libraries(example PRIVATE dbscan) \ No newline at end of file +include(GNUInstallDirs) +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIB_DIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) \ No newline at end of file From ddecebecdca40b2af93332bc028464710fc27721 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Sun, 3 Apr 2022 09:10:05 +0100 Subject: [PATCH 09/23] =?UTF-8?q?=F0=9F=9A=9A=20Moving=20stuff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 6 +- include/dbscan.h | 150 ---------------------------------------- include/dbscan/dbscan.h | 52 ++++++++++++++ lib/libdbscan.a | Bin 8 -> 188024 bytes src/dbscan/dbscan.cpp | 112 ++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+), 151 deletions(-) delete mode 100644 include/dbscan.h create mode 100644 include/dbscan/dbscan.h create mode 100644 src/dbscan/dbscan.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ff6c61..df5bcc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + $ + $ + PRIVATE src) include(GNUInstallDirs) install(TARGETS ${PROJECT_NAME} diff --git a/include/dbscan.h b/include/dbscan.h deleted file mode 100644 index e8bb481..0000000 --- a/include/dbscan.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef DBSCAN_H -#define DBSCAN_H - -#include -#include -#include - -#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& points); - ~DBSCAN() = default; - - int run(); - vector 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& getPoints() { return m_points; } - - private: - unsigned int m_minPoints; - float m_epsilon; - unsigned int m_pointSize; - vector m_points; -}; - -DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, - const vector& points) - : m_minPoints(minPts), m_epsilon(eps) { - m_pointSize = points.size(); - m_points = points; -} - -int DBSCAN::run() { - int clusterID = 1; - typename vector::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 clusterSeeds = calculateCluster(point); - - if (clusterSeeds.size() < m_minPoints) { - point.clusterID = NOISE; - return FAILURE; - } else { - int index = 0, indexCorePoint = 0; - vector::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::size_type i = 0, n = clusterSeeds.size(); i < n; ++i) { - vector clusterNeighors = - calculateCluster(m_points.at(clusterSeeds[i])); - - if (clusterNeighors.size() >= m_minPoints) { - vector::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 - */ - -vector DBSCAN::calculateCluster(Point point) { - int index = 0; - typename vector::iterator iter; - vector 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)); -} - -#endif // DBSCAN_H diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h new file mode 100644 index 0000000..e5d05e2 --- /dev/null +++ b/include/dbscan/dbscan.h @@ -0,0 +1,52 @@ +#ifndef DBSCAN_H +#define DBSCAN_H + +#include +#include +#include + +#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& points); + ~DBSCAN() = default; + + int run(); + vector 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& getPoints() { return m_points; } + + private: + unsigned int m_minPoints; + float m_epsilon; + unsigned int m_pointSize; + vector m_points; +}; + +#endif // DBSCAN_H diff --git a/lib/libdbscan.a b/lib/libdbscan.a index 8b277f0dd5dcdcb9c4b6c0b7a32153664f111266..146a717ce668a32b9482543489f0376a2031a4f5 100644 GIT binary patch literal 188024 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 literal 8 PcmY$iNi0gvu;T&%3Vs4a diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp new file mode 100644 index 0000000..fab32d1 --- /dev/null +++ b/src/dbscan/dbscan.cpp @@ -0,0 +1,112 @@ +/** + * @file dbscan.cpp + * @author Alejandro Marrero (amarrerd@ull.edu.es) + * @brief + * @version 0.1 + * @date 2022-04-03 + * + * @copyright Copyright (c) 2022 + * + */ + +#include + +DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, + const vector& points) + : m_minPoints(minPts), m_epsilon(eps) { + m_pointSize = points.size(); + m_points = points; +} + +int DBSCAN::run() { + int clusterID = 1; + typename vector::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 clusterSeeds = calculateCluster(point); + + if (clusterSeeds.size() < m_minPoints) { + point.clusterID = NOISE; + return FAILURE; + } else { + int index = 0, indexCorePoint = 0; + vector::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::size_type i = 0, n = clusterSeeds.size(); i < n; + ++i) { + vector clusterNeighors = + calculateCluster(m_points.at(clusterSeeds[i])); + + if (clusterNeighors.size() >= m_minPoints) { + vector::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 + */ + +vector DBSCAN::calculateCluster(Point point) { + int index = 0; + typename vector::iterator iter; + vector 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)); +} \ No newline at end of file From 80170550521decd33d786b8c42d2b19ba5a8e4fe Mon Sep 17 00:00:00 2001 From: amarrerod Date: Mon, 4 Apr 2022 16:20:46 +0200 Subject: [PATCH 10/23] =?UTF-8?q?=F0=9F=92=9A=20Fixing=20Cmake=20installat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + CMakeLists.txt | 7 +------ lib/libdbscan.a | Bin 188024 -> 0 bytes 3 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 lib/libdbscan.a diff --git a/.gitignore b/.gitignore index d5697ec..59a2f43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ bin/ +lib/ diff --git a/CMakeLists.txt b/CMakeLists.txt index df5bcc0..46914f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ 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/dbscan.h src/dbscan/dbscan.cpp) +add_library(${PROJECT_NAME} STATIC 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) @@ -21,8 +21,3 @@ target_include_directories(${PROJECT_NAME} PUBLIC $ PRIVATE src) -include(GNUInstallDirs) -install(TARGETS ${PROJECT_NAME} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIB_DIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) \ No newline at end of file diff --git a/lib/libdbscan.a b/lib/libdbscan.a deleted file mode 100644 index 146a717ce668a32b9482543489f0376a2031a4f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188024 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 From ca690b5f23fab412c72199606f2514f371ae2039 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Mon, 4 Apr 2022 16:57:20 +0200 Subject: [PATCH 11/23] =?UTF-8?q?=F0=9F=9A=A7=20Working=20on=20the=20lib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46914f4..07943df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,8 @@ 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} STATIC include/dbscan/dbscan.h src/dbscan/dbscan.cpp) +add_library(${PROJECT_NAME} src/dbscan/dbscan.cpp) +target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) 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) From 76c74c206fd1b95882ee44524bbef19e268088ba Mon Sep 17 00:00:00 2001 From: amarrerod Date: Tue, 5 Apr 2022 15:45:15 +0200 Subject: [PATCH 12/23] =?UTF-8?q?=F0=9F=9A=A7=20Working=20on=20shared=20li?= =?UTF-8?q?b?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 21 ++++++++++++++------- dbscan.pc.in | 12 ++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 dbscan.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 07943df..643984f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.0.0) -project(dbscan LANGUAGES C CXX VERSION 0.1.0 DESCRIPTION "DBSCAN algorithm") +project(dbscan LANGUAGES C CXX VERSION 1.0.0 DESCRIPTION "DBSCAN algorithm") +include(GNUInstallDirs) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) @@ -9,16 +10,22 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE ON) 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") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -lstdc++fs -O3 -ffast-math -Wall -march=native -mtune=native -fPIC") -add_library(${PROJECT_NAME} src/dbscan/dbscan.cpp) +add_library(${PROJECT_NAME} SHARED src/dbscan/dbscan.cpp) target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) 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 - $ - $ - PRIVATE src) +target_include_directories(${PROJECT_NAME} PRIVATE include) +target_include_directories(${PROJECT_NAME} PRIVATE src) +configure_file(dbscan.pc.in dbscan.pc @ONLY) +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) +install(FILES ${CMAKE_BINARY_DIR}/dbscan.pc + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig + ) diff --git a/dbscan.pc.in b/dbscan.pc.in new file mode 100644 index 0000000..0a0f329 --- /dev/null +++ b/dbscan.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: @PROJECT_NAME@ +Description: @PROJECT_DESCRIPTION@ +Version: @PROJECT_VERSION@ + +Requires: +Libs: -L${libdir} -lmylib +Cflags: -I${includedir} \ No newline at end of file From 6f50381c1a7270dcd16803508632444b50f1cfca Mon Sep 17 00:00:00 2001 From: Alejandro Marrero Date: Tue, 5 Apr 2022 15:32:43 +0100 Subject: [PATCH 13/23] Update dbscan.pc.in --- dbscan.pc.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbscan.pc.in b/dbscan.pc.in index 0a0f329..6f8813b 100644 --- a/dbscan.pc.in +++ b/dbscan.pc.in @@ -8,5 +8,5 @@ Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Requires: -Libs: -L${libdir} -lmylib -Cflags: -I${includedir} \ No newline at end of file +Libs: -L${libdir} -ldbscan +Cflags: -I${includedir} From c38c27c0790ff1418dd94e4ad1e963b2d24a5728 Mon Sep 17 00:00:00 2001 From: Alejandro Marrero Date: Tue, 5 Apr 2022 15:49:31 +0100 Subject: [PATCH 14/23] =?UTF-8?q?=F0=9F=90=9B=20Fix=20an=20installation=20?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 643984f..7e81c5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,11 +21,15 @@ set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER include/dbscan.h) target_include_directories(${PROJECT_NAME} PRIVATE include) target_include_directories(${PROJECT_NAME} PRIVATE src) configure_file(dbscan.pc.in dbscan.pc @ONLY) -install(TARGETS ${PROJECT_NAME} +install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install(FILES ${CMAKE_BINARY_DIR}/dbscan.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig ) +install(EXPORT ${PROJECT_NAME}Config DESTINATION share/${PROJECT_NAME}/cmake) +export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}.cmake) \ No newline at end of file From a29cfe6358b4e6c045e6b3f768cb77049686b2be Mon Sep 17 00:00:00 2001 From: Alejandro Marrero Date: Tue, 5 Apr 2022 16:10:01 +0100 Subject: [PATCH 15/23] =?UTF-8?q?=F0=9F=92=9A=20Working=20on=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 9 +++++---- src/dbscan/dbscan.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e81c5d..e0f7009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,12 +14,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -lstdc++fs -O3 -ffast-math -W add_library(${PROJECT_NAME} SHARED src/dbscan/dbscan.cpp) -target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) 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} PRIVATE include) -target_include_directories(${PROJECT_NAME} PRIVATE src) +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + PRIVATE src) + configure_file(dbscan.pc.in dbscan.pc @ONLY) install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index fab32d1..9fdef4a 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -9,7 +9,7 @@ * */ -#include +#include "dbscan.h" DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, const vector& points) From bf93bb048dfb787f02bd06b95c889274b5d02cb8 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Wed, 6 Apr 2022 16:04:48 +0200 Subject: [PATCH 16/23] =?UTF-8?q?=E2=9C=A8=20Introduces=20cluster=20counte?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/dbscan/dbscan.h | 18 ++++++++++-------- src/dbscan/dbscan.cpp | 37 +++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h index e5d05e2..0fe829b 100644 --- a/include/dbscan/dbscan.h +++ b/include/dbscan/dbscan.h @@ -37,16 +37,18 @@ class DBSCAN { 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& getPoints() { return m_points; } + int getTotalPointSize() { return pointSize; } + int getMinimumClusterSize() { return minPoints; } + int getEpsilonSize() { return eps; } + const vector& getPoints() { return points; } + const unsigned int getNClusters() const { return nClusters; } private: - unsigned int m_minPoints; - float m_epsilon; - unsigned int m_pointSize; - vector m_points; + unsigned int nClusters; + unsigned int minPoints; + float eps; + unsigned int pointSize; + vector points; }; #endif // DBSCAN_H diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index 9fdef4a..24818a4 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -12,29 +12,30 @@ #include "dbscan.h" DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, - const vector& points) - : m_minPoints(minPts), m_epsilon(eps) { - m_pointSize = points.size(); - m_points = points; + const vector& p) + : minPoints(minPts), eps(eps) { + pointSize = points.size(); + this->points = p; } int DBSCAN::run() { int clusterID = 1; typename vector::iterator iter; - for (iter = m_points.begin(); iter != m_points.end(); ++iter) { + for (iter = points.begin(); iter != points.end(); ++iter) { if (iter->clusterID == UNCLASSIFIED) { if (expandCluster(*iter, clusterID) != FAILURE) { clusterID += 1; } } } - return 0; + nClusters = clusterID; + return nClusters; } int DBSCAN::expandCluster(Point point, int clusterID) { vector clusterSeeds = calculateCluster(point); - if (clusterSeeds.size() < m_minPoints) { + if (clusterSeeds.size() < minPoints) { point.clusterID = NOISE; return FAILURE; } else { @@ -42,9 +43,9 @@ int DBSCAN::expandCluster(Point point, int clusterID) { vector::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) { + points.at(*iterSeeds).clusterID = clusterID; + if (points.at(*iterSeeds).x == point.x && + points.at(*iterSeeds).y == point.y) { indexCorePoint = index; } ++index; @@ -54,20 +55,20 @@ int DBSCAN::expandCluster(Point point, int clusterID) { for (vector::size_type i = 0, n = clusterSeeds.size(); i < n; ++i) { vector clusterNeighors = - calculateCluster(m_points.at(clusterSeeds[i])); + calculateCluster(points.at(clusterSeeds[i])); - if (clusterNeighors.size() >= m_minPoints) { + if (clusterNeighors.size() >= minPoints) { vector::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 == + if (points.at(*iterNeighors).clusterID == UNCLASSIFIED || + points.at(*iterNeighors).clusterID == NOISE) { + if (points.at(*iterNeighors).clusterID == UNCLASSIFIED) { clusterSeeds.push_back(*iterNeighors); n = clusterSeeds.size(); } - m_points.at(*iterNeighors).clusterID = clusterID; + points.at(*iterNeighors).clusterID = clusterID; } } } @@ -88,8 +89,8 @@ vector DBSCAN::calculateCluster(Point point) { int index = 0; typename vector::iterator iter; vector clusterIndex; - for (iter = m_points.begin(); iter != m_points.end(); ++iter) { - if (calculateDistance(point, *iter) <= m_epsilon) { + for (iter = points.begin(); iter != points.end(); ++iter) { + if (calculateDistance(point, *iter) <= eps) { clusterIndex.push_back(index); } index++; From 59b93d056b583eedaac584bea307d487084ac05a Mon Sep 17 00:00:00 2001 From: amarrerod Date: Wed, 6 Apr 2022 16:42:31 +0200 Subject: [PATCH 17/23] =?UTF-8?q?=F0=9F=A7=90=20Includes=20data=20samples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 21 + CMakeLists.txt | 6 +- benchmark_hepta.dat | 213 --- data/2d_10c.data | 2991 +++++++++++++++++++++++++++++++++++++ data/2d_4c.data | 2991 +++++++++++++++++++++++++++++++++++++ example/simpleExample.cpp | 91 +- include/dbscan/dbscan.h | 18 +- src/dbscan/dbscan.cpp | 39 +- 8 files changed, 6084 insertions(+), 286 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 benchmark_hepta.dat create mode 100644 data/2d_10c.data create mode 100644 data/2d_4c.data diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..69decad --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "files.associations": { + "makefile_algorithm": "makefile", + "makefile_migration_selector": "makefile", + "makefile_problem": "makefile", + "makefile_migration_selectors": "makefile", + "makefile_mutation": "makefile", + "makefile_crossover": "makefile", + "*.am": "makefile", + "makefile_score": "makefile", + "makefile_exchange_selector": "makefile", + "makefile_init_pop_island_loader": "makefile", + "makefile_localSearch": "makefile", + "makefile_multiobjectivization": "makefile", + "makefile_decomposition": "makefile", + "makefile_output_printer": "makefile", + "makefile_migration_topology": "makefile", + "*.tcc": "cpp", + "fstream": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e0f7009..f9efb49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,4 +33,8 @@ install(FILES ${CMAKE_BINARY_DIR}/dbscan.pc ) install(EXPORT ${PROJECT_NAME}Config DESTINATION share/${PROJECT_NAME}/cmake) -export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}.cmake) \ No newline at end of file +export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}.cmake) + + +add_executable(example example/simpleExample.cpp) +target_link_libraries(example PRIVATE ${PROJECT_NAME}) \ No newline at end of file diff --git a/benchmark_hepta.dat b/benchmark_hepta.dat deleted file mode 100644 index 8cd4a76..0000000 --- a/benchmark_hepta.dat +++ /dev/null @@ -1,213 +0,0 @@ -212 --0.063274 0.027734 1 --0.000731 0.048211 1 --0.060767 -0.00908 1 -0.013252 -0.011876 1 --0.054508 -0.003813 1 -0.02418 0.068275 1 --0.029308 0.059849 1 --0.016453 0.013881 1 --0.042361 -0.059942 1 --0.01631 -0.036612 1 -0.03536 -0.04495 1 --0.000287 -0.049496 1 --0.065931 -0.005381 1 -0.009049 0.027976 1 --0.005335 0.062592 1 --0.004175 0.064646 1 -0.091024 -0.031446 1 --0.077068 -0.035324 1 -0.05515 -0.007045 1 --0.033779 0.049066 1 -0.044954 -0.033716 1 -0.008785 0.016895 1 --0.061655 -0.023085 1 --0.051274 0.054634 1 -0.04421 -0.062217 1 --0.003343 0.069586 1 --0.064487 0.012217 1 -0.042168 -0.009972 1 --0.061495 0.059835 1 -0.071795 -0.01526 1 -0.058733 -0.029135 1 -0.078178 -0.014786 1 -2.418463 0.490127 2 -2.805184 0.769746 2 -2.983722 -0.983118 2 -3.055291 -0.477796 2 -3.015527 -0.666039 2 -2.449981 0.175666 2 -3.199806 0.201051 2 -3.266405 0.012518 2 -3.74771 -0.41696 2 -3.411849 0.516665 2 -3.733854 0.184758 2 -3.59214 -0.371411 2 -3.59351 0.125884 2 -2.387269 0.784515 2 -3.423791 -0.039296 2 -2.425059 -0.206822 2 -2.407337 -0.015134 2 -2.923991 -0.262388 2 -3.188203 -0.476377 2 -2.377023 0.498033 2 -2.610067 0.787375 2 -2.918826 -0.8296 2 -2.932853 0.719728 2 -3.47194 0.322667 2 -3.266172 0.207763 2 -2.916963 -0.636281 2 -3.020822 -0.491739 2 -2.844004 -0.078753 2 -2.826876 -0.241459 2 -2.771511 0.362751 2 --2.69712 0.342837 3 --2.57583 -0.752408 3 --3.308062 0.919403 3 --3.970394 -0.017968 3 --3.332026 -0.22133 3 --2.679173 0.521163 3 --2.186732 -0.536953 3 --3.013009 -0.082401 3 --3.464085 0.458797 3 --2.632916 0.683901 3 --3.315788 0.017903 3 --2.833584 -0.684569 3 --2.722148 -0.502344 3 --2.608905 0.443179 3 --2.853364 -0.788934 3 --2.809655 -0.092462 3 --3.538035 0.777137 3 --2.457811 -0.601538 3 --2.762541 -0.540911 3 --2.929594 -0.162338 3 --3.054864 -0.220749 3 --3.632051 -0.045369 3 --3.595796 -0.25031 3 --2.285053 0.111547 3 --2.664311 -0.035719 3 --3.163578 0.286805 3 --2.599157 0.438496 3 --3.381994 0.308228 3 --3.961031 -0.111044 3 --2.827045 -0.074139 3 -2.895371 0.786843 4 -3.067538 0.030236 4 -2.12925 0.320246 4 -3.055572 0.230617 4 -3.446317 -0.101455 4 -3.285343 0.278274 4 -3.296888 -0.174357 4 -2.657112 0.01996 4 -3.334167 0.068536 4 -3.706688 -0.259004 4 -2.844335 0.073905 4 -3.634562 0.613045 4 -3.774495 0.096256 4 -3.491508 -0.745843 4 -2.618886 0.576378 4 -3.548497 0.101766 4 -3.662073 -0.103739 4 -2.91813 0.390422 4 -2.976918 -0.40471 4 -2.460306 0.323449 4 -2.287469 -0.243128 4 -3.107724 -0.876719 4 -3.715249 0.344842 4 -2.515348 0.695052 4 -2.986915 -0.265349 4 -2.772903 0.583035 4 -3.467443 -0.171137 4 -2.60696 0.767379 4 -2.895231 -0.335877 4 -3.293211 -0.383773 4 --0.154151 -2.382802 5 -0.042376 -3.013402 5 -0.76406 -2.974825 5 -0.273431 -3.549045 5 -0.109072 -2.872739 5 --0.609027 -2.316553 5 -0.563714 -2.668933 5 -0.053112 -3.69483 5 -0.374246 -3.881493 5 --0.25541 -2.573785 5 --0.05833 -3.539877 5 -0.436804 -2.849058 5 --0.185927 -2.83419 5 --0.15729 -3.035242 5 --0.253287 -2.355499 5 -0.856338 -2.928918 5 --0.448767 -2.892567 5 --0.763126 -3.121529 5 -0.50729 -3.69845 5 --0.262387 -2.7936 5 -0.638189 -2.885896 5 --0.715655 -3.174318 5 --0.148243 -2.348742 5 --0.436461 -3.189614 5 --0.015747 -3.601469 5 --0.380327 -2.120669 5 --0.078679 -2.969195 5 -0.725907 -2.642703 5 --0.118512 -2.391662 5 -0.378156 -3.742474 5 --0.646687 2.879026 6 -0.862612 3.339622 6 -0.58395 3.164447 6 --0.106313 3.36243 6 --0.447773 2.395462 6 -0.278688 3.019065 6 --0.499959 2.918835 6 -0.628733 2.961669 6 --0.550777 2.888145 6 -0.280057 2.280202 6 --0.68149 2.852309 6 --0.150402 3.236697 6 --0.175775 2.810907 6 -0.40849 2.708342 6 --0.687687 2.864252 6 -0.187892 3.3971 6 -0.40274 2.184721 6 --0.333692 2.755337 6 --0.073884 3.449364 6 -0.074276 2.289555 6 --0.234023 2.627695 6 -0.33853 2.402052 6 -0.777033 2.671151 6 -0.093523 3.532532 6 -0.215945 2.195408 6 --0.031152 3.106696 6 -0.26075 2.176698 6 --0.542543 2.917456 6 --0.306005 2.884296 6 --0.114414 3.899389 6 --0.749873 0.616942 7 --0.108157 -0.083104 7 --0.410898 0.467216 7 -0.662499 -0.378195 7 --0.057589 0.548771 7 -0.64518 -0.276585 7 -0.257191 0.114881 7 --0.169119 0.400328 7 -0.228327 -0.513736 7 --0.512238 0.372109 7 --0.510091 -0.617806 7 --0.001328 0.275274 7 --0.086874 0.138084 7 --0.558094 -0.138533 7 -0.640575 -0.52869 7 -0.033866 0.301424 7 --0.530334 0.571733 7 -0.488731 0.68226 7 --0.320178 -0.530404 7 -0.143306 0.578726 7 --0.36578 -0.491918 7 -0.660425 -0.259537 7 -0.647696 0.44422 7 --0.110876 0.163359 7 --0.694187 0.258777 7 -0.175738 -0.053478 7 -0.396046 -0.858377 7 --0.406362 -0.334541 7 --0.299275 0.071281 7 --0.506192 0.433538 7 diff --git a/data/2d_10c.data b/data/2d_10c.data new file mode 100644 index 0000000..ad69d8a --- /dev/null +++ b/data/2d_10c.data @@ -0,0 +1,2991 @@ +2990 +1.00007 40.9378 0 +0.99736 41.1714 0 +0.134799 41.8113 0 +2.47585 41.6346 0 +-3.0587 41.3887 0 +0.73266 41.4888 0 +0.35745 41.8429 0 +0.157674 41.7513 0 +2.69103 41.8298 0 +0.536346 41.5344 0 +2.46873 41.4813 0 +-1.91946 40.8824 0 +3.44394 41.3349 0 +2.88157 41.1534 0 +-0.53933 41.4057 0 +-0.0276636 41.1127 0 +0.0933292 41.0051 0 +0.209173 41.7993 0 +-0.0668266 41.7829 0 +1.79969 42.3177 0 +0.510155 41.6298 0 +0.138588 41.1531 0 +-0.0175984 41.694 0 +0.618498 41.4093 0 +-2.63433 41.9534 0 +2.01141 41.222 0 +5.57577 41.5869 0 +1.40539 41.53 0 +3.55797 41.8688 0 +2.68052 41.3868 0 +2.95654 41.486 0 +-0.391807 41.2361 0 +4.00381 41.4221 0 +1.44796 41.0426 0 +0.201187 41.4562 0 +0.795719 41.6564 0 +0.502018 41.5292 0 +0.290078 41.6987 0 +1.19913 40.799 0 +-1.28096 41.1171 0 +0.030134 41.4093 0 +1.99597 41.7064 0 +3.11367 41.4872 0 +0.546399 41.5257 0 +-1.00433 41.3616 0 +1.22587 42.0243 0 +-0.202468 41.863 0 +-1.40362 40.9709 0 +0.977844 40.6544 0 +2.66858 41.613 0 +3.87692 41.5591 0 +2.62824 41.4168 0 +2.06543 41.3289 0 +-1.63482 41.3223 0 +2.00123 41.8628 0 +3.64504 42.0131 0 +-2.36311 41.4501 0 +2.6411 41.6433 0 +-2.92099 40.9228 0 +1.66685 41.3844 0 +1.35976 41.4936 0 +2.40343 42.0717 0 +-0.156466 41.3901 0 +-0.149501 41.3361 0 +2.31285 41.3771 0 +2.73428 41.6682 0 +0.703931 40.8069 0 +2.65785 41.2811 0 +4.18733 41.6706 0 +0.21038 41.3822 0 +-2.37222 41.5596 0 +2.14842 42.1958 0 +3.90696 41.487 0 +0.805582 40.9885 0 +2.88554 41.7446 0 +0.4224 41.6881 0 +4.28893 41.7292 0 +0.709065 41.6168 0 +-1.114 41.4017 0 +0.00767159 41.3293 0 +2.98833 41.0246 0 +-0.895292 41.5051 0 +3.71451 41.4277 0 +-0.34788 40.9151 0 +3.6333 41.5624 0 +3.86924 41.0564 0 +-0.228855 40.791 0 +3.10995 41.9408 0 +2.41484 41.1329 0 +3.09267 41.8441 0 +-1.40569 40.9844 0 +2.83167 41.5767 0 +-2.08925 41.8549 0 +-0.0413047 41.4111 0 +0.99321 41.2289 0 +5.49799 42.229 0 +4.56593 41.3131 0 +2.62767 41.2001 0 +1.86702 41.0572 0 +0.99447 40.9706 0 +1.35799 41.9985 0 +0.965753 41.2944 0 +5.09559 41.0741 0 +1.36247 41.1762 0 +1.69922 41.2959 0 +3.16355 41.7048 0 +5.25389 41.8303 0 +0.531934 41.5568 0 +3.28948 41.5843 0 +0.10212 41.6421 0 +-2.09836 41.0296 0 +1.1946 41.225 0 +0.0879961 41.7027 0 +-0.344577 41.9871 0 +-0.195498 41.2088 0 +2.2287 41.8828 0 +3.68595 41.7489 0 +2.78496 41.4375 0 +-1.03866 41.3832 0 +0.83488 40.8743 0 +1.10206 41.6165 0 +2.73045 42.2562 0 +1.85942 42.4662 0 +-2.90953 41.7232 0 +3.17061 41.78 0 +-1.28675 41.7713 0 +3.19275 41.3024 0 +2.44799 41.3377 0 +1.01221 41.3916 0 +2.86381 41.3201 0 +2.53895 41.8226 0 +0.652358 41.6833 0 +2.95625 41.2105 0 +2.05624 41.7799 0 +2.73907 41.5838 0 +0.19292 41.4039 0 +-1.90824 41.2266 0 +3.31292 41.8747 0 +-1.17188 41.499 0 +-1.19959 41.2945 0 +3.40639 41.4131 0 +-0.309029 41.7895 0 +2.29291 41.4736 0 +2.85405 41.4468 0 +0.906787 41.8417 0 +1.03301 41.6805 0 +2.7908 41.5484 0 +1.60142 41.0711 0 +3.07553 41.3319 0 +2.66801 41.3151 0 +1.57486 41.8305 0 +4.79379 42.3375 0 +0.683916 41.4464 0 +4.30425 41.5736 0 +-4.99684 41.4194 0 +0.407559 41.5083 0 +1.31942 41.2904 0 +-2.36349 41.9116 0 +4.31274 41.5094 0 +3.94453 41.3956 0 +46.3802 3.32142 1 +48.4628 3.09102 1 +46.1492 3.13285 1 +48.8009 2.98271 1 +46.13 3.22293 1 +48.8492 3.34834 1 +52.4008 2.66164 1 +45.6532 2.92506 1 +51.7098 3.12781 1 +49.3856 2.97191 1 +54.8398 3.09188 1 +51.3912 3.04305 1 +48.7477 2.88549 1 +47.3895 3.08509 1 +45.5833 3.42697 1 +52.1513 3.39225 1 +54.7523 3.18117 1 +47.9111 3.25294 1 +43.0308 3.16003 1 +52.5527 2.9644 1 +51.0376 3.12574 1 +39.7875 3.24483 1 +51.4247 3.02434 1 +54.9527 3.11502 1 +55.269 3.23374 1 +51.6444 3.05482 1 +52.7037 3.40248 1 +47.3123 3.11889 1 +39.9097 3.19928 1 +46.9546 3.21672 1 +54.7801 3.45151 1 +46.8688 3.30554 1 +50.7167 3.3011 1 +43.3099 3.13502 1 +49.0462 3.30432 1 +46.7978 3.14741 1 +39.1666 3.25898 1 +52.8303 3.2864 1 +43.5847 3.09874 1 +43.8313 3.26131 1 +47.0354 3.37726 1 +43.8303 3.00101 1 +49.2136 2.82901 1 +53.0703 3.25768 1 +51.5605 3.13051 1 +51.6565 3.03276 1 +54.6803 3.21761 1 +52.8974 3.11975 1 +49.8031 3.24972 1 +42.8679 3.06868 1 +49.5025 3.32133 1 +48.1066 3.25607 1 +47.5742 3.31038 1 +47.9516 3.0661 1 +45.6754 3.06525 1 +53.5019 3.2174 1 +56.9209 3.22393 1 +46.6076 3.35139 1 +45.2508 3.26453 1 +46.0753 3.31525 1 +49.2275 2.83737 1 +48.5368 3.22135 1 +51.592 3.38263 1 +52.079 3.253 1 +47.6605 3.08802 1 +52.4266 3.27257 1 +47.2102 3.07995 1 +51.7235 3.18778 1 +48.3572 3.40303 1 +50.4224 3.43891 1 +48.8457 3.17306 1 +52.3564 3.11401 1 +47.8073 3.37175 1 +45.2018 3.14158 1 +42.0126 3.31301 1 +47.1974 3.31478 1 +44.5805 3.09813 1 +47.9305 3.36138 1 +46.6296 3.05323 1 +51.7158 3.24734 1 +48.241 3.1586 1 +43.1457 3.10903 1 +53.5328 3.23527 1 +51.2686 3.05155 1 +52.6787 3.26477 1 +47.3229 3.25546 1 +50.6885 2.86228 1 +56.2172 3.26755 1 +52.5805 3.00891 1 +41.348 3.07628 1 +44.471 3.22271 1 +45.5043 3.17306 1 +52.9761 3.46274 1 +48.554 2.92317 1 +51.0304 3.05824 1 +55.3886 3.30659 1 +43.4255 3.25965 1 +51.9739 3.21241 1 +55.4508 3.21214 1 +48.8366 3.10592 1 +49.6574 3.43084 1 +48.2048 3.10344 1 +48.3355 3.2727 1 +51.1717 2.86299 1 +48.2203 3.30793 1 +45.1759 3.38008 1 +52.557 3.41086 1 +50.9924 2.98479 1 +49.8621 3.36127 1 +49.4336 3.19372 1 +48.7223 3.22935 1 +46.0376 3.53939 1 +51.1494 3.09522 1 +51.5877 3.53584 1 +54.3164 3.11213 1 +55.9106 3.02007 1 +51.3509 3.13694 1 +43.6607 3.15844 1 +50.3681 3.26108 1 +52.1362 3.10912 1 +45.1316 3.19939 1 +49.7714 2.84767 1 +45.1409 3.17001 1 +48.7293 3.39143 1 +55.6218 3.21222 1 +45.5667 3.1683 1 +50.5703 3.15988 1 +40.4224 3.12012 1 +46.9099 2.99161 1 +48.3726 2.85729 1 +46.6999 3.18883 1 +54.7413 3.47117 1 +47.3751 3.41105 1 +46.3036 3.33763 1 +45.4987 3.39797 1 +46.846 3.31468 1 +51.7251 3.43504 1 +45.2973 2.98033 1 +49.8244 3.21477 1 +47.2907 3.14332 1 +55.7865 3.11092 1 +47.5147 3.13047 1 +51.9523 3.20358 1 +53.7048 3.15458 1 +55.4817 2.9708 1 +47.0661 2.97888 1 +51.1148 3.04882 1 +55.7009 3.23165 1 +49.0926 3.0482 1 +49.2104 2.91954 1 +48.1315 3.1167 1 +43.8467 3.23859 1 +51.1212 3.10171 1 +48.241 3.27221 1 +48.7886 3.24547 1 +52.8058 3.31464 1 +54.6923 3.14978 1 +52.6505 3.483 1 +48.0059 3.01747 1 +43.2217 3.1709 1 +45.0373 3.21427 1 +50.8902 2.88582 1 +52.6745 3.24796 1 +49.427 3.25409 1 +47.8334 3.05406 1 +51.2101 3.08916 1 +46.2907 3.33246 1 +46.9564 3.06804 1 +48.7533 3.26383 1 +41.4118 3.22717 1 +57.1937 3.19327 1 +49.6908 3.18739 1 +48.1525 3.45527 1 +49.0834 2.90239 1 +45.3508 3.43377 1 +50.7461 3.29786 1 +48.4637 3.24045 1 +53.1632 3.14422 1 +44.9922 3.276 1 +52.8385 3.36757 1 +55.1785 2.78434 1 +52.6964 3.06467 1 +52.3657 3.04656 1 +52.695 2.99897 1 +47.426 2.99716 1 +45.3452 3.15207 1 +45.2563 2.95095 1 +44.9966 3.2906 1 +50.3892 3.10151 1 +42.8576 3.18715 1 +52.9982 3.05736 1 +50.0296 3.14682 1 +48.4227 3.12249 1 +45.8861 2.99218 1 +50.1186 3.39889 1 +42.2795 3.03919 1 +47.6122 2.89763 1 +44.026 3.10352 1 +49.8229 3.23362 1 +42.2478 3.25066 1 +51.3718 3.3026 1 +52.9524 3.12044 1 +51.347 3.30349 1 +49.2108 3.11055 1 +46.7317 3.08488 1 +38.398 3.33134 1 +49.4036 3.14496 1 +48.2214 3.32088 1 +38.0886 3.25209 1 +51.0267 2.86896 1 +40.9795 3.14887 1 +50.4044 3.33867 1 +48.3125 3.05636 1 +58.1081 3.45579 1 +48.4837 2.77284 1 +44.6498 3.00221 1 +48.0957 3.12917 1 +51.6222 3.31966 1 +50.5266 3.00372 1 +55.8049 3.2521 1 +44.3543 3.03395 1 +51.7189 3.2616 1 +53.1411 2.97594 1 +49.0658 3.16308 1 +43.6292 3.28213 1 +46.6628 3.07487 1 +49.0 3.25821 1 +51.1193 3.28436 1 +48.537 3.39792 1 +51.1833 3.16959 1 +50.7161 3.29627 1 +42.8636 3.07529 1 +49.4004 3.31495 1 +52.8072 3.51344 1 +44.2475 3.20818 1 +48.1885 3.19024 1 +48.0431 3.19459 1 +44.0315 3.38755 1 +45.6412 3.33712 1 +43.1365 3.05084 1 +47.0187 3.23208 1 +51.5345 3.38118 1 +57.173 3.32384 1 +44.6304 3.15582 1 +51.4211 3.42271 1 +47.8996 3.34198 1 +50.7063 3.26427 1 +51.7951 3.02464 1 +46.7669 3.3198 1 +55.0914 3.26275 1 +46.1609 3.08328 1 +44.2276 3.02086 1 +47.1665 3.08554 1 +49.9811 3.05603 1 +52.716 2.99968 1 +49.7461 3.31221 1 +50.5154 2.95242 1 +48.383 3.25018 1 +52.7087 2.79629 1 +44.2069 3.17022 1 +51.2816 3.11025 1 +46.0121 3.36816 1 +45.672 3.02456 1 +56.4607 3.18282 1 +39.4447 2.97675 1 +53.1977 3.4076 1 +48.1868 3.24323 1 +45.7023 3.11071 1 +46.9664 3.37809 1 +46.7991 3.28213 1 +53.2534 3.37943 1 +51.7157 3.14671 1 +43.9658 3.28225 1 +49.6987 3.5289 1 +47.755 3.08917 1 +48.7549 2.9592 1 +47.8815 3.30628 1 +47.6413 3.00383 1 +50.7445 3.20133 1 +51.4968 3.11166 1 +48.0207 3.00295 1 +51.4464 3.2879 1 +45.2989 3.0688 1 +41.2781 3.04708 1 +48.9077 3.32952 1 +51.8702 3.37652 1 +45.7139 2.99215 1 +46.0954 3.25909 1 +47.809 3.31064 1 +49.129 3.37745 1 +46.5891 3.21292 1 +45.8006 3.28586 1 +49.1638 3.41501 1 +51.1161 3.20525 1 +46.8335 3.27148 1 +49.3144 3.14129 1 +47.488 3.1997 1 +46.7548 3.04395 1 +52.4264 3.1654 1 +40.174 3.10943 1 +49.4648 3.22927 1 +51.5877 3.06211 1 +45.8653 3.36263 1 +44.6298 3.20112 1 +44.3965 3.39205 1 +47.911 3.30222 1 +49.4857 3.23339 1 +56.1655 3.05991 1 +53.602 3.25718 1 +56.3524 3.02202 1 +50.1797 3.27069 1 +47.9044 3.09403 1 +45.6034 3.06824 1 +48.638 3.33807 1 +45.1189 3.48732 1 +52.2518 3.45751 1 +55.5827 3.25323 1 +49.7789 2.9981 1 +45.8278 2.93058 1 +59.3848 3.20105 1 +56.9081 3.28189 1 +50.2923 3.11007 1 +49.6901 3.33219 1 +50.4372 3.33817 1 +46.6901 2.90752 1 +43.0592 3.07746 1 +53.0521 3.31728 1 +51.6457 2.91166 1 +56.4155 3.16169 1 +48.1242 3.06898 1 +51.1564 3.138 1 +45.9108 3.00238 1 +41.8679 3.41625 1 +45.2634 3.32542 1 +48.371 3.04901 1 +51.7331 3.12092 1 +55.2505 2.87529 1 +50.4898 3.26063 1 +45.7229 3.02482 1 +53.2487 3.12843 1 +40.7495 3.11301 1 +54.4269 3.0139 1 +49.8631 3.20293 1 +51.3726 3.2277 1 +45.2361 3.07773 1 +48.4523 3.07081 1 +46.287 3.13189 1 +50.3515 3.27347 1 +44.9904 3.26817 1 +42.4476 3.27972 1 +47.3749 3.03735 1 +53.4555 3.31727 1 +48.4153 3.1094 1 +53.7926 3.04449 1 +54.0196 3.39215 1 +50.2666 3.36189 1 +52.443 3.01037 1 +48.3527 3.33365 1 +48.1739 3.45715 1 +47.1748 3.10138 1 +51.9233 3.25977 1 +43.4883 3.18882 1 +54.9576 3.1186 1 +48.4501 3.26485 1 +54.5546 3.1002 1 +46.7135 3.17809 1 +49.1796 3.06229 1 +45.108 3.00187 1 +45.3851 3.18066 1 +47.5917 3.02068 1 +42.1095 3.29195 1 +47.5234 3.24008 1 +49.1828 3.21735 1 +47.529 3.169 1 +48.2168 3.20558 1 +51.3444 3.50515 1 +56.7801 3.12952 1 +43.376 3.11452 1 +51.6813 3.05728 1 +46.4761 3.33867 1 +42.7989 3.28225 1 +48.2147 3.33388 1 +43.8398 3.21452 1 +45.3259 3.32341 1 +42.4857 3.12416 1 +53.3488 3.00662 1 +40.6202 3.31405 1 +47.8093 3.37327 1 +53.1658 3.05509 1 +49.9901 3.30853 1 +46.1864 3.25731 1 +53.3771 3.31825 1 +45.314 2.97054 1 +43.5727 3.38909 1 +46.3295 2.95946 1 +52.0035 3.36222 1 +47.0441 3.09477 1 +46.4137 3.36186 1 +48.4922 2.88955 1 +47.4296 2.91461 1 +52.8988 3.00928 1 +51.0569 3.26932 1 +45.0936 3.10621 1 +51.7982 3.06612 1 +50.047 3.18173 1 +46.3997 3.47319 1 +40.6815 3.26614 1 +50.7804 3.14651 1 +50.945 3.00502 1 +53.8828 2.77829 1 +44.4023 3.38764 1 +48.7407 2.96121 1 +41.8816 3.10102 1 +50.8409 3.1567 1 +47.3503 3.31003 1 +45.4192 3.08922 1 +44.6007 3.45986 1 +45.7837 3.1961 1 +49.0422 3.00113 1 +56.4355 3.05265 1 +46.9315 3.03045 1 +48.6428 2.99467 1 +49.1295 3.08512 1 +51.5027 3.2787 1 +37.855 3.03425 1 +53.5651 2.99958 1 +52.905 3.19491 1 +52.0593 3.27347 1 +42.5397 3.19292 1 +46.9304 3.24266 1 +47.8697 3.28761 1 +48.4161 3.40762 1 +49.9486 3.16326 1 +48.4125 3.09489 1 +50.6681 3.49667 1 +46.5242 3.41124 1 +50.5101 3.56525 1 +48.7909 3.38031 1 +52.6336 3.37625 1 +46.7003 3.37347 1 +51.8202 3.02563 1 +52.3359 2.98045 1 +51.3504 3.27101 1 +47.2302 3.17823 1 +49.3377 3.2678 1 +47.4029 3.00885 1 +44.8973 3.0369 1 +51.1332 3.0311 1 +49.4433 3.16302 1 +50.8831 3.23256 1 +43.8155 3.08257 1 +48.1016 3.13554 1 +37.6605 3.24663 1 +51.6785 3.26059 1 +49.4207 3.07894 1 +48.2709 2.89937 1 +51.1283 3.07072 1 +47.2327 3.21821 1 +45.4456 2.98875 1 +57.0703 3.31448 1 +51.6428 3.34001 1 +51.6533 2.88381 1 +50.63 3.10976 1 +43.6541 3.14525 1 +53.4491 3.00302 1 +52.5741 3.26348 1 +48.216 3.32503 1 +49.352 3.24349 1 +45.4329 3.44311 1 +44.5352 3.18291 1 +47.031 3.08933 1 +48.2176 3.00225 1 +52.4414 3.05054 1 +46.6631 2.86697 1 +47.6167 3.10341 1 +48.9153 3.0127 1 +50.8521 2.94517 1 +42.3533 3.09931 1 +51.3696 3.12944 1 +51.3345 3.09018 1 +43.6623 3.41723 1 +46.6873 3.09785 1 +47.045 3.10088 1 +47.2197 3.30685 1 +51.1561 3.52719 1 +53.3846 2.99178 1 +50.2928 3.42872 1 +47.7987 3.20889 1 +46.4311 3.19132 1 +51.3061 2.96329 1 +44.7023 3.2151 1 +49.7588 2.88182 1 +44.1186 3.21516 1 +47.3292 3.00484 1 +41.8121 3.11807 1 +38.6818 3.23351 1 +46.0823 3.23881 1 +86.4786 43.0231 2 +90.5166 46.1754 2 +89.2814 44.9217 2 +84.9356 51.8863 2 +85.5441 47.9452 2 +88.371 51.2428 2 +92.554 47.3903 2 +96.9115 50.199 2 +85.6855 45.3967 2 +90.7706 41.4383 2 +88.8817 53.4048 2 +94.5828 49.3152 2 +85.2334 47.6874 2 +86.1995 53.5157 2 +85.21 50.9604 2 +94.0564 48.241 2 +87.3753 43.7219 2 +85.3393 39.4274 2 +90.9115 45.6575 2 +90.5645 49.3189 2 +89.8818 42.9256 2 +84.6589 57.9173 2 +86.5223 44.953 2 +89.7094 50.688 2 +87.6717 45.994 2 +93.0334 49.4908 2 +91.3684 49.0288 2 +86.552 45.5235 2 +88.4861 44.9406 2 +92.2209 49.4438 2 +88.5739 45.4714 2 +85.721 51.4256 2 +87.4631 55.8705 2 +89.9723 50.5565 2 +86.514 43.5825 2 +85.8972 40.6694 2 +94.2403 46.7061 2 +89.6243 46.4683 2 +83.556 39.6034 2 +88.8591 44.4038 2 +86.9261 45.0167 2 +88.4302 48.1385 2 +90.9127 43.9326 2 +87.414 47.85 2 +94.1278 49.1223 2 +85.3379 50.7741 2 +89.6671 41.6763 2 +88.7917 46.7319 2 +85.7231 46.2902 2 +85.9244 52.2396 2 +89.4591 44.9787 2 +87.64 44.2899 2 +89.3194 48.0031 2 +84.5089 41.3523 2 +87.674 48.3026 2 +86.8302 53.5616 2 +91.1842 49.8113 2 +89.9145 55.4672 2 +92.5937 59.081 2 +85.9683 52.5082 2 +86.4609 53.6659 2 +87.0482 48.1905 2 +95.197 45.2427 2 +93.4848 43.8534 2 +82.6953 49.1193 2 +86.5811 53.1177 2 +84.0562 47.3221 2 +92.4917 49.4388 2 +84.1925 49.5229 2 +91.2156 42.083 2 +87.1048 43.0394 2 +94.3474 43.4886 2 +87.3667 53.8325 2 +92.0275 47.5645 2 +86.5159 51.5866 2 +87.7532 53.4529 2 +89.597 43.1592 2 +89.655 40.6216 2 +84.6928 45.5548 2 +91.7639 48.3699 2 +92.6607 49.8629 2 +86.555 49.3919 2 +90.8054 47.5149 2 +86.1772 50.0533 2 +91.7656 50.4225 2 +89.3769 47.5726 2 +85.1607 52.3038 2 +84.704 40.4872 2 +94.8569 48.781 2 +90.535 43.1931 2 +95.8752 43.3556 2 +83.6924 43.3161 2 +89.2377 44.3606 2 +84.3062 46.7992 2 +83.5389 53.7744 2 +89.2846 44.9876 2 +86.7638 52.1358 2 +88.2236 42.7809 2 +86.3139 41.4031 2 +92.0585 50.6343 2 +88.81 62.4678 2 +86.1412 46.1583 2 +91.2111 51.015 2 +90.1774 44.4296 2 +88.652 39.9193 2 +91.3123 45.6877 2 +85.9216 46.2768 2 +90.6827 42.4833 2 +88.5398 44.8324 2 +89.8672 45.4424 2 +90.9917 48.2749 2 +88.2335 48.5318 2 +89.2344 50.5561 2 +88.7892 52.6681 2 +85.1552 52.6832 2 +88.7378 53.8588 2 +87.7561 41.5831 2 +93.7412 46.4636 2 +86.2986 51.1928 2 +86.9153 44.3384 2 +86.9154 49.1602 2 +90.8443 45.4698 2 +87.992 49.4111 2 +89.8717 51.5685 2 +88.6999 39.1328 2 +89.6743 49.6021 2 +87.3297 44.6507 2 +89.577 47.7356 2 +92.0662 48.3302 2 +89.0368 50.1882 2 +86.7379 45.9187 2 +86.3596 48.6252 2 +90.0337 45.0403 2 +89.2108 48.9147 2 +89.689 48.8692 2 +87.2408 56.3074 2 +88.3154 44.1634 2 +91.1699 46.9355 2 +88.8875 43.8631 2 +87.283 44.4296 2 +84.8534 43.1804 2 +87.3335 47.2952 2 +87.6505 50.5414 2 +96.311 46.6471 2 +88.6926 53.4257 2 +88.0917 52.869 2 +91.3403 50.753 2 +84.0359 49.4986 2 +87.2923 48.303 2 +82.2091 43.2666 2 +84.7917 44.2794 2 +92.5688 42.5525 2 +89.4485 54.3598 2 +86.4943 54.3347 2 +89.6788 49.456 2 +85.2595 56.1845 2 +89.7428 45.36 2 +90.6358 50.1006 2 +91.8902 49.0099 2 +85.3543 46.2237 2 +88.287 51.4585 2 +83.311 55.9955 2 +86.6745 49.6291 2 +85.2198 47.3764 2 +93.0694 42.2177 2 +94.5288 42.8157 2 +89.9834 42.0647 2 +89.6189 49.5295 2 +84.2698 47.9101 2 +92.5819 42.961 2 +91.3042 40.6204 2 +85.0711 44.4821 2 +90.1461 40.9955 2 +92.4721 39.8382 2 +86.1014 51.718 2 +86.0812 49.3518 2 +87.1755 47.1891 2 +84.2288 45.3026 2 +91.565 50.3471 2 +87.78 52.2848 2 +90.4919 43.7984 2 +87.1027 49.6385 2 +85.8336 50.7768 2 +86.9718 49.962 2 +89.8365 46.1989 2 +89.9746 49.1052 2 +91.0806 44.8371 2 +92.403 50.6994 2 +91.8123 47.3802 2 +85.2089 43.3215 2 +87.1131 36.9117 2 +84.6508 51.7035 2 +86.856 41.1463 2 +87.8024 53.6324 2 +87.728 45.3324 2 +91.8835 48.4475 2 +87.2429 42.0583 2 +90.2466 48.2316 2 +92.1318 45.4135 2 +91.505 45.4504 2 +85.5979 50.574 2 +89.921 53.5856 2 +86.1419 51.7783 2 +87.2909 44.8204 2 +91.915 48.4429 2 +96.0962 49.388 2 +89.013 41.348 2 +88.2461 53.4774 2 +91.8352 48.3888 2 +88.1476 49.0767 2 +92.4085 47.1247 2 +86.5908 47.3597 2 +90.8951 48.6404 2 +85.1012 48.3759 2 +86.5862 51.6755 2 +89.005 52.7666 2 +89.4523 50.372 2 +89.1947 51.7825 2 +88.0423 54.1936 2 +89.1126 42.4508 2 +88.6973 45.0153 2 +90.2052 48.1759 2 +89.6 44.7762 2 +88.2543 53.9042 2 +91.999 49.3056 2 +91.7828 38.3965 2 +90.3491 44.7946 2 +86.4181 48.8886 2 +90.1743 54.5527 2 +84.2166 48.9596 2 +87.1318 48.5002 2 +89.4146 52.1653 2 +96.1585 47.4563 2 +94.4054 52.493 2 +86.9418 45.9029 2 +85.9066 44.2445 2 +86.6872 48.0419 2 +86.3109 48.6685 2 +86.4281 42.5467 2 +85.0789 46.2326 2 +91.936 50.4201 2 +91.5812 45.0742 2 +95.1291 42.8016 2 +88.4259 45.7601 2 +94.9516 45.7467 2 +89.9463 50.2493 2 +89.5216 36.1927 2 +84.0739 54.1751 2 +83.564 47.5439 2 +89.6949 45.577 2 +90.2285 41.2575 2 +89.7117 48.7373 2 +89.7428 46.2592 2 +84.0808 50.0201 2 +88.8406 39.389 2 +90.1685 47.9725 2 +86.8695 51.2951 2 +85.7424 49.6763 2 +91.2372 43.1012 2 +84.3017 49.326 2 +94.2768 44.6449 2 +86.3431 48.7447 2 +84.4161 44.6044 2 +85.4507 48.7714 2 +90.5204 41.1995 2 +89.6142 55.9238 2 +87.2395 47.814 2 +91.3517 53.9457 2 +87.7428 44.2146 2 +89.2816 44.7962 2 +88.3347 50.1716 2 +88.7167 53.8383 2 +93.725 52.1806 2 +88.8652 46.2972 2 +86.8973 49.1004 2 +84.4684 53.9446 2 +85.2105 49.5808 2 +88.7945 47.299 2 +86.6341 52.8885 2 +88.1526 42.285 2 +89.8543 47.8203 2 +89.6499 54.3044 2 +85.0978 48.1174 2 +93.0341 43.9514 2 +88.8999 55.6848 2 +91.1194 45.3769 2 +90.6155 48.163 2 +86.3177 44.259 2 +91.7015 46.48 2 +87.1794 51.1598 2 +94.3648 41.8924 2 +92.1155 46.7421 2 +90.4303 48.403 2 +87.9613 41.0845 2 +90.9545 45.775 2 +85.4282 54.8191 2 +89.0309 45.6888 2 +92.1905 40.3106 2 +90.7636 49.5251 2 +91.3334 43.5115 2 +91.4937 50.3064 2 +91.5215 47.7161 2 +90.912 48.4959 2 +84.5398 49.0111 2 +89.7231 48.9016 2 +90.1669 46.6715 2 +90.6192 45.6402 2 +90.2356 45.1738 2 +85.5931 50.5666 2 +90.3601 50.0199 2 +88.9088 45.9637 2 +83.6885 39.4644 2 +91.2123 45.3723 2 +83.8924 34.3746 2 +85.6403 44.0833 2 +86.652 48.2945 2 +87.0762 50.7283 2 +87.4564 47.4037 2 +89.4854 51.8464 2 +91.1165 48.9172 2 +90.3261 44.0005 2 +88.5556 51.3694 2 +90.458 44.1667 2 +93.4729 49.243 2 +88.8853 48.4224 2 +95.1038 48.0907 2 +91.754 47.1854 2 +95.9075 49.1264 2 +89.5228 43.2814 2 +90.7021 45.6001 2 +92.0849 44.9925 2 +88.82 48.4119 2 +87.4787 50.8263 2 +85.5918 43.3649 2 +84.9395 49.9214 2 +87.0413 47.5512 2 +86.6818 50.5586 2 +89.5018 43.7927 2 +89.665 52.2942 2 +90.1356 47.877 2 +89.5638 52.2045 2 +87.6453 45.5494 2 +96.8817 50.6807 2 +88.8998 51.8197 2 +87.7613 52.269 2 +84.8836 44.4607 2 +84.1566 51.5901 2 +88.5174 50.9329 2 +84.1924 52.2039 2 +88.5677 44.7193 2 +87.1738 48.171 2 +88.8642 48.0175 2 +93.5652 52.9374 2 +86.4614 46.5039 2 +81.435 52.4516 2 +94.1343 49.3229 2 +90.7788 50.4529 2 +89.2447 48.8367 2 +94.8868 45.8962 2 +89.9756 48.1054 2 +83.3507 52.0499 2 +90.1138 45.3442 2 +88.8562 50.9917 2 +88.7974 52.053 2 +90.2219 39.8266 2 +90.3273 48.9453 2 +88.6123 47.1052 2 +87.5244 42.6378 2 +86.6708 47.7617 2 +90.358 46.6412 2 +86.934 50.2767 2 +88.3847 45.9418 2 +87.6987 46.9347 2 +97.6855 44.7411 2 +89.395 52.5135 2 +88.052 46.0769 2 +90.7918 52.3049 2 +87.5639 50.6963 2 +90.1878 44.4266 2 +88.1547 44.3935 2 +87.6249 52.9993 2 +83.5884 43.193 2 +88.3563 49.7908 2 +88.9367 41.5876 2 +85.7033 53.1422 2 +85.0605 53.9194 2 +85.2478 48.0425 2 +86.402 52.5303 2 +86.2921 54.6127 2 +87.3851 40.1131 2 +90.3538 50.489 2 +92.2456 49.8483 2 +89.3327 42.3362 2 +92.1793 44.9883 2 +90.1942 49.9448 2 +86.3947 52.5926 2 +86.7467 51.1191 2 +88.5879 48.6831 2 +87.2106 52.2256 2 +89.67 48.1116 2 +90.5859 45.1967 2 +92.8207 51.5179 2 +89.014 43.603 2 +88.8365 53.8056 2 +85.6767 46.1244 2 +88.0831 51.1716 2 +85.2735 55.0444 2 +82.4569 51.4223 2 +89.8371 45.6955 2 +91.0736 50.0676 2 +80.2368 45.3892 2 +94.1671 48.3806 2 +90.2918 58.0761 2 +91.4702 50.8459 2 +89.7609 50.9258 2 +88.9767 53.2659 2 +89.0141 47.2254 2 +90.5379 50.6422 2 +89.8731 55.2361 2 +92.3094 52.1076 2 +87.1002 51.2813 2 +86.2298 48.1148 2 +89.3258 50.2489 2 +92.9927 52.9134 2 +84.6777 45.3125 2 +84.8171 46.6045 2 +82.4462 51.6815 2 +93.8521 49.4999 2 +91.4381 51.9424 2 +81.4439 48.5216 2 +94.6958 46.716 2 +89.2705 46.4272 2 +87.9909 45.4986 2 +87.1652 46.2185 2 +80.1322 47.939 2 +94.7135 45.0414 2 +89.1497 42.924 2 +96.4274 40.1169 2 +88.8806 44.2576 2 +87.8476 46.4712 2 +89.5247 54.1398 2 +87.9559 43.27 2 +87.7503 52.3902 2 +86.2991 42.9858 2 +83.0513 47.3891 2 +87.4855 51.2645 2 +92.4444 49.4336 2 +89.9791 43.9567 2 +84.8837 49.3133 2 +87.0268 43.7103 2 +85.9711 44.6149 2 +88.4842 51.8088 2 +93.0818 50.1863 2 +90.5982 46.9826 2 +89.2324 54.4526 2 +84.317 49.503 2 +86.897 51.2823 2 +88.53 49.1958 2 +88.7332 38.2667 2 +85.3736 50.9609 2 +88.6667 49.2659 2 +85.0091 46.4564 2 +88.767 43.1842 2 +89.0164 51.0875 2 +81.7452 47.8578 2 +87.1229 44.7752 2 +85.8284 46.6734 2 +90.7763 50.1546 2 +86.7108 46.8908 2 +92.6708 51.8017 2 +74.2726 69.8067 3 +73.9818 67.4649 3 +74.1322 72.7556 3 +72.7323 71.8585 3 +74.1531 70.7375 3 +73.3552 68.3534 3 +73.2703 69.4745 3 +73.631 72.4323 3 +73.3769 68.2072 3 +72.6533 69.2083 3 +72.9688 69.1342 3 +73.8642 70.599 3 +73.8378 69.8061 3 +73.302 69.2352 3 +74.5045 69.3018 3 +73.2974 70.8838 3 +73.743 67.624 3 +74.6375 69.7559 3 +73.8718 71.5831 3 +73.192 66.8238 3 +73.9072 68.3804 3 +73.5798 67.6714 3 +73.575 68.158 3 +73.823 71.3263 3 +73.0799 71.4504 3 +73.202 71.0826 3 +75.0493 70.3255 3 +73.4871 67.8094 3 +73.0799 71.3822 3 +73.4581 67.936 3 +73.0602 69.3307 3 +73.2275 67.6483 3 +73.6979 70.7219 3 +74.1304 65.1982 3 +72.7914 72.6058 3 +73.7366 69.6277 3 +73.7855 70.3239 3 +74.3501 72.0416 3 +73.6619 69.4683 3 +72.7375 67.0718 3 +72.6612 68.8753 3 +73.6744 72.5614 3 +74.0665 66.307 3 +74.6205 69.2277 3 +73.6707 70.493 3 +73.6159 71.9067 3 +74.3796 69.4959 3 +73.4579 65.8763 3 +74.6789 67.6465 3 +73.2255 67.3565 3 +72.5276 69.068 3 +73.6076 71.8806 3 +73.5133 69.3907 3 +74.6233 67.1822 3 +73.0254 68.7516 3 +74.4376 69.978 3 +72.8367 72.4539 3 +72.9212 69.7396 3 +73.8538 70.7214 3 +73.4151 68.8293 3 +73.9113 70.8323 3 +73.8672 70.8038 3 +73.416 69.3949 3 +74.3085 70.829 3 +73.7153 67.5603 3 +74.2444 67.9185 3 +73.5054 73.9994 3 +75.2686 71.5738 3 +74.5974 72.6614 3 +74.4964 68.9337 3 +74.1138 70.4915 3 +73.1965 70.2223 3 +74.6996 70.9788 3 +73.5289 70.3221 3 +72.3757 71.767 3 +72.7007 70.7112 3 +72.9772 70.4844 3 +74.1244 71.595 3 +72.635 72.7985 3 +73.1364 74.9658 3 +73.3382 66.7437 3 +72.8381 66.8321 3 +73.8062 68.983 3 +74.0164 67.9562 3 +73.123 68.1732 3 +73.7772 69.7548 3 +74.0034 70.2333 3 +73.9119 69.4078 3 +74.0703 71.3454 3 +73.4394 68.3741 3 +72.96 71.1806 3 +73.0452 67.9602 3 +73.5992 67.4286 3 +74.0655 67.7051 3 +72.9039 73.1573 3 +73.722 71.3017 3 +73.7299 66.9321 3 +72.2967 70.6181 3 +73.4491 70.1462 3 +72.7991 68.6031 3 +73.3971 68.7175 3 +73.3778 68.9861 3 +74.2252 68.2841 3 +72.6546 71.0669 3 +73.7999 73.2534 3 +74.5922 68.8572 3 +73.4812 69.5408 3 +74.3824 69.1418 3 +73.7835 66.108 3 +73.0171 69.0298 3 +73.5381 72.7584 3 +73.3591 69.9393 3 +72.7752 71.4214 3 +73.7243 70.2679 3 +73.6415 69.6417 3 +73.8954 69.8098 3 +73.2771 70.8836 3 +73.7346 68.7563 3 +72.9913 68.5504 3 +72.5512 72.608 3 +73.8834 71.0078 3 +72.4116 68.3206 3 +74.0903 69.715 3 +73.6169 71.9917 3 +73.6451 71.6268 3 +73.818 68.2721 3 +72.5783 68.539 3 +72.8977 69.0658 3 +74.6791 68.2805 3 +74.1521 71.4337 3 +73.6652 69.5958 3 +73.8454 71.3259 3 +72.4555 71.2883 3 +73.7817 70.1752 3 +91.9811 26.0161 4 +90.2979 25.2049 4 +91.2388 26.6595 4 +91.9655 23.9165 4 +90.7678 29.024 4 +87.7469 24.0594 4 +92.4135 27.5165 4 +90.4122 26.6673 4 +94.2253 26.573 4 +90.6259 24.8211 4 +88.6002 28.7988 4 +90.1902 25.0782 4 +89.3152 25.2486 4 +89.0171 29.0451 4 +89.537 27.8269 4 +90.0721 25.0237 4 +93.7158 27.9905 4 +88.425 27.7088 4 +90.5562 25.042 4 +91.7559 27.3475 4 +89.5061 28.7581 4 +91.8513 28.4709 4 +91.9714 29.3321 4 +90.6725 25.995 4 +90.1253 28.6277 4 +90.3599 25.2032 4 +90.803 27.1479 4 +89.9646 28.6848 4 +91.1998 26.4056 4 +91.0664 24.2256 4 +88.5661 28.929 4 +90.8862 26.8697 4 +93.0949 26.319 4 +90.8704 24.9768 4 +91.4186 24.2155 4 +92.1146 30.2797 4 +87.0458 27.1386 4 +88.7295 24.9766 4 +91.264 24.7828 4 +89.7206 25.1047 4 +92.532 26.5028 4 +90.67 26.9685 4 +92.0341 23.8323 4 +90.2749 26.479 4 +92.2503 29.37 4 +90.8437 28.5166 4 +89.4117 25.6386 4 +91.8173 26.4935 4 +90.4973 26.4059 4 +90.8256 26.6124 4 +92.1876 29.471 4 +91.7216 25.6866 4 +92.0806 25.0022 4 +88.1969 27.4593 4 +90.1792 27.37 4 +92.1735 25.1773 4 +90.975 26.7702 4 +89.3249 28.6589 4 +89.514 26.9974 4 +88.3018 25.8741 4 +90.923 23.8659 4 +90.6065 26.0769 4 +90.3361 28.8277 4 +89.8283 27.117 4 +92.3136 31.7137 4 +89.6927 25.3439 4 +90.6924 29.8552 4 +89.3893 27.6362 4 +89.7644 27.4435 4 +90.6016 30.5066 4 +90.158 25.9923 4 +88.5255 27.2176 4 +89.895 24.3798 4 +89.377 24.5855 4 +91.2859 29.5072 4 +92.2599 26.9987 4 +87.2779 25.2799 4 +92.4109 25.7417 4 +88.944 23.8288 4 +90.792 25.5756 4 +90.7118 26.995 4 +90.3853 29.3784 4 +91.9259 25.297 4 +90.1195 26.5868 4 +92.591 27.0844 4 +91.8291 28.1403 4 +91.4011 29.3396 4 +93.0582 32.3108 4 +91.4498 25.6946 4 +90.751 27.5155 4 +91.4602 30.0453 4 +92.1166 26.5203 4 +90.6286 26.7077 4 +91.4566 27.9929 4 +91.7619 21.0296 4 +92.6422 24.9973 4 +91.6837 25.1544 4 +90.7574 26.5851 4 +90.2623 25.3736 4 +90.2408 25.9322 4 +90.3636 27.7679 4 +93.0433 26.2691 4 +90.3456 25.9149 4 +92.5928 27.8577 4 +91.8386 25.8612 4 +90.6975 26.614 4 +92.0151 26.7313 4 +87.8768 26.2049 4 +88.435 30.1644 4 +89.4816 25.8074 4 +89.9832 22.8605 4 +89.3518 27.9378 4 +90.6126 27.1129 4 +93.4874 26.1727 4 +89.1395 26.558 4 +90.6683 29.4576 4 +90.2914 27.8309 4 +88.7257 28.6311 4 +89.1031 23.3056 4 +90.6858 26.8134 4 +90.6457 27.1179 4 +90.2173 26.4178 4 +91.4241 26.3936 4 +89.2604 27.0415 4 +89.4668 24.5544 4 +92.2178 24.5295 4 +90.7077 28.9985 4 +92.2339 25.2276 4 +89.8906 25.019 4 +90.5106 31.0679 4 +90.4675 26.9606 4 +89.9945 24.0291 4 +92.0604 26.8875 4 +88.5457 27.5487 4 +91.3498 29.6584 4 +92.1397 27.6735 4 +94.6411 28.4039 4 +91.4722 25.951 4 +90.9964 24.5505 4 +90.7977 29.0235 4 +88.1699 26.1086 4 +88.905 27.5412 4 +90.1492 25.6711 4 +90.7858 26.3573 4 +88.566 24.85 4 +90.6651 26.7752 4 +90.021 26.4181 4 +89.5879 24.8532 4 +92.4591 28.2499 4 +92.6956 26.5025 4 +89.4804 29.1821 4 +91.4405 24.0908 4 +90.3535 26.2176 4 +88.9036 27.2917 4 +92.2926 26.5262 4 +95.2243 27.6474 4 +90.4325 26.4718 4 +88.068 26.5283 4 +89.2784 25.8961 4 +91.9309 25.4583 4 +91.9168 27.4116 4 +90.1169 25.7655 4 +92.6506 22.2658 4 +90.0457 28.4028 4 +90.3543 24.4808 4 +92.7355 23.1739 4 +90.8783 24.1287 4 +91.786 26.2046 4 +88.7722 26.9345 4 +90.8266 28.2891 4 +88.789 25.6881 4 +92.4348 25.7879 4 +90.9219 27.2295 4 +91.4017 25.1013 4 +91.1503 26.5223 4 +89.4192 24.1066 4 +90.8332 27.6948 4 +89.0772 25.1445 4 +88.1759 28.6175 4 +90.9373 26.3729 4 +92.843 26.2314 4 +91.3838 24.5404 4 +88.976 27.0877 4 +91.581 24.4955 4 +93.4245 27.2631 4 +91.147 25.7659 4 +89.1462 25.1933 4 +90.4053 26.1751 4 +90.0441 27.2868 4 +90.5743 26.9449 4 +90.103 25.5377 4 +89.8373 25.2346 4 +90.2871 33.6603 4 +89.8459 26.0444 4 +90.7001 23.9198 4 +90.6129 26.8572 4 +90.0107 26.898 4 +91.6055 24.0911 4 +92.1508 27.4122 4 +92.6512 27.797 4 +89.4823 27.4543 4 +91.1698 26.946 4 +89.7991 23.9718 4 +91.6375 28.4893 4 +90.2568 28.6949 4 +89.4447 30.0294 4 +91.5498 23.8889 4 +90.5709 25.8111 4 +91.9621 27.79 4 +91.5837 26.6053 4 +91.8624 24.9775 4 +92.7647 24.3805 4 +92.5599 25.7229 4 +89.5375 23.6246 4 +89.2872 26.4767 4 +90.8763 27.6425 4 +88.4581 25.8987 4 +88.8848 25.4981 4 +92.6461 26.5901 4 +92.6712 27.6029 4 +91.088 24.5292 4 +89.3503 20.8126 4 +90.8414 27.5455 4 +90.185 26.0746 4 +92.2745 25.1596 4 +90.0506 30.4402 4 +92.2351 24.8627 4 +89.5966 26.0208 4 +92.1886 29.2782 4 +89.5351 26.6449 4 +92.2264 26.3972 4 +89.6375 26.4345 4 +91.014 28.2277 4 +87.8676 26.1316 4 +90.0777 28.5869 4 +90.4841 26.8201 4 +89.5183 28.241 4 +90.7438 27.3458 4 +91.4075 25.0657 4 +90.2214 28.7614 4 +91.3736 26.4393 4 +89.4379 27.0212 4 +91.5826 24.4177 4 +92.0618 24.8452 4 +90.2 26.4186 4 +91.0427 27.729 4 +90.8863 22.5538 4 +89.5708 26.0742 4 +92.1803 24.3223 4 +90.8578 24.263 4 +92.6844 24.8197 4 +90.615 26.9866 4 +92.7103 25.5469 4 +91.3432 23.3244 4 +91.3293 24.6959 4 +90.8851 27.4971 4 +90.2636 26.2225 4 +89.8283 30.3716 4 +92.2707 23.889 4 +93.4133 25.1232 4 +88.3781 28.0142 4 +88.7215 24.4829 4 +89.0628 27.1402 4 +92.4659 25.061 4 +89.3753 24.9058 4 +90.9037 31.8957 4 +91.086 26.8256 4 +88.9895 29.171 4 +90.7835 25.7059 4 +91.2416 24.382 4 +93.523 25.4828 4 +90.7055 24.7443 4 +91.5216 25.8635 4 +91.6126 29.1513 4 +89.5577 22.1402 4 +91.55 24.9954 4 +87.1713 29.0131 4 +88.6679 28.6267 4 +90.8896 27.3246 4 +91.9702 25.2676 4 +90.115 27.8777 4 +92.7312 27.9704 4 +90.228 21.8559 4 +91.308 26.3749 4 +90.0861 25.107 4 +90.5469 27.1608 4 +90.9897 27.6804 4 +93.8508 25.2669 4 +89.6564 27.9189 4 +90.3725 26.0339 4 +90.8686 26.5653 4 +89.7784 27.0816 4 +91.1231 25.2911 4 +90.9732 27.6954 4 +91.0708 30.5316 4 +87.817 24.8397 4 +92.9265 27.3698 4 +91.2247 28.2971 4 +91.3348 24.9713 4 +93.2589 26.3927 4 +91.2791 24.5847 4 +89.2009 28.5092 4 +91.7797 30.0154 4 +88.9906 23.4283 4 +91.216 28.2823 4 +92.367 25.3266 4 +91.6419 26.0725 4 +92.4662 25.7127 4 +90.6701 27.1679 4 +91.1143 29.7778 4 +92.2739 24.0119 4 +91.4413 23.5201 4 +92.0196 29.8628 4 +91.0818 25.9817 4 +89.1357 29.5639 4 +89.571 26.882 4 +92.3279 29.3579 4 +89.788 27.5002 4 +91.3746 25.2047 4 +90.5895 25.7622 4 +90.1159 23.1072 4 +89.77 26.7014 4 +88.0015 25.3795 4 +88.2077 24.908 4 +87.0637 28.099 4 +89.0327 28.6303 4 +91.4685 26.9955 4 +91.3455 25.3371 4 +90.6186 29.7416 4 +92.1977 25.4636 4 +91.6136 29.1239 4 +91.0327 26.9506 4 +88.4428 24.3246 4 +90.7656 27.5968 4 +90.13 27.5494 4 +89.9753 28.044 4 +88.8746 26.4726 4 +90.1393 24.1829 4 +-1.65466 3.15554 5 +-1.95979 1.89509 5 +0.242731 6.30034 5 +-4.54983 5.83891 5 +-2.85125 -1.8993 5 +4.07533 -0.00279304 5 +3.64364 -0.388653 5 +11.5645 5.68943 5 +-0.14346 -6.13068 5 +-7.99011 -3.55738 5 +-0.177416 -0.497974 5 +-1.35756 6.00807 5 +3.25944 4.96499 5 +6.08788 7.19605 5 +2.21844 5.30573 5 +1.63419 -1.56224 5 +-2.36155 0.127156 5 +0.11425 -0.896811 5 +7.64785 1.49522 5 +2.30702 0.830296 5 +-1.21257 0.965462 5 +7.55589 0.0988247 5 +4.33746 -1.25607 5 +1.54874 9.68863 5 +-0.592713 -0.116108 5 +2.66729 1.71522 5 +1.31065 0.558702 5 +-6.38358 -2.22453 5 +-2.97827 3.83165 5 +-1.611 2.77637 5 +-3.91203 1.54852 5 +4.42151 -6.23474 5 +0.2244 -3.07489 5 +9.52907 1.73414 5 +2.50423 4.56043 5 +-1.84383 -1.48748 5 +-0.0484444 -5.97343 5 +-3.39596 6.11471 5 +0.855239 -1.1621 5 +1.10345 2.55092 5 +-5.31066 3.34637 5 +0.835511 -3.44371 5 +8.10291 -1.2116 5 +-4.96163 -2.42639 5 +10.8092 0.356932 5 +-3.32887 3.24998 5 +-0.397606 3.20236 5 +-3.2666 -5.72386 5 +-3.02228 1.00746 5 +-2.04176 -5.64454 5 +2.72495 2.27014 5 +-1.67995 3.55699 5 +6.0739 7.05283 5 +-1.27768 5.53267 5 +2.51899 -0.291185 5 +1.1463 -1.98053 5 +-5.294 0.724984 5 +6.12424 -1.91427 5 +2.5964 -6.36295 5 +5.63341 2.8208 5 +2.69827 -1.92172 5 +10.3994 1.19503 5 +4.32114 -0.206678 5 +6.66836 -3.70412 5 +1.64158 -3.79976 5 +9.7046 0.839301 5 +-3.57995 3.73176 5 +2.69933 9.35067 5 +-0.239075 -7.38483 5 +-0.438414 4.15476 5 +2.64711 -3.07873 5 +-2.21501 2.50166 5 +8.04171 -3.2728 5 +3.81812 2.24573 5 +4.87076 -1.61641 5 +-1.72199 3.93798 5 +-6.40525 0.557111 5 +-2.43844 -0.852453 5 +4.19113 -4.16546 5 +-5.93183 -2.45815 5 +6.24556 7.74392 5 +2.9709 -2.7168 5 +-7.30964 -2.61273 5 +-8.57655 1.14362 5 +-1.22235 -8.39053 5 +-1.07542 -1.48035 5 +-0.466294 -7.94737 5 +-0.937551 5.67085 5 +3.09871 3.89322 5 +9.56232 5.10074 5 +3.78911 -0.054962 5 +1.34379 2.37818 5 +1.68973 -5.34433 5 +-0.0720189 -6.59261 5 +-6.71218 4.20541 5 +-5.77796 -4.01372 5 +5.54546 1.02003 5 +-0.61054 1.97387 5 +4.32751 -0.4685 5 +0.0433711 -2.69711 5 +2.07737 -1.49538 5 +10.1146 -4.03963 5 +6.30502 4.85174 5 +-1.68707 -5.25781 5 +-6.1506 1.03138 5 +-0.954344 0.888134 5 +-2.58785 -2.37655 5 +5.19407 -2.79605 5 +8.55873 7.11099 5 +-1.46419 0.9145 5 +-3.58374 8.63403 5 +1.89922 0.160052 5 +6.98553 1.06818 5 +4.03384 -3.29934 5 +0.584499 -5.52117 5 +-0.128668 5.28011 5 +8.09119 -8.86059 5 +2.78583 1.13262 5 +1.39289 0.167642 5 +-3.46198 2.72315 5 +4.78413 -5.36212 5 +0.640676 -0.292248 5 +-3.33334 0.780647 5 +6.16653 4.72602 5 +-4.76767 3.1332 5 +-2.52385 2.44323 5 +-5.74168 -2.96422 5 +0.0622463 -1.03993 5 +0.72398 -2.56943 5 +-0.542308 -1.49573 5 +3.61572 3.45244 5 +0.943772 0.144619 5 +-3.63437 0.124569 5 +0.599637 5.76874 5 +1.86564 1.1967 5 +-4.01782 -0.79129 5 +-9.53771 3.26686 5 +-0.634747 -4.92272 5 +1.49663 3.41677 5 +-0.235596 -1.75087 5 +-1.96046 0.964119 5 +-4.39435 -3.37095 5 +-3.94655 5.02581 5 +-2.49111 6.54932 5 +-0.431078 0.490679 5 +1.93255 5.7082 5 +-0.719091 -4.62139 5 +12.2838 2.25227 5 +3.35946 0.431036 5 +-2.3539 2.52036 5 +3.71371 -0.501098 5 +-2.20401 -1.69065 5 +1.45176 -1.4088 5 +0.464342 0.0891036 5 +0.832195 -1.89687 5 +-4.93361 5.9575 5 +0.0122751 -0.155296 5 +-0.139144 3.87836 5 +3.26964 -3.66852 5 +4.16192 7.80085 5 +2.31779 -1.96063 5 +-1.61499 -1.37047 5 +5.56298 4.12885 5 +9.07988 -2.79007 5 +-0.211274 3.0923 5 +8.14108 -9.06238 5 +7.2831 11.3461 5 +-9.71298 2.76591 5 +14.7922 -1.53972 5 +-3.03625 3.14589 5 +3.24869 1.47472 5 +0.905788 -0.0489007 5 +2.08973 -4.71409 5 +5.76686 0.827778 5 +8.16547 3.32944 5 +3.22301 5.20771 5 +3.93875 5.30128 5 +-7.42484 5.19288 5 +0.633585 2.82469 5 +2.56726 1.31561 5 +-4.49471 1.84318 5 +0.380982 0.333542 5 +-3.46291 -1.35364 5 +-3.50238 -6.40089 5 +2.23613 6.05214 5 +3.66124 -0.0598393 5 +-1.83806 -1.33336 5 +8.52088 -0.68811 5 +1.32014 1.90211 5 +1.51614 -2.66772 5 +-9.19635 0.883039 5 +2.97915 1.03053 5 +4.46492 1.63294 5 +-3.06431 -2.32888 5 +0.597905 4.07005 5 +4.41701 -5.01487 5 +-0.953847 1.97457 5 +1.37149 3.47017 5 +4.88548 6.72843 5 +-1.04998 4.07991 5 +3.24584 -1.01001 5 +5.93121 1.00057 5 +4.6739 0.019708 5 +6.83384 4.41556 5 +-1.91565 5.70897 5 +6.80317 6.64806 5 +0.918914 1.20794 5 +0.8364 0.0173155 5 +-1.77346 -3.98593 5 +1.92042 0.596846 5 +-10.1495 -5.77052 5 +7.54711 -1.4167 5 +-9.94659 4.46867 5 +-4.14971 2.83657 5 +-4.20263 -2.70979 5 +-0.239809 -1.65895 5 +-3.54769 7.7192 5 +-4.41639 -2.63558 5 +5.90387 1.95566 5 +0.0737254 4.09633 5 +3.4177 0.0200606 5 +10.2639 -3.03816 5 +0.197503 1.81457 5 +8.96799 8.22514 5 +4.30686 -3.77064 5 +4.93563 -2.17216 5 +5.17733 -0.814761 5 +7.82605 3.60719 5 +-2.91463 7.86977 5 +-4.94531 6.7106 5 +1.62834 0.493812 5 +12.977 2.04322 5 +5.09127 -3.83338 5 +-8.04881 6.6609 5 +3.99283 0.0638659 5 +1.63371 3.56097 5 +8.02647 2.84756 5 +-6.10105 1.85929 5 +-1.1779 2.52419 5 +0.695207 2.71839 5 +-2.68079 5.70324 5 +11.7375 5.00656 5 +-1.77092 -1.68061 5 +-2.97868 3.41728 5 +-0.370456 6.7466 5 +5.00147 8.27174 5 +-2.2907 -1.43738 5 +-9.30166 -2.4587 5 +1.9714 1.94833 5 +0.397733 -0.76196 5 +3.31097 -5.1518 5 +-4.83887 1.15181 5 +0.639433 6.28158 5 +-7.3024 7.48131 5 +-5.50179 6.48834 5 +-9.60045 -4.2444 5 +-1.07479 2.3999 5 +-8.88191 0.72365 5 +-2.7492 3.65052 5 +2.35226 3.47701 5 +-1.36277 4.96686 5 +-2.24105 5.95415 5 +4.71727 -3.72103 5 +0.326285 6.77888 5 +-5.37655 -2.43309 5 +-5.62916 3.53113 5 +-4.18169 2.40695 5 +0.036091 0.456471 5 +1.91916 -3.79522 5 +-6.47782 -0.0190141 5 +-2.36081 -0.660907 5 +9.32368 3.00638 5 +-7.50842 -0.234816 5 +-0.94 4.59998 5 +3.41021 1.72389 5 +-4.18479 0.899722 5 +3.20191 -4.27056 5 +-3.19708 1.01505 5 +5.44536 2.25157 5 +10.0825 7.18699 5 +10.6657 5.67901 5 +3.51985 1.24137 5 +-2.35764 -6.09353 5 +-7.0898 3.66954 5 +0.70734 -1.14433 5 +-7.4583 -4.71297 5 +2.24185 -3.93383 5 +7.4003 2.09532 5 +4.03369 3.84064 5 +1.62249 0.168851 5 +1.73933 0.610429 5 +-7.23506 1.64027 5 +2.243 5.64408 5 +12.2009 -1.15147 5 +46.8561 97.8985 8 +46.8416 96.6635 8 +46.4602 96.2782 8 +46.7127 97.7423 8 +46.9914 97.2041 8 +46.9173 96.7827 8 +46.7745 96.4818 8 +46.9683 96.9228 8 +46.9475 97.0782 8 +46.9178 98.2688 8 +46.8158 97.132 8 +46.4592 97.4589 8 +46.7112 99.047 8 +46.3934 98.1286 8 +47.2699 99.4634 8 +46.888 98.1687 8 +47.1195 97.7149 8 +46.648 96.5271 8 +46.8689 97.8978 8 +46.8373 96.1379 8 +46.4721 97.5516 8 +46.3042 97.7456 8 +46.8441 97.9966 8 +46.9667 96.7757 8 +46.2576 97.174 8 +46.3537 96.7191 8 +46.788 98.84 8 +46.5896 96.865 8 +46.4405 97.9658 8 +46.6816 97.7828 8 +46.8654 97.9209 8 +46.5054 97.4591 8 +46.5314 97.4193 8 +47.0844 97.1519 8 +46.7607 97.3105 8 +46.1788 97.7681 8 +46.8031 97.6769 8 +46.6754 96.6076 8 +46.6825 96.8158 8 +46.5879 97.5057 8 +47.0293 97.8876 8 +47.1024 97.2003 8 +46.4841 97.8724 8 +46.7678 97.8517 8 +47.0438 99.4431 8 +46.475 98.5681 8 +46.9435 98.7066 8 +46.5785 98.1102 8 +46.6087 97.9767 8 +46.6545 98.4958 8 +46.5087 97.675 8 +46.8251 97.4383 8 +46.7483 96.9506 8 +46.8477 98.4845 8 +46.2725 98.7478 8 +46.3932 98.6142 8 +46.903 95.7448 8 +46.8512 95.8197 8 +47.2473 98.146 8 +46.6484 97.5435 8 +46.8626 96.9986 8 +47.0493 97.9576 8 +46.6599 97.2893 8 +46.8039 97.4159 8 +46.259 98.3545 8 +46.602 98.0131 8 +46.921 97.2904 8 +47.1647 98.8029 8 +47.1102 97.6287 8 +46.5269 98.4176 8 +46.6604 99.2336 8 +46.6316 96.5949 8 +46.5649 96.9664 8 +47.0506 98.1135 8 +46.8383 96.4201 8 +46.3531 97.3522 8 +46.5944 97.8713 8 +46.6731 95.1606 8 +46.5163 97.8681 8 +46.5566 97.0541 8 +46.531 97.2174 8 +46.7041 96.5078 8 +47.2848 97.2332 8 +46.9291 98.1139 8 +46.3256 99.8857 8 +47.102 98.9331 8 +46.814 96.7862 8 +46.9374 96.6155 8 +46.7145 97.6226 8 +46.715 98.1566 8 +46.5158 95.5454 8 +46.5629 97.0851 8 +46.9501 98.5567 8 +46.3124 97.7652 8 +46.2066 99.5194 8 +46.9503 97.9211 8 +46.339 97.7687 8 +45.9853 96.7089 8 +47.3146 97.2134 8 +46.2186 96.9146 8 +46.4874 98.0093 8 +46.6408 97.6948 8 +46.5774 96.5733 8 +46.1674 98.0757 8 +46.1367 97.3792 8 +46.1729 96.7925 8 +46.9602 95.183 8 +46.637 99.8563 8 +47.1634 97.7161 8 +46.9084 99.7199 8 +46.455 96.705 8 +46.955 98.8835 8 +46.765 98.7974 8 +46.1961 98.006 8 +46.3598 97.1438 8 +46.5656 98.3999 8 +47.1086 96.9564 8 +47.3158 99.949 8 +46.5392 96.9697 8 +47.5078 97.6512 8 +46.6645 97.5788 8 +46.4633 98.4374 8 +46.632 96.4211 8 +46.684 96.3748 8 +47.0257 96.4409 8 +46.5726 99.7075 8 +46.372 97.9994 8 +46.5176 97.0279 8 +46.5873 96.9607 8 +46.4106 97.5547 8 +46.5163 97.2247 8 +46.5243 98.0861 8 +46.5143 97.7893 8 +46.3077 97.8731 8 +46.9413 97.0721 8 +46.7776 97.7588 8 +46.9127 97.8808 8 +46.3164 97.2455 8 +46.9484 96.5465 8 +46.7762 98.4775 8 +46.989 98.1925 8 +46.7029 98.3393 8 +46.5889 98.5784 8 +46.9014 98.1903 8 +46.6347 96.7807 8 +46.3536 97.1091 8 +46.7157 99.4054 8 +46.7234 99.337 8 +46.7502 98.1035 8 +47.2217 97.0716 8 +46.2567 98.1482 8 +46.8522 94.8742 8 +46.3502 97.0685 8 +46.2311 98.0683 8 +47.02 97.9608 8 +46.8203 96.7425 8 +46.8181 97.7725 8 +46.4673 97.0973 8 +46.4067 99.07 8 +46.9564 98.5048 8 +46.6692 96.6604 8 +47.1612 98.1991 8 +46.6564 96.6772 8 +46.5594 98.7963 8 +47.4426 97.3721 8 +47.0102 98.0624 8 +46.5032 98.8213 8 +46.6145 96.7089 8 +47.1639 98.4716 8 +47.2586 98.2868 8 +46.9278 97.6147 8 +47.0204 98.9521 8 +45.9869 98.3687 8 +47.0106 97.5301 8 +46.7703 96.7064 8 +46.5817 96.6913 8 +46.5698 98.0398 8 +46.4025 97.1813 8 +46.189 98.2358 8 +46.193 97.6883 8 +47.0593 98.0335 8 +46.6658 97.8147 8 +46.4066 97.8696 8 +46.3388 97.914 8 +46.7286 98.4514 8 +46.9915 96.9698 8 +46.9412 97.1415 8 +46.5364 98.9139 8 +46.5315 96.4185 8 +47.1419 97.2853 8 +46.351 98.0415 8 +46.585 98.1207 8 +46.769 96.8816 8 +46.6161 99.2195 8 +46.8233 98.8489 8 +46.4523 96.1711 8 +46.8374 97.4622 8 +46.5149 96.9054 8 +46.602 96.1774 8 +46.5315 95.7907 8 +46.3252 97.3333 8 +46.7356 95.5964 8 +46.8493 97.1612 8 +46.3894 97.0569 8 +46.7776 99.1992 8 +47.0271 98.2515 8 +47.0145 97.8455 8 +46.898 97.5772 8 +46.5732 98.1306 8 +46.6545 98.2411 8 +46.5216 95.1804 8 +46.3795 96.0969 8 +46.9031 96.7382 8 +46.3574 97.2506 8 +47.1661 97.7714 8 +46.6209 99.8443 8 +46.77 97.9611 8 +46.6682 99.1463 8 +46.7765 98.5504 8 +46.9267 96.784 8 +46.5207 97.071 8 +46.5703 97.2067 8 +46.831 98.0702 8 +46.7175 98.2498 8 +46.7156 98.0367 8 +46.9933 96.9021 8 +46.7886 96.9757 8 +46.6007 97.5568 8 +46.5315 98.0102 8 +46.6238 96.7985 8 +47.1479 97.6063 8 +46.4097 96.8193 8 +46.6684 98.1812 8 +46.7959 96.8826 8 +46.8998 97.0426 8 +47.2447 96.8455 8 +46.5496 96.9662 8 +46.9293 98.9393 8 +47.0228 98.5483 8 +46.6132 96.7525 8 +46.6835 96.7918 8 +46.9555 99.3202 8 +46.625 97.9187 8 +46.5252 98.3655 8 +46.7008 98.0457 8 +46.5398 97.3689 8 +46.7512 99.3429 8 +47.0768 99.8496 8 +46.659 98.043 8 +46.5479 97.6389 8 +46.9157 98.0732 8 +46.6428 97.0618 8 +46.4175 98.5782 8 +47.0373 96.5907 8 +46.8521 95.2534 8 +46.2121 97.4255 8 +46.5087 98.0472 8 +46.4243 98.3533 8 +46.5749 97.7495 8 +46.5066 96.8138 8 +47.0033 96.7007 8 +46.3021 96.3472 8 +47.0555 97.6184 8 +46.7625 97.2768 8 +46.9152 96.8095 8 +46.8526 96.4927 8 +46.9735 98.3559 8 +46.5275 96.8696 8 +46.37 98.1412 8 +46.7295 98.0914 8 +46.6313 97.1242 8 +47.0642 97.8177 8 +46.7369 97.1109 8 +46.2172 97.8546 8 +46.3558 97.1101 8 +46.5212 97.8762 8 +47.078 98.0654 8 +46.9496 96.2408 8 +46.4143 96.7127 8 +46.6686 98.2456 8 +45.7663 96.8454 8 +46.9618 97.9479 8 +46.78 98.2831 8 +46.3811 97.5172 8 +47.1949 96.2542 8 +46.8597 98.2963 8 +46.9287 96.9239 8 +46.557 98.3573 8 +47.4469 97.1521 8 +46.8447 97.7708 8 +46.3489 96.9911 8 +46.8837 99.1218 8 +46.3846 97.9074 8 +46.8051 97.1442 8 +47.3268 97.373 8 +46.4207 98.3194 8 +46.5076 99.4655 8 +47.3039 95.6372 8 +46.9581 98.7394 8 +46.8243 97.1014 8 +47.0037 97.4976 8 +46.7505 96.9469 8 +46.6066 96.6853 8 +47.0229 97.6962 8 +46.8556 98.2446 8 +46.9865 97.807 8 +46.5313 97.7366 8 +46.3971 97.28 8 +46.5744 98.289 8 +46.9842 96.9101 8 +46.817 97.9921 8 +46.4645 96.9861 8 +46.1864 95.4522 8 +46.6734 96.5289 8 +46.7991 96.1429 8 +47.2485 96.8359 8 +46.7249 97.6652 8 +46.7152 99.2337 8 +46.7289 96.2303 8 +46.7253 97.4934 8 +47.0489 98.77 8 +46.7341 99.2624 8 +46.4837 98.9432 8 +46.8485 96.8085 8 +46.7738 98.1114 8 +46.4683 97.9079 8 +46.4505 96.4696 8 +46.6628 97.9374 8 +46.792 98.7427 8 +46.9446 96.5463 8 +46.4672 96.9506 8 +46.5609 97.4632 8 +46.5964 96.1828 8 +46.3169 96.7562 8 +47.121 97.4957 8 +46.5687 97.9135 8 +47.214 98.1828 8 +46.4651 96.1499 8 +46.6054 98.6599 8 +46.8178 98.2631 8 +46.8222 97.383 8 +46.6923 96.7786 8 +46.4988 98.0345 8 +46.8991 97.6042 8 +47.0519 96.4753 8 +46.1498 98.8999 8 +46.586 96.35 8 +46.6059 97.8301 8 +47.1183 98.0723 8 +46.6617 97.9003 8 +46.5575 97.9043 8 +46.6516 98.5847 8 +47.0235 97.1376 8 +47.1024 97.3328 8 +46.4445 96.9594 8 +46.5609 98.0655 8 +46.5731 97.5946 8 +46.1865 97.7227 8 +46.5671 98.1244 8 +46.4306 96.3438 8 +46.9301 98.5617 8 +46.8742 98.3594 8 +46.5588 98.7898 8 +46.5237 98.5861 8 +46.4943 97.162 8 +46.5252 98.6681 8 +46.766 98.6994 8 +46.6523 98.6087 8 +46.8653 97.4346 8 +46.6171 97.0944 8 +46.4471 97.8565 8 +46.893 96.7955 8 +46.7267 99.271 8 +46.9025 97.8068 8 +46.2772 98.0083 8 +46.4573 96.9402 8 +46.4523 96.1453 8 +46.4924 97.9978 8 +46.7979 97.0451 8 +47.0281 98.2777 8 +46.6854 98.829 8 +46.2903 96.7216 8 +46.6661 98.73 8 +46.6764 96.1902 8 +46.8709 98.1225 8 +46.9612 98.56 8 +46.8291 99.3309 8 +46.5931 96.7585 8 +47.0305 98.2756 8 +47.0987 98.5335 8 +46.5922 98.4491 8 +46.9719 96.9798 8 +46.5271 97.9006 8 +46.9003 97.1881 8 +46.9146 97.2717 8 +46.7988 97.5314 8 +46.7203 97.0126 8 +46.5724 98.0873 8 +46.1339 98.054 8 +46.3826 97.5336 8 +47.2287 98.2187 8 +46.9248 98.553 8 +46.4297 96.8159 8 +46.3007 96.6835 8 +47.1466 97.0955 8 +47.0695 96.4776 8 +46.726 98.2215 8 +47.0347 97.8555 8 +46.5335 99.3149 8 +46.5477 98.2022 8 +46.9019 96.3167 8 +46.7368 97.262 8 +46.7786 99.7681 8 +46.8741 99.1138 8 +46.5626 99.4614 8 +46.4747 97.4475 8 +46.2026 98.1928 8 +46.3383 98.3835 8 +46.542 97.2429 8 +46.7819 97.6607 8 +46.8051 97.8664 8 +46.6427 98.0271 8 +46.5849 97.398 8 +46.7824 96.4489 8 +46.7976 97.752 8 +46.7184 96.9687 8 +46.7825 98.4931 8 +46.9262 97.9827 8 +46.6928 97.5397 8 +46.6757 97.6326 8 +46.5386 98.556 8 +46.9401 97.3801 8 +47.1088 97.0551 8 +47.404 97.1537 8 +6.9742 63.5598 7 +6.46399 66.146 7 +18.5047 77.5835 7 +16.0333 73.5723 7 +7.42553 74.8369 7 +11.7781 75.2099 7 +13.3548 68.5617 7 +18.0088 72.8295 7 +9.93295 72.9016 7 +12.3635 72.4916 7 +16.8757 72.5421 7 +6.59346 79.6186 7 +11.4979 71.8487 7 +15.8975 79.1598 7 +16.0393 72.5746 7 +18.8133 77.0823 7 +12.974 65.8262 7 +17.7227 70.795 7 +15.8848 77.1236 7 +16.7038 78.8864 7 +14.7131 74.4971 7 +15.008 72.6344 7 +14.0303 76.2621 7 +19.836 74.8614 7 +12.3228 71.7349 7 +11.8228 60.8732 7 +17.1616 66.4786 7 +9.1945 74.8571 7 +10.9675 74.9959 7 +14.0197 75.2624 7 +17.8185 69.8292 7 +14.9716 74.8698 7 +11.3575 69.0807 7 +15.2966 72.657 7 +17.5655 75.8027 7 +13.5258 69.1893 7 +16.7934 67.3642 7 +17.9568 70.4081 7 +9.38253 69.0601 7 +10.0653 74.5443 7 +7.92786 74.4489 7 +14.5688 74.071 7 +12.0616 78.308 7 +18.8568 72.2338 7 +15.0005 77.0597 7 +17.6146 73.2862 7 +14.5691 80.9173 7 +14.5615 73.5849 7 +12.4247 65.1364 7 +21.0351 70.5554 7 +14.4129 66.9985 7 +16.8253 69.0902 7 +13.8975 70.8838 7 +4.83364 70.7908 7 +17.4459 69.786 7 +15.4855 73.1077 7 +6.61716 71.7575 7 +12.7626 67.7246 7 +21.7233 74.3631 7 +15.7184 62.5602 7 +18.4173 69.2612 7 +15.4037 76.1274 7 +16.1142 73.4925 7 +20.2021 67.7087 7 +18.6125 71.3553 7 +15.9821 81.7773 7 +14.7601 70.3693 7 +11.0119 77.4211 7 +14.9101 74.4998 7 +16.4344 79.3438 7 +22.9702 71.7193 7 +5.1016 79.3232 7 +14.3271 76.0561 7 +11.96 84.2657 7 +8.03136 75.8108 7 +11.6875 79.217 7 +13.3976 60.3978 7 +19.1962 77.9851 7 +17.5152 68.3059 7 +21.5956 73.967 7 +13.9858 72.2624 7 +14.5007 67.7301 7 +8.86643 76.7621 7 +11.913 63.5411 7 +17.4928 64.2277 7 +14.662 74.6725 7 +12.9914 71.8402 7 +14.6694 74.8898 7 +11.9876 73.1704 7 +6.79527 67.7802 7 +18.268 79.6573 7 +11.0498 77.0895 7 +18.1086 70.1339 7 +13.6122 74.0688 7 +6.93684 72.113 7 +12.58 77.3262 7 +15.1078 66.2657 7 +16.0514 75.7698 7 +10.383 67.3842 7 +15.9949 73.0173 7 +8.78849 80.0371 7 +15.9425 58.4478 7 +13.8141 68.9628 7 +23.1919 75.9825 7 +9.33767 72.7899 7 +13.1499 77.948 7 +9.31113 66.0853 7 +13.6298 77.9882 7 +14.7806 70.4936 7 +10.7807 77.9293 7 +12.1075 84.2081 7 +18.0637 73.155 7 +12.2869 72.1929 7 +17.8834 78.6057 7 +15.0611 71.2426 7 +12.6032 69.0315 7 +16.11 73.644 7 +17.0151 77.1487 7 +16.9914 76.5998 7 +13.863 67.3368 7 +13.7336 72.1281 7 +15.799 66.3803 7 +17.5132 70.087 7 +11.6782 68.8306 7 +17.9938 70.2958 7 +13.355 77.3186 7 +15.2698 74.2343 7 +21.8976 83.2627 7 +11.1427 82.1626 7 +15.2363 70.1339 7 +11.1334 70.5787 7 +13.1384 74.7592 7 +17.1843 76.3483 7 +16.9459 73.1542 7 +10.6792 78.5428 7 +13.1234 74.1113 7 +18.9347 62.8147 7 +10.8564 65.1915 7 +14.1361 74.144 7 +16.8179 73.4168 7 +20.4314 79.1002 7 +12.5282 71.6858 7 +16.3075 74.0084 7 +12.6015 76.6854 7 +11.4256 72.069 7 +8.67112 73.6595 7 +20.0546 77.4793 7 +5.66921 74.7665 7 +21.1012 86.303 7 +15.3943 70.1011 7 +7.07924 76.6519 7 +15.2409 78.2069 7 +11.3114 73.1903 7 +12.5313 69.8949 7 +9.56799 68.0229 7 +13.2154 72.8227 7 +10.9088 79.7561 7 +10.1041 74.6244 7 +15.213 67.1256 7 +13.5404 68.5892 7 +24.516 72.4898 7 +13.902 65.4107 7 +18.9457 67.3117 7 +15.8751 77.2214 7 +10.0324 70.5172 7 +18.7745 68.0842 7 +11.1172 67.8786 7 +15.6576 78.1547 7 +11.7784 62.7092 7 +10.6007 72.7629 7 +16.4342 70.7504 7 +16.0939 68.6336 7 +7.32682 80.992 7 +21.7923 77.9965 7 +20.7545 72.5261 7 +9.97794 71.7252 7 +16.5896 70.6464 7 +17.7794 70.8952 7 +17.0605 66.86 7 +4.44968 79.6235 7 +19.4552 65.6815 7 +10.8662 80.0937 7 +12.8369 73.5149 7 +14.0044 74.3141 7 +10.4842 72.3611 7 +15.4378 70.5417 7 +7.7826 79.7765 7 +15.2945 77.8664 7 +17.1188 73.3233 7 +17.8253 73.2815 7 +13.4018 68.7243 7 +12.8319 77.1705 7 +11.8416 71.5687 7 +15.4133 68.3427 7 +14.3874 75.0911 7 +14.7618 78.3312 7 +8.56969 76.0649 7 +4.87489 76.7773 7 +14.7324 79.746 7 +16.1758 68.1576 7 +11.6288 72.0451 7 +18.4902 73.4662 7 +3.62344 59.9285 7 +15.5947 74.5344 7 +10.878 79.1342 7 +14.8407 69.6396 7 +2.84344 71.5012 7 +12.4883 66.8669 7 +10.468 64.6173 7 +7.77496 71.3847 7 +18.6877 77.3514 7 +10.2618 81.514 7 +23.1101 77.8435 7 +8.29675 77.0656 7 +13.1048 78.2182 7 +14.0717 77.3593 7 +10.4853 70.9936 7 +8.14661 75.3408 7 +10.9537 72.6611 7 +19.3943 80.9806 7 +19.4368 71.8462 7 +11.8372 69.65 7 +13.8936 71.6775 7 +16.4462 68.2286 7 +9.35932 82.8769 7 +11.4419 75.8901 7 +8.00972 67.9883 7 +16.1423 72.6532 7 +17.5449 72.9405 7 +20.2077 79.7205 7 +12.0972 76.5809 7 +15.0473 66.1835 7 +18.005 68.9914 7 +15.5652 65.9837 7 +8.20881 72.9559 7 +13.2994 69.3226 7 +14.3928 71.4406 7 +13.144 76.8367 7 +13.4069 69.89 7 +15.2506 72.4894 7 +15.4718 65.3772 7 +6.28291 68.7217 7 +17.0008 71.9158 7 +12.782 73.8156 7 +15.6109 71.2024 7 +25.0523 67.318 7 +11.0317 70.1689 7 +14.3198 77.6605 7 +9.76055 76.678 7 +13.009 68.9532 7 +9.03985 70.387 7 +9.91819 67.126 7 +9.39186 67.6286 7 +9.23366 76.9973 7 +9.90062 72.9595 7 +13.7697 69.6652 7 +18.7182 71.6706 7 +19.3225 74.307 7 +18.034 83.5673 7 +18.4821 70.9698 7 +14.2428 70.0197 7 +15.9691 79.5589 7 +17.8546 64.5312 7 +17.3575 74.0294 7 +14.7628 73.0349 7 +17.5428 70.2942 7 +12.409 71.5285 7 +7.64793 75.4301 7 +23.4986 72.5452 7 +8.38578 70.7554 7 +9.747 68.1746 7 +9.07505 71.9796 7 +12.2811 73.9022 7 +11.2408 68.1408 7 +12.8555 73.0838 7 +15.6769 73.0767 7 +15.2056 63.572 7 +18.9136 71.6167 7 +11.0493 76.097 7 +14.999 79.7878 7 +17.6008 72.28 7 +7.44971 81.2882 7 +12.2055 76.7956 7 +18.1146 71.9282 7 +13.7783 78.709 7 +26.147 73.308 7 +16.1113 76.1851 7 +15.8876 74.961 7 +13.2603 72.4898 7 +20.6139 74.1227 7 +15.5693 72.1147 7 +7.4477 74.1965 7 +13.3477 72.3795 7 +11.4621 82.6934 7 +13.2552 81.1053 7 +15.5997 70.0399 7 +13.6189 80.0286 7 +11.752 78.6136 7 +11.9002 70.894 7 +15.2897 82.206 7 +14.2906 74.9315 7 +11.0522 73.673 7 +22.7165 64.5184 7 +15.378 77.9423 7 +10.8619 70.9644 7 +9.65983 76.2478 7 +15.5432 71.3917 7 +15.8865 75.6598 7 +12.1625 77.7504 7 +9.74072 70.1159 7 +15.6409 70.2935 7 +12.8535 76.8015 7 +13.4595 76.9247 7 +20.7965 72.3806 7 +18.9609 72.8208 7 +22.3784 75.6609 7 +14.1641 72.1781 7 +9.92617 69.1983 7 +18.2911 69.3891 7 +15.3908 72.8343 7 +10.0663 75.3633 7 +12.7845 67.7347 7 +12.7302 72.6837 7 +12.6735 67.9715 7 +16.9401 68.9921 7 +9.40018 70.906 7 +14.7253 71.9753 7 +5.26614 77.5098 7 +9.76337 68.8844 7 +16.3041 80.022 7 +18.6544 80.0636 7 +20.5745 76.1862 7 +13.8585 63.6911 7 +9.7573 63.8881 7 +12.1147 73.6008 7 +10.8968 73.0989 7 +12.5356 75.0092 7 +7.43643 74.1687 7 +13.3259 69.9454 7 +16.6829 75.7218 7 +12.5697 70.5723 7 +10.3905 75.958 7 +18.9164 76.0827 7 +14.6007 72.0524 7 +19.4285 74.9735 7 +19.9799 75.5132 7 +15.5005 68.7026 7 +16.0318 67.8982 7 +21.0952 64.5587 7 +13.9007 74.8945 7 +19.6489 74.7528 7 +12.4929 71.4185 7 +17.6386 76.1382 7 +8.57432 82.6621 7 +9.58557 66.1414 7 +11.0456 69.5803 7 +12.1605 70.8958 7 +14.9477 78.2299 7 +17.7285 67.1226 7 +13.2754 79.3836 7 +10.229 76.4249 7 +14.0693 71.434 7 +12.8931 71.7727 7 +17.9009 71.8102 7 +13.2442 77.9717 7 +9.36279 71.5327 7 +13.0456 63.7823 7 +9.42968 66.6865 7 +14.5659 72.133 7 +21.7401 73.3919 7 +11.9362 71.9542 7 +7.55315 76.3411 7 +9.42557 72.671 7 +17.4073 74.5066 7 +16.0269 73.4295 7 +7.34307 77.196 7 +16.7426 70.0379 7 +12.9911 75.7311 7 +16.858 69.2427 7 +16.0424 76.8963 7 +17.2367 81.0253 7 +18.8085 79.1206 7 +13.228 74.7781 7 +7.82159 70.8112 7 +8.82195 74.3393 7 +18.0928 62.4608 7 +14.4714 78.7609 7 +17.2222 70.2953 7 +14.0585 66.8945 7 +15.1509 71.3675 7 +23.0115 77.1704 7 +10.7838 66.9981 7 +14.0673 71.4014 7 +20.0259 75.849 7 +13.735 74.2524 7 +19.1428 75.8848 7 +14.5204 72.0799 7 +12.9293 71.9116 7 +7.91306 70.0406 7 +11.1569 72.5301 7 +18.5769 82.9214 7 +17.0431 77.3224 7 +19.8204 72.0764 7 +15.1146 73.3423 7 +14.9551 81.5398 7 +16.7977 64.5207 7 +20.8961 73.9012 7 +11.3243 75.4182 7 +15.4702 64.015 7 +12.9239 82.308 7 +13.1114 72.7146 7 +13.221 81.1251 7 +23.681 71.2745 7 +4.019 76.7883 7 +12.4485 75.9931 7 +19.9562 64.5198 7 +13.851 71.5423 7 +11.163 66.8932 7 +14.6376 76.2576 7 +16.9634 70.2364 7 +19.0134 78.3643 7 +10.6944 72.2111 7 +16.2133 65.9127 7 +10.9631 72.7751 7 +11.3727 71.7992 7 +18.5126 76.2785 7 +15.9101 74.2728 7 +18.5133 76.754 7 +15.8657 82.2787 7 +9.9406 78.2441 7 +14.0614 71.4062 7 +11.6339 73.6409 7 +18.1891 77.3399 7 +14.2462 70.3142 7 +14.2587 68.6824 7 +14.1859 77.6699 7 +41.4421 95.1835 8 +49.9689 93.1219 8 +48.9502 98.5986 8 +48.8835 101.19 8 +50.1349 94.0788 8 +44.9024 96.1416 8 +47.4277 96.6013 8 +48.7175 98.3238 8 +49.6 98.8651 8 +49.647 97.3412 8 +51.0073 96.0242 8 +45.4451 105.71 8 +52.1357 97.8324 8 +47.5369 96.3437 8 +48.0226 98.1668 8 +50.0173 97.4693 8 +46.9606 98.8998 8 +52.3675 98.3242 8 +47.3761 95.6861 8 +50.4993 95.3446 8 +48.3599 95.8236 8 +53.2012 99.5836 8 +48.834 97.0675 8 +51.4258 97.8536 8 +48.2486 98.0379 8 +50.5352 95.2385 8 +51.966 94.314 8 +51.0185 97.0484 8 +53.4679 93.897 8 +51.7624 94.7498 8 +55.3625 99.6402 8 +50.1651 95.5381 8 +48.5293 97.2518 8 +47.6447 97.9821 8 +50.6167 97.58 8 +50.9469 97.2312 8 +50.3737 98.3207 8 +50.9797 98.5861 8 +53.1431 97.0138 8 +45.5952 98.8883 8 +54.1421 95.9169 8 +51.5126 99.1836 8 +49.3575 94.2565 8 +55.9648 101.242 8 +54.0428 96.5008 8 +50.9739 97.871 8 +49.7275 93.3433 8 +52.4788 96.101 8 +47.9087 98.787 8 +49.5041 95.175 8 +51.7279 96.4927 8 +50.3544 99.4839 8 +48.0173 95.9962 8 +48.7575 95.0564 8 +45.5439 96.7317 8 +47.2433 92.9991 8 +50.1988 92.8083 8 +50.4409 95.9461 8 +51.6926 96.0898 8 +50.5479 97.1375 8 +47.9703 97.8309 8 +55.3622 97.4572 8 +51.2496 95.7789 8 +53.0253 96.6107 8 +48.7691 97.7165 8 +52.5326 99.717 8 +47.4153 96.1176 8 +54.98 100.573 8 +50.2622 99.4942 8 +46.1076 97.2104 8 +46.0329 94.5252 8 +51.6916 95.1614 8 +46.5102 96.4943 8 +51.3057 94.2738 8 +44.0614 94.5153 8 +51.6252 97.2491 8 +46.6135 99.319 8 +52.2948 98.226 8 +48.1176 98.1658 8 +51.9199 95.6656 8 +49.6601 97.6666 8 +48.2809 97.1118 8 +50.6258 98.7189 8 +54.5118 97.0744 8 +47.948 98.1689 8 +49.2226 94.6523 8 +53.3937 96.3825 8 +53.1772 96.6464 8 +53.2555 96.4591 8 +51.606 98.8852 8 +47.2193 96.1011 8 +45.934 98.4114 8 +47.952 92.6304 8 +51.9725 96.3493 8 +52.9004 102.211 8 +48.9986 96.982 8 +48.3003 96.289 8 +47.2406 96.6319 8 +45.0341 95.9396 8 +50.452 96.4533 8 +55.8699 93.6161 8 +49.1143 96.7294 8 +49.5852 99.4858 8 +46.9503 96.2251 8 +46.9918 95.9268 8 +50.3754 97.1761 8 +50.7271 100.905 8 +46.92 95.0981 8 +54.6489 96.057 8 +51.3893 93.5392 8 +42.223 98.2652 8 +47.255 96.2813 8 +50.7468 100.008 8 +53.5001 98.5525 8 +50.0758 95.7402 8 +52.6382 97.9511 8 +50.7758 93.3224 8 +49.7789 95.0243 8 +53.3533 95.3494 8 +50.7794 96.8392 8 +48.6835 93.7599 8 +50.5545 100.139 8 +49.9814 99.9025 8 +49.4176 100.063 8 +49.3004 98.1639 8 +51.9416 99.8599 8 +50.779 97.6581 8 +47.4913 95.4818 8 +50.0526 96.9909 8 +51.8662 98.7923 8 +45.192 96.118 8 +52.0513 95.2885 8 +45.1058 98.8115 8 +97.3191 68.0847 9 +99.9103 67.9731 9 +101.142 68.0599 9 +95.8612 68.0137 9 +95.3405 68.0971 9 +96.6713 68.2601 9 +97.7959 67.9033 9 +99.3944 68.066 9 +98.8196 68.1389 9 +100.835 68.3521 9 +96.0567 68.2631 9 +97.7124 67.987 9 +97.6818 68.1729 9 +95.6442 68.2786 9 +94.9751 67.9418 9 +97.0649 68.1848 9 +98.1745 68.299 9 +97.5609 68.0262 9 +97.6705 67.9386 9 +101.017 68.0252 9 +96.6478 68.1323 9 +94.2996 68.1649 9 +96.9756 68.3145 9 +97.2107 67.9364 9 +97.7873 68.2199 9 +97.1539 68.1341 9 +94.7383 68.2297 9 +101.351 68.0265 9 +95.6913 67.955 9 +98.0526 67.943 9 +97.6307 68.0589 9 +96.5153 68.0757 9 +99.7218 68.0519 9 +100.13 68.0103 9 +96.6848 68.0285 9 +98.2577 68.0187 9 +97.8715 68.1369 9 +95.303 68.0653 9 +96.7226 68.0783 9 +96.6646 68.1718 9 +102.01 68.0171 9 +92.8552 68.1594 9 +98.4827 68.0471 9 +98.677 68.3001 9 +94.9963 68.1207 9 +95.0845 68.2416 9 +95.2289 67.9679 9 +98.8395 68.1763 9 +97.5372 67.8789 9 +95.0989 68.0631 9 +96.2249 68.1139 9 +100.754 67.9854 9 +94.6755 68.0948 9 +95.0181 67.8509 9 +98.3966 68.1505 9 +95.9037 68.2702 9 +98.3384 67.9264 9 +98.3108 68.0733 9 +98.3052 68.0953 9 +96.3574 68.0066 9 +97.6805 68.024 9 +98.1658 68.0928 9 +95.5992 68.1486 9 +96.6595 68.1624 9 +96.3046 68.1027 9 +97.6432 68.2355 9 +97.8414 67.9624 9 +99.2772 67.7924 9 +99.1261 68.0036 9 +100.67 68.1046 9 +97.6889 68.172 9 +99.9417 67.9191 9 +95.1743 68.2626 9 +98.7606 67.9607 9 +99.7031 68.0427 9 +94.3437 67.9619 9 +95.6103 68.2285 9 +97.7253 68.3245 9 +97.323 67.9701 9 +97.691 67.9551 9 +97.5687 68.1529 9 +97.2912 67.8588 9 +100.286 68.0849 9 +97.8297 67.9631 9 +95.4533 68.5077 9 +96.3836 68.1377 9 +95.3567 68.0426 9 +98.4426 68.0826 9 +94.4767 68.1639 9 +98.2559 68.0158 9 +96.5007 67.9212 9 +96.8852 68.1787 9 +96.834 67.9841 9 +98.4335 68.2043 9 \ No newline at end of file diff --git a/data/2d_4c.data b/data/2d_4c.data new file mode 100644 index 0000000..f9045b5 --- /dev/null +++ b/data/2d_4c.data @@ -0,0 +1,2991 @@ +2990 +1.00007 40.9378 0 +0.99736 41.1714 0 +0.134799 41.8113 0 +2.47585 41.6346 0 +-3.0587 41.3887 0 +0.73266 41.4888 0 +0.35745 41.8429 0 +0.157674 41.7513 0 +2.69103 41.8298 0 +0.536346 41.5344 0 +2.46873 41.4813 0 +-1.91946 40.8824 0 +3.44394 41.3349 0 +2.88157 41.1534 0 +-0.53933 41.4057 0 +-0.0276636 41.1127 0 +0.0933292 41.0051 0 +0.209173 41.7993 0 +-0.0668266 41.7829 0 +1.79969 42.3177 0 +0.510155 41.6298 0 +0.138588 41.1531 0 +-0.0175984 41.694 0 +0.618498 41.4093 0 +-2.63433 41.9534 0 +2.01141 41.222 0 +5.57577 41.5869 0 +1.40539 41.53 0 +3.55797 41.8688 0 +2.68052 41.3868 0 +2.95654 41.486 0 +-0.391807 41.2361 0 +4.00381 41.4221 0 +1.44796 41.0426 0 +0.201187 41.4562 0 +0.795719 41.6564 0 +0.502018 41.5292 0 +0.290078 41.6987 0 +1.19913 40.799 0 +-1.28096 41.1171 0 +0.030134 41.4093 0 +1.99597 41.7064 0 +3.11367 41.4872 0 +0.546399 41.5257 0 +-1.00433 41.3616 0 +1.22587 42.0243 0 +-0.202468 41.863 0 +-1.40362 40.9709 0 +0.977844 40.6544 0 +2.66858 41.613 0 +3.87692 41.5591 0 +2.62824 41.4168 0 +2.06543 41.3289 0 +-1.63482 41.3223 0 +2.00123 41.8628 0 +3.64504 42.0131 0 +-2.36311 41.4501 0 +2.6411 41.6433 0 +-2.92099 40.9228 0 +1.66685 41.3844 0 +1.35976 41.4936 0 +2.40343 42.0717 0 +-0.156466 41.3901 0 +-0.149501 41.3361 0 +2.31285 41.3771 0 +2.73428 41.6682 0 +0.703931 40.8069 0 +2.65785 41.2811 0 +4.18733 41.6706 0 +0.21038 41.3822 0 +-2.37222 41.5596 0 +2.14842 42.1958 0 +3.90696 41.487 0 +0.805582 40.9885 0 +2.88554 41.7446 0 +0.4224 41.6881 0 +4.28893 41.7292 0 +0.709065 41.6168 0 +-1.114 41.4017 0 +0.00767159 41.3293 0 +2.98833 41.0246 0 +-0.895292 41.5051 0 +3.71451 41.4277 0 +-0.34788 40.9151 0 +3.6333 41.5624 0 +3.86924 41.0564 0 +-0.228855 40.791 0 +3.10995 41.9408 0 +2.41484 41.1329 0 +3.09267 41.8441 0 +-1.40569 40.9844 0 +2.83167 41.5767 0 +-2.08925 41.8549 0 +-0.0413047 41.4111 0 +0.99321 41.2289 0 +5.49799 42.229 0 +4.56593 41.3131 0 +2.62767 41.2001 0 +1.86702 41.0572 0 +0.99447 40.9706 0 +1.35799 41.9985 0 +0.965753 41.2944 0 +5.09559 41.0741 0 +1.36247 41.1762 0 +1.69922 41.2959 0 +3.16355 41.7048 0 +5.25389 41.8303 0 +0.531934 41.5568 0 +3.28948 41.5843 0 +0.10212 41.6421 0 +-2.09836 41.0296 0 +1.1946 41.225 0 +0.0879961 41.7027 0 +-0.344577 41.9871 0 +-0.195498 41.2088 0 +2.2287 41.8828 0 +3.68595 41.7489 0 +2.78496 41.4375 0 +-1.03866 41.3832 0 +0.83488 40.8743 0 +1.10206 41.6165 0 +2.73045 42.2562 0 +1.85942 42.4662 0 +-2.90953 41.7232 0 +3.17061 41.78 0 +-1.28675 41.7713 0 +3.19275 41.3024 0 +2.44799 41.3377 0 +1.01221 41.3916 0 +2.86381 41.3201 0 +2.53895 41.8226 0 +0.652358 41.6833 0 +2.95625 41.2105 0 +2.05624 41.7799 0 +2.73907 41.5838 0 +0.19292 41.4039 0 +-1.90824 41.2266 0 +3.31292 41.8747 0 +-1.17188 41.499 0 +-1.19959 41.2945 0 +3.40639 41.4131 0 +-0.309029 41.7895 0 +2.29291 41.4736 0 +2.85405 41.4468 0 +0.906787 41.8417 0 +1.03301 41.6805 0 +2.7908 41.5484 0 +1.60142 41.0711 0 +3.07553 41.3319 0 +2.66801 41.3151 0 +1.57486 41.8305 0 +4.79379 42.3375 0 +0.683916 41.4464 0 +4.30425 41.5736 0 +-4.99684 41.4194 0 +0.407559 41.5083 0 +1.31942 41.2904 0 +-2.36349 41.9116 0 +4.31274 41.5094 0 +3.94453 41.3956 0 +46.3802 3.32142 1 +48.4628 3.09102 1 +46.1492 3.13285 1 +48.8009 2.98271 1 +46.13 3.22293 1 +48.8492 3.34834 1 +52.4008 2.66164 1 +45.6532 2.92506 1 +51.7098 3.12781 1 +49.3856 2.97191 1 +54.8398 3.09188 1 +51.3912 3.04305 1 +48.7477 2.88549 1 +47.3895 3.08509 1 +45.5833 3.42697 1 +52.1513 3.39225 1 +54.7523 3.18117 1 +47.9111 3.25294 1 +43.0308 3.16003 1 +52.5527 2.9644 1 +51.0376 3.12574 1 +39.7875 3.24483 1 +51.4247 3.02434 1 +54.9527 3.11502 1 +55.269 3.23374 1 +51.6444 3.05482 1 +52.7037 3.40248 1 +47.3123 3.11889 1 +39.9097 3.19928 1 +46.9546 3.21672 1 +54.7801 3.45151 1 +46.8688 3.30554 1 +50.7167 3.3011 1 +43.3099 3.13502 1 +49.0462 3.30432 1 +46.7978 3.14741 1 +39.1666 3.25898 1 +52.8303 3.2864 1 +43.5847 3.09874 1 +43.8313 3.26131 1 +47.0354 3.37726 1 +43.8303 3.00101 1 +49.2136 2.82901 1 +53.0703 3.25768 1 +51.5605 3.13051 1 +51.6565 3.03276 1 +54.6803 3.21761 1 +52.8974 3.11975 1 +49.8031 3.24972 1 +42.8679 3.06868 1 +49.5025 3.32133 1 +48.1066 3.25607 1 +47.5742 3.31038 1 +47.9516 3.0661 1 +45.6754 3.06525 1 +53.5019 3.2174 1 +56.9209 3.22393 1 +46.6076 3.35139 1 +45.2508 3.26453 1 +46.0753 3.31525 1 +49.2275 2.83737 1 +48.5368 3.22135 1 +51.592 3.38263 1 +52.079 3.253 1 +47.6605 3.08802 1 +52.4266 3.27257 1 +47.2102 3.07995 1 +51.7235 3.18778 1 +48.3572 3.40303 1 +50.4224 3.43891 1 +48.8457 3.17306 1 +52.3564 3.11401 1 +47.8073 3.37175 1 +45.2018 3.14158 1 +42.0126 3.31301 1 +47.1974 3.31478 1 +44.5805 3.09813 1 +47.9305 3.36138 1 +46.6296 3.05323 1 +51.7158 3.24734 1 +48.241 3.1586 1 +43.1457 3.10903 1 +53.5328 3.23527 1 +51.2686 3.05155 1 +52.6787 3.26477 1 +47.3229 3.25546 1 +50.6885 2.86228 1 +56.2172 3.26755 1 +52.5805 3.00891 1 +41.348 3.07628 1 +44.471 3.22271 1 +45.5043 3.17306 1 +52.9761 3.46274 1 +48.554 2.92317 1 +51.0304 3.05824 1 +55.3886 3.30659 1 +43.4255 3.25965 1 +51.9739 3.21241 1 +55.4508 3.21214 1 +48.8366 3.10592 1 +49.6574 3.43084 1 +48.2048 3.10344 1 +48.3355 3.2727 1 +51.1717 2.86299 1 +48.2203 3.30793 1 +45.1759 3.38008 1 +52.557 3.41086 1 +50.9924 2.98479 1 +49.8621 3.36127 1 +49.4336 3.19372 1 +48.7223 3.22935 1 +46.0376 3.53939 1 +51.1494 3.09522 1 +51.5877 3.53584 1 +54.3164 3.11213 1 +55.9106 3.02007 1 +51.3509 3.13694 1 +43.6607 3.15844 1 +50.3681 3.26108 1 +52.1362 3.10912 1 +45.1316 3.19939 1 +49.7714 2.84767 1 +45.1409 3.17001 1 +48.7293 3.39143 1 +55.6218 3.21222 1 +45.5667 3.1683 1 +50.5703 3.15988 1 +40.4224 3.12012 1 +46.9099 2.99161 1 +48.3726 2.85729 1 +46.6999 3.18883 1 +54.7413 3.47117 1 +47.3751 3.41105 1 +46.3036 3.33763 1 +45.4987 3.39797 1 +46.846 3.31468 1 +51.7251 3.43504 1 +45.2973 2.98033 1 +49.8244 3.21477 1 +47.2907 3.14332 1 +55.7865 3.11092 1 +47.5147 3.13047 1 +51.9523 3.20358 1 +53.7048 3.15458 1 +55.4817 2.9708 1 +47.0661 2.97888 1 +51.1148 3.04882 1 +55.7009 3.23165 1 +49.0926 3.0482 1 +49.2104 2.91954 1 +48.1315 3.1167 1 +43.8467 3.23859 1 +51.1212 3.10171 1 +48.241 3.27221 1 +48.7886 3.24547 1 +52.8058 3.31464 1 +54.6923 3.14978 1 +52.6505 3.483 1 +48.0059 3.01747 1 +43.2217 3.1709 1 +45.0373 3.21427 1 +50.8902 2.88582 1 +52.6745 3.24796 1 +49.427 3.25409 1 +47.8334 3.05406 1 +51.2101 3.08916 1 +46.2907 3.33246 1 +46.9564 3.06804 1 +48.7533 3.26383 1 +41.4118 3.22717 1 +57.1937 3.19327 1 +49.6908 3.18739 1 +48.1525 3.45527 1 +49.0834 2.90239 1 +45.3508 3.43377 1 +50.7461 3.29786 1 +48.4637 3.24045 1 +53.1632 3.14422 1 +44.9922 3.276 1 +52.8385 3.36757 1 +55.1785 2.78434 1 +52.6964 3.06467 1 +52.3657 3.04656 1 +52.695 2.99897 1 +47.426 2.99716 1 +45.3452 3.15207 1 +45.2563 2.95095 1 +44.9966 3.2906 1 +50.3892 3.10151 1 +42.8576 3.18715 1 +52.9982 3.05736 1 +50.0296 3.14682 1 +48.4227 3.12249 1 +45.8861 2.99218 1 +50.1186 3.39889 1 +42.2795 3.03919 1 +47.6122 2.89763 1 +44.026 3.10352 1 +49.8229 3.23362 1 +42.2478 3.25066 1 +51.3718 3.3026 1 +52.9524 3.12044 1 +51.347 3.30349 1 +49.2108 3.11055 1 +46.7317 3.08488 1 +38.398 3.33134 1 +49.4036 3.14496 1 +48.2214 3.32088 1 +38.0886 3.25209 1 +51.0267 2.86896 1 +40.9795 3.14887 1 +50.4044 3.33867 1 +48.3125 3.05636 1 +58.1081 3.45579 1 +48.4837 2.77284 1 +44.6498 3.00221 1 +48.0957 3.12917 1 +51.6222 3.31966 1 +50.5266 3.00372 1 +55.8049 3.2521 1 +44.3543 3.03395 1 +51.7189 3.2616 1 +53.1411 2.97594 1 +49.0658 3.16308 1 +43.6292 3.28213 1 +46.6628 3.07487 1 +49.0 3.25821 1 +51.1193 3.28436 1 +48.537 3.39792 1 +51.1833 3.16959 1 +50.7161 3.29627 1 +42.8636 3.07529 1 +49.4004 3.31495 1 +52.8072 3.51344 1 +44.2475 3.20818 1 +48.1885 3.19024 1 +48.0431 3.19459 1 +44.0315 3.38755 1 +45.6412 3.33712 1 +43.1365 3.05084 1 +47.0187 3.23208 1 +51.5345 3.38118 1 +57.173 3.32384 1 +44.6304 3.15582 1 +51.4211 3.42271 1 +47.8996 3.34198 1 +50.7063 3.26427 1 +51.7951 3.02464 1 +46.7669 3.3198 1 +55.0914 3.26275 1 +46.1609 3.08328 1 +44.2276 3.02086 1 +47.1665 3.08554 1 +49.9811 3.05603 1 +52.716 2.99968 1 +49.7461 3.31221 1 +50.5154 2.95242 1 +48.383 3.25018 1 +52.7087 2.79629 1 +44.2069 3.17022 1 +51.2816 3.11025 1 +46.0121 3.36816 1 +45.672 3.02456 1 +56.4607 3.18282 1 +39.4447 2.97675 1 +53.1977 3.4076 1 +48.1868 3.24323 1 +45.7023 3.11071 1 +46.9664 3.37809 1 +46.7991 3.28213 1 +53.2534 3.37943 1 +51.7157 3.14671 1 +43.9658 3.28225 1 +49.6987 3.5289 1 +47.755 3.08917 1 +48.7549 2.9592 1 +47.8815 3.30628 1 +47.6413 3.00383 1 +50.7445 3.20133 1 +51.4968 3.11166 1 +48.0207 3.00295 1 +51.4464 3.2879 1 +45.2989 3.0688 1 +41.2781 3.04708 1 +48.9077 3.32952 1 +51.8702 3.37652 1 +45.7139 2.99215 1 +46.0954 3.25909 1 +47.809 3.31064 1 +49.129 3.37745 1 +46.5891 3.21292 1 +45.8006 3.28586 1 +49.1638 3.41501 1 +51.1161 3.20525 1 +46.8335 3.27148 1 +49.3144 3.14129 1 +47.488 3.1997 1 +46.7548 3.04395 1 +52.4264 3.1654 1 +40.174 3.10943 1 +49.4648 3.22927 1 +51.5877 3.06211 1 +45.8653 3.36263 1 +44.6298 3.20112 1 +44.3965 3.39205 1 +47.911 3.30222 1 +49.4857 3.23339 1 +56.1655 3.05991 1 +53.602 3.25718 1 +56.3524 3.02202 1 +50.1797 3.27069 1 +47.9044 3.09403 1 +45.6034 3.06824 1 +48.638 3.33807 1 +45.1189 3.48732 1 +52.2518 3.45751 1 +55.5827 3.25323 1 +49.7789 2.9981 1 +45.8278 2.93058 1 +59.3848 3.20105 1 +56.9081 3.28189 1 +50.2923 3.11007 1 +49.6901 3.33219 1 +50.4372 3.33817 1 +46.6901 2.90752 1 +43.0592 3.07746 1 +53.0521 3.31728 1 +51.6457 2.91166 1 +56.4155 3.16169 1 +48.1242 3.06898 1 +51.1564 3.138 1 +45.9108 3.00238 1 +41.8679 3.41625 1 +45.2634 3.32542 1 +48.371 3.04901 1 +51.7331 3.12092 1 +55.2505 2.87529 1 +50.4898 3.26063 1 +45.7229 3.02482 1 +53.2487 3.12843 1 +40.7495 3.11301 1 +54.4269 3.0139 1 +49.8631 3.20293 1 +51.3726 3.2277 1 +45.2361 3.07773 1 +48.4523 3.07081 1 +46.287 3.13189 1 +50.3515 3.27347 1 +44.9904 3.26817 1 +42.4476 3.27972 1 +47.3749 3.03735 1 +53.4555 3.31727 1 +48.4153 3.1094 1 +53.7926 3.04449 1 +54.0196 3.39215 1 +50.2666 3.36189 1 +52.443 3.01037 1 +48.3527 3.33365 1 +48.1739 3.45715 1 +47.1748 3.10138 1 +51.9233 3.25977 1 +43.4883 3.18882 1 +54.9576 3.1186 1 +48.4501 3.26485 1 +54.5546 3.1002 1 +46.7135 3.17809 1 +49.1796 3.06229 1 +45.108 3.00187 1 +45.3851 3.18066 1 +47.5917 3.02068 1 +42.1095 3.29195 1 +47.5234 3.24008 1 +49.1828 3.21735 1 +47.529 3.169 1 +48.2168 3.20558 1 +51.3444 3.50515 1 +56.7801 3.12952 1 +43.376 3.11452 1 +51.6813 3.05728 1 +46.4761 3.33867 1 +42.7989 3.28225 1 +48.2147 3.33388 1 +43.8398 3.21452 1 +45.3259 3.32341 1 +42.4857 3.12416 1 +53.3488 3.00662 1 +40.6202 3.31405 1 +47.8093 3.37327 1 +53.1658 3.05509 1 +49.9901 3.30853 1 +46.1864 3.25731 1 +53.3771 3.31825 1 +45.314 2.97054 1 +43.5727 3.38909 1 +46.3295 2.95946 1 +52.0035 3.36222 1 +47.0441 3.09477 1 +46.4137 3.36186 1 +48.4922 2.88955 1 +47.4296 2.91461 1 +52.8988 3.00928 1 +51.0569 3.26932 1 +45.0936 3.10621 1 +51.7982 3.06612 1 +50.047 3.18173 1 +46.3997 3.47319 1 +40.6815 3.26614 1 +50.7804 3.14651 1 +50.945 3.00502 1 +53.8828 2.77829 1 +44.4023 3.38764 1 +48.7407 2.96121 1 +41.8816 3.10102 1 +50.8409 3.1567 1 +47.3503 3.31003 1 +45.4192 3.08922 1 +44.6007 3.45986 1 +45.7837 3.1961 1 +49.0422 3.00113 1 +56.4355 3.05265 1 +46.9315 3.03045 1 +48.6428 2.99467 1 +49.1295 3.08512 1 +51.5027 3.2787 1 +37.855 3.03425 1 +53.5651 2.99958 1 +52.905 3.19491 1 +52.0593 3.27347 1 +42.5397 3.19292 1 +46.9304 3.24266 1 +47.8697 3.28761 1 +48.4161 3.40762 1 +49.9486 3.16326 1 +48.4125 3.09489 1 +50.6681 3.49667 1 +46.5242 3.41124 1 +50.5101 3.56525 1 +48.7909 3.38031 1 +52.6336 3.37625 1 +46.7003 3.37347 1 +51.8202 3.02563 1 +52.3359 2.98045 1 +51.3504 3.27101 1 +47.2302 3.17823 1 +49.3377 3.2678 1 +47.4029 3.00885 1 +44.8973 3.0369 1 +51.1332 3.0311 1 +49.4433 3.16302 1 +50.8831 3.23256 1 +43.8155 3.08257 1 +48.1016 3.13554 1 +37.6605 3.24663 1 +51.6785 3.26059 1 +49.4207 3.07894 1 +48.2709 2.89937 1 +51.1283 3.07072 1 +47.2327 3.21821 1 +45.4456 2.98875 1 +57.0703 3.31448 1 +51.6428 3.34001 1 +51.6533 2.88381 1 +50.63 3.10976 1 +43.6541 3.14525 1 +53.4491 3.00302 1 +52.5741 3.26348 1 +48.216 3.32503 1 +49.352 3.24349 1 +45.4329 3.44311 1 +44.5352 3.18291 1 +47.031 3.08933 1 +48.2176 3.00225 1 +52.4414 3.05054 1 +46.6631 2.86697 1 +47.6167 3.10341 1 +48.9153 3.0127 1 +50.8521 2.94517 1 +42.3533 3.09931 1 +51.3696 3.12944 1 +51.3345 3.09018 1 +43.6623 3.41723 1 +46.6873 3.09785 1 +47.045 3.10088 1 +47.2197 3.30685 1 +51.1561 3.52719 1 +53.3846 2.99178 1 +50.2928 3.42872 1 +47.7987 3.20889 1 +46.4311 3.19132 1 +51.3061 2.96329 1 +44.7023 3.2151 1 +49.7588 2.88182 1 +44.1186 3.21516 1 +47.3292 3.00484 1 +41.8121 3.11807 1 +38.6818 3.23351 1 +46.0823 3.23881 1 +86.4786 43.0231 2 +90.5166 46.1754 2 +89.2814 44.9217 2 +84.9356 51.8863 2 +85.5441 47.9452 2 +88.371 51.2428 2 +92.554 47.3903 2 +96.9115 50.199 2 +85.6855 45.3967 2 +90.7706 41.4383 2 +88.8817 53.4048 2 +94.5828 49.3152 2 +85.2334 47.6874 2 +86.1995 53.5157 2 +85.21 50.9604 2 +94.0564 48.241 2 +87.3753 43.7219 2 +85.3393 39.4274 2 +90.9115 45.6575 2 +90.5645 49.3189 2 +89.8818 42.9256 2 +84.6589 57.9173 2 +86.5223 44.953 2 +89.7094 50.688 2 +87.6717 45.994 2 +93.0334 49.4908 2 +91.3684 49.0288 2 +86.552 45.5235 2 +88.4861 44.9406 2 +92.2209 49.4438 2 +88.5739 45.4714 2 +85.721 51.4256 2 +87.4631 55.8705 2 +89.9723 50.5565 2 +86.514 43.5825 2 +85.8972 40.6694 2 +94.2403 46.7061 2 +89.6243 46.4683 2 +83.556 39.6034 2 +88.8591 44.4038 2 +86.9261 45.0167 2 +88.4302 48.1385 2 +90.9127 43.9326 2 +87.414 47.85 2 +94.1278 49.1223 2 +85.3379 50.7741 2 +89.6671 41.6763 2 +88.7917 46.7319 2 +85.7231 46.2902 2 +85.9244 52.2396 2 +89.4591 44.9787 2 +87.64 44.2899 2 +89.3194 48.0031 2 +84.5089 41.3523 2 +87.674 48.3026 2 +86.8302 53.5616 2 +91.1842 49.8113 2 +89.9145 55.4672 2 +92.5937 59.081 2 +85.9683 52.5082 2 +86.4609 53.6659 2 +87.0482 48.1905 2 +95.197 45.2427 2 +93.4848 43.8534 2 +82.6953 49.1193 2 +86.5811 53.1177 2 +84.0562 47.3221 2 +92.4917 49.4388 2 +84.1925 49.5229 2 +91.2156 42.083 2 +87.1048 43.0394 2 +94.3474 43.4886 2 +87.3667 53.8325 2 +92.0275 47.5645 2 +86.5159 51.5866 2 +87.7532 53.4529 2 +89.597 43.1592 2 +89.655 40.6216 2 +84.6928 45.5548 2 +91.7639 48.3699 2 +92.6607 49.8629 2 +86.555 49.3919 2 +90.8054 47.5149 2 +86.1772 50.0533 2 +91.7656 50.4225 2 +89.3769 47.5726 2 +85.1607 52.3038 2 +84.704 40.4872 2 +94.8569 48.781 2 +90.535 43.1931 2 +95.8752 43.3556 2 +83.6924 43.3161 2 +89.2377 44.3606 2 +84.3062 46.7992 2 +83.5389 53.7744 2 +89.2846 44.9876 2 +86.7638 52.1358 2 +88.2236 42.7809 2 +86.3139 41.4031 2 +92.0585 50.6343 2 +88.81 62.4678 2 +86.1412 46.1583 2 +91.2111 51.015 2 +90.1774 44.4296 2 +88.652 39.9193 2 +91.3123 45.6877 2 +85.9216 46.2768 2 +90.6827 42.4833 2 +88.5398 44.8324 2 +89.8672 45.4424 2 +90.9917 48.2749 2 +88.2335 48.5318 2 +89.2344 50.5561 2 +88.7892 52.6681 2 +85.1552 52.6832 2 +88.7378 53.8588 2 +87.7561 41.5831 2 +93.7412 46.4636 2 +86.2986 51.1928 2 +86.9153 44.3384 2 +86.9154 49.1602 2 +90.8443 45.4698 2 +87.992 49.4111 2 +89.8717 51.5685 2 +88.6999 39.1328 2 +89.6743 49.6021 2 +87.3297 44.6507 2 +89.577 47.7356 2 +92.0662 48.3302 2 +89.0368 50.1882 2 +86.7379 45.9187 2 +86.3596 48.6252 2 +90.0337 45.0403 2 +89.2108 48.9147 2 +89.689 48.8692 2 +87.2408 56.3074 2 +88.3154 44.1634 2 +91.1699 46.9355 2 +88.8875 43.8631 2 +87.283 44.4296 2 +84.8534 43.1804 2 +87.3335 47.2952 2 +87.6505 50.5414 2 +96.311 46.6471 2 +88.6926 53.4257 2 +88.0917 52.869 2 +91.3403 50.753 2 +84.0359 49.4986 2 +87.2923 48.303 2 +82.2091 43.2666 2 +84.7917 44.2794 2 +92.5688 42.5525 2 +89.4485 54.3598 2 +86.4943 54.3347 2 +89.6788 49.456 2 +85.2595 56.1845 2 +89.7428 45.36 2 +90.6358 50.1006 2 +91.8902 49.0099 2 +85.3543 46.2237 2 +88.287 51.4585 2 +83.311 55.9955 2 +86.6745 49.6291 2 +85.2198 47.3764 2 +93.0694 42.2177 2 +94.5288 42.8157 2 +89.9834 42.0647 2 +89.6189 49.5295 2 +84.2698 47.9101 2 +92.5819 42.961 2 +91.3042 40.6204 2 +85.0711 44.4821 2 +90.1461 40.9955 2 +92.4721 39.8382 2 +86.1014 51.718 2 +86.0812 49.3518 2 +87.1755 47.1891 2 +84.2288 45.3026 2 +91.565 50.3471 2 +87.78 52.2848 2 +90.4919 43.7984 2 +87.1027 49.6385 2 +85.8336 50.7768 2 +86.9718 49.962 2 +89.8365 46.1989 2 +89.9746 49.1052 2 +91.0806 44.8371 2 +92.403 50.6994 2 +91.8123 47.3802 2 +85.2089 43.3215 2 +87.1131 36.9117 2 +84.6508 51.7035 2 +86.856 41.1463 2 +87.8024 53.6324 2 +87.728 45.3324 2 +91.8835 48.4475 2 +87.2429 42.0583 2 +90.2466 48.2316 2 +92.1318 45.4135 2 +91.505 45.4504 2 +85.5979 50.574 2 +89.921 53.5856 2 +86.1419 51.7783 2 +87.2909 44.8204 2 +91.915 48.4429 2 +96.0962 49.388 2 +89.013 41.348 2 +88.2461 53.4774 2 +91.8352 48.3888 2 +88.1476 49.0767 2 +92.4085 47.1247 2 +86.5908 47.3597 2 +90.8951 48.6404 2 +85.1012 48.3759 2 +86.5862 51.6755 2 +89.005 52.7666 2 +89.4523 50.372 2 +89.1947 51.7825 2 +88.0423 54.1936 2 +89.1126 42.4508 2 +88.6973 45.0153 2 +90.2052 48.1759 2 +89.6 44.7762 2 +88.2543 53.9042 2 +91.999 49.3056 2 +91.7828 38.3965 2 +90.3491 44.7946 2 +86.4181 48.8886 2 +90.1743 54.5527 2 +84.2166 48.9596 2 +87.1318 48.5002 2 +89.4146 52.1653 2 +96.1585 47.4563 2 +94.4054 52.493 2 +86.9418 45.9029 2 +85.9066 44.2445 2 +86.6872 48.0419 2 +86.3109 48.6685 2 +86.4281 42.5467 2 +85.0789 46.2326 2 +91.936 50.4201 2 +91.5812 45.0742 2 +95.1291 42.8016 2 +88.4259 45.7601 2 +94.9516 45.7467 2 +89.9463 50.2493 2 +89.5216 36.1927 2 +84.0739 54.1751 2 +83.564 47.5439 2 +89.6949 45.577 2 +90.2285 41.2575 2 +89.7117 48.7373 2 +89.7428 46.2592 2 +84.0808 50.0201 2 +88.8406 39.389 2 +90.1685 47.9725 2 +86.8695 51.2951 2 +85.7424 49.6763 2 +91.2372 43.1012 2 +84.3017 49.326 2 +94.2768 44.6449 2 +86.3431 48.7447 2 +84.4161 44.6044 2 +85.4507 48.7714 2 +90.5204 41.1995 2 +89.6142 55.9238 2 +87.2395 47.814 2 +91.3517 53.9457 2 +87.7428 44.2146 2 +89.2816 44.7962 2 +88.3347 50.1716 2 +88.7167 53.8383 2 +93.725 52.1806 2 +88.8652 46.2972 2 +86.8973 49.1004 2 +84.4684 53.9446 2 +85.2105 49.5808 2 +88.7945 47.299 2 +86.6341 52.8885 2 +88.1526 42.285 2 +89.8543 47.8203 2 +89.6499 54.3044 2 +85.0978 48.1174 2 +93.0341 43.9514 2 +88.8999 55.6848 2 +91.1194 45.3769 2 +90.6155 48.163 2 +86.3177 44.259 2 +91.7015 46.48 2 +87.1794 51.1598 2 +94.3648 41.8924 2 +92.1155 46.7421 2 +90.4303 48.403 2 +87.9613 41.0845 2 +90.9545 45.775 2 +85.4282 54.8191 2 +89.0309 45.6888 2 +92.1905 40.3106 2 +90.7636 49.5251 2 +91.3334 43.5115 2 +91.4937 50.3064 2 +91.5215 47.7161 2 +90.912 48.4959 2 +84.5398 49.0111 2 +89.7231 48.9016 2 +90.1669 46.6715 2 +90.6192 45.6402 2 +90.2356 45.1738 2 +85.5931 50.5666 2 +90.3601 50.0199 2 +88.9088 45.9637 2 +83.6885 39.4644 2 +91.2123 45.3723 2 +83.8924 34.3746 2 +85.6403 44.0833 2 +86.652 48.2945 2 +87.0762 50.7283 2 +87.4564 47.4037 2 +89.4854 51.8464 2 +91.1165 48.9172 2 +90.3261 44.0005 2 +88.5556 51.3694 2 +90.458 44.1667 2 +93.4729 49.243 2 +88.8853 48.4224 2 +95.1038 48.0907 2 +91.754 47.1854 2 +95.9075 49.1264 2 +89.5228 43.2814 2 +90.7021 45.6001 2 +92.0849 44.9925 2 +88.82 48.4119 2 +87.4787 50.8263 2 +85.5918 43.3649 2 +84.9395 49.9214 2 +87.0413 47.5512 2 +86.6818 50.5586 2 +89.5018 43.7927 2 +89.665 52.2942 2 +90.1356 47.877 2 +89.5638 52.2045 2 +87.6453 45.5494 2 +96.8817 50.6807 2 +88.8998 51.8197 2 +87.7613 52.269 2 +84.8836 44.4607 2 +84.1566 51.5901 2 +88.5174 50.9329 2 +84.1924 52.2039 2 +88.5677 44.7193 2 +87.1738 48.171 2 +88.8642 48.0175 2 +93.5652 52.9374 2 +86.4614 46.5039 2 +81.435 52.4516 2 +94.1343 49.3229 2 +90.7788 50.4529 2 +89.2447 48.8367 2 +94.8868 45.8962 2 +89.9756 48.1054 2 +83.3507 52.0499 2 +90.1138 45.3442 2 +88.8562 50.9917 2 +88.7974 52.053 2 +90.2219 39.8266 2 +90.3273 48.9453 2 +88.6123 47.1052 2 +87.5244 42.6378 2 +86.6708 47.7617 2 +90.358 46.6412 2 +86.934 50.2767 2 +88.3847 45.9418 2 +87.6987 46.9347 2 +97.6855 44.7411 2 +89.395 52.5135 2 +88.052 46.0769 2 +90.7918 52.3049 2 +87.5639 50.6963 2 +90.1878 44.4266 2 +88.1547 44.3935 2 +87.6249 52.9993 2 +83.5884 43.193 2 +88.3563 49.7908 2 +88.9367 41.5876 2 +85.7033 53.1422 2 +85.0605 53.9194 2 +85.2478 48.0425 2 +86.402 52.5303 2 +86.2921 54.6127 2 +87.3851 40.1131 2 +90.3538 50.489 2 +92.2456 49.8483 2 +89.3327 42.3362 2 +92.1793 44.9883 2 +90.1942 49.9448 2 +86.3947 52.5926 2 +86.7467 51.1191 2 +88.5879 48.6831 2 +87.2106 52.2256 2 +89.67 48.1116 2 +90.5859 45.1967 2 +92.8207 51.5179 2 +89.014 43.603 2 +88.8365 53.8056 2 +85.6767 46.1244 2 +88.0831 51.1716 2 +85.2735 55.0444 2 +82.4569 51.4223 2 +89.8371 45.6955 2 +91.0736 50.0676 2 +80.2368 45.3892 2 +94.1671 48.3806 2 +90.2918 58.0761 2 +91.4702 50.8459 2 +89.7609 50.9258 2 +88.9767 53.2659 2 +89.0141 47.2254 2 +90.5379 50.6422 2 +89.8731 55.2361 2 +92.3094 52.1076 2 +87.1002 51.2813 2 +86.2298 48.1148 2 +89.3258 50.2489 2 +92.9927 52.9134 2 +84.6777 45.3125 2 +84.8171 46.6045 2 +82.4462 51.6815 2 +93.8521 49.4999 2 +91.4381 51.9424 2 +81.4439 48.5216 2 +94.6958 46.716 2 +89.2705 46.4272 2 +87.9909 45.4986 2 +87.1652 46.2185 2 +80.1322 47.939 2 +94.7135 45.0414 2 +89.1497 42.924 2 +96.4274 40.1169 2 +88.8806 44.2576 2 +87.8476 46.4712 2 +89.5247 54.1398 2 +87.9559 43.27 2 +87.7503 52.3902 2 +86.2991 42.9858 2 +83.0513 47.3891 2 +87.4855 51.2645 2 +92.4444 49.4336 2 +89.9791 43.9567 2 +84.8837 49.3133 2 +87.0268 43.7103 2 +85.9711 44.6149 2 +88.4842 51.8088 2 +93.0818 50.1863 2 +90.5982 46.9826 2 +89.2324 54.4526 2 +84.317 49.503 2 +86.897 51.2823 2 +88.53 49.1958 2 +88.7332 38.2667 2 +85.3736 50.9609 2 +88.6667 49.2659 2 +85.0091 46.4564 2 +88.767 43.1842 2 +89.0164 51.0875 2 +81.7452 47.8578 2 +87.1229 44.7752 2 +85.8284 46.6734 2 +90.7763 50.1546 2 +86.7108 46.8908 2 +92.6708 51.8017 2 +74.2726 69.8067 3 +73.9818 67.4649 3 +74.1322 72.7556 3 +72.7323 71.8585 3 +74.1531 70.7375 3 +73.3552 68.3534 3 +73.2703 69.4745 3 +73.631 72.4323 3 +73.3769 68.2072 3 +72.6533 69.2083 3 +72.9688 69.1342 3 +73.8642 70.599 3 +73.8378 69.8061 3 +73.302 69.2352 3 +74.5045 69.3018 3 +73.2974 70.8838 3 +73.743 67.624 3 +74.6375 69.7559 3 +73.8718 71.5831 3 +73.192 66.8238 3 +73.9072 68.3804 3 +73.5798 67.6714 3 +73.575 68.158 3 +73.823 71.3263 3 +73.0799 71.4504 3 +73.202 71.0826 3 +75.0493 70.3255 3 +73.4871 67.8094 3 +73.0799 71.3822 3 +73.4581 67.936 3 +73.0602 69.3307 3 +73.2275 67.6483 3 +73.6979 70.7219 3 +74.1304 65.1982 3 +72.7914 72.6058 3 +73.7366 69.6277 3 +73.7855 70.3239 3 +74.3501 72.0416 3 +73.6619 69.4683 3 +72.7375 67.0718 3 +72.6612 68.8753 3 +73.6744 72.5614 3 +74.0665 66.307 3 +74.6205 69.2277 3 +73.6707 70.493 3 +73.6159 71.9067 3 +74.3796 69.4959 3 +73.4579 65.8763 3 +74.6789 67.6465 3 +73.2255 67.3565 3 +72.5276 69.068 3 +73.6076 71.8806 3 +73.5133 69.3907 3 +74.6233 67.1822 3 +73.0254 68.7516 3 +74.4376 69.978 3 +72.8367 72.4539 3 +72.9212 69.7396 3 +73.8538 70.7214 3 +73.4151 68.8293 3 +73.9113 70.8323 3 +73.8672 70.8038 3 +73.416 69.3949 3 +74.3085 70.829 3 +73.7153 67.5603 3 +74.2444 67.9185 3 +73.5054 73.9994 3 +75.2686 71.5738 3 +74.5974 72.6614 3 +74.4964 68.9337 3 +74.1138 70.4915 3 +73.1965 70.2223 3 +74.6996 70.9788 3 +73.5289 70.3221 3 +72.3757 71.767 3 +72.7007 70.7112 3 +72.9772 70.4844 3 +74.1244 71.595 3 +72.635 72.7985 3 +73.1364 74.9658 3 +73.3382 66.7437 3 +72.8381 66.8321 3 +73.8062 68.983 3 +74.0164 67.9562 3 +73.123 68.1732 3 +73.7772 69.7548 3 +74.0034 70.2333 3 +73.9119 69.4078 3 +74.0703 71.3454 3 +73.4394 68.3741 3 +72.96 71.1806 3 +73.0452 67.9602 3 +73.5992 67.4286 3 +74.0655 67.7051 3 +72.9039 73.1573 3 +73.722 71.3017 3 +73.7299 66.9321 3 +72.2967 70.6181 3 +73.4491 70.1462 3 +72.7991 68.6031 3 +73.3971 68.7175 3 +73.3778 68.9861 3 +74.2252 68.2841 3 +72.6546 71.0669 3 +73.7999 73.2534 3 +74.5922 68.8572 3 +73.4812 69.5408 3 +74.3824 69.1418 3 +73.7835 66.108 3 +73.0171 69.0298 3 +73.5381 72.7584 3 +73.3591 69.9393 3 +72.7752 71.4214 3 +73.7243 70.2679 3 +73.6415 69.6417 3 +73.8954 69.8098 3 +73.2771 70.8836 3 +73.7346 68.7563 3 +72.9913 68.5504 3 +72.5512 72.608 3 +73.8834 71.0078 3 +72.4116 68.3206 3 +74.0903 69.715 3 +73.6169 71.9917 3 +73.6451 71.6268 3 +73.818 68.2721 3 +72.5783 68.539 3 +72.8977 69.0658 3 +74.6791 68.2805 3 +74.1521 71.4337 3 +73.6652 69.5958 3 +73.8454 71.3259 3 +72.4555 71.2883 3 +73.7817 70.1752 3 +91.9811 26.0161 4 +90.2979 25.2049 4 +91.2388 26.6595 4 +91.9655 23.9165 4 +90.7678 29.024 4 +87.7469 24.0594 4 +92.4135 27.5165 4 +90.4122 26.6673 4 +94.2253 26.573 4 +90.6259 24.8211 4 +88.6002 28.7988 4 +90.1902 25.0782 4 +89.3152 25.2486 4 +89.0171 29.0451 4 +89.537 27.8269 4 +90.0721 25.0237 4 +93.7158 27.9905 4 +88.425 27.7088 4 +90.5562 25.042 4 +91.7559 27.3475 4 +89.5061 28.7581 4 +91.8513 28.4709 4 +91.9714 29.3321 4 +90.6725 25.995 4 +90.1253 28.6277 4 +90.3599 25.2032 4 +90.803 27.1479 4 +89.9646 28.6848 4 +91.1998 26.4056 4 +91.0664 24.2256 4 +88.5661 28.929 4 +90.8862 26.8697 4 +93.0949 26.319 4 +90.8704 24.9768 4 +91.4186 24.2155 4 +92.1146 30.2797 4 +87.0458 27.1386 4 +88.7295 24.9766 4 +91.264 24.7828 4 +89.7206 25.1047 4 +92.532 26.5028 4 +90.67 26.9685 4 +92.0341 23.8323 4 +90.2749 26.479 4 +92.2503 29.37 4 +90.8437 28.5166 4 +89.4117 25.6386 4 +91.8173 26.4935 4 +90.4973 26.4059 4 +90.8256 26.6124 4 +92.1876 29.471 4 +91.7216 25.6866 4 +92.0806 25.0022 4 +88.1969 27.4593 4 +90.1792 27.37 4 +92.1735 25.1773 4 +90.975 26.7702 4 +89.3249 28.6589 4 +89.514 26.9974 4 +88.3018 25.8741 4 +90.923 23.8659 4 +90.6065 26.0769 4 +90.3361 28.8277 4 +89.8283 27.117 4 +92.3136 31.7137 4 +89.6927 25.3439 4 +90.6924 29.8552 4 +89.3893 27.6362 4 +89.7644 27.4435 4 +90.6016 30.5066 4 +90.158 25.9923 4 +88.5255 27.2176 4 +89.895 24.3798 4 +89.377 24.5855 4 +91.2859 29.5072 4 +92.2599 26.9987 4 +87.2779 25.2799 4 +92.4109 25.7417 4 +88.944 23.8288 4 +90.792 25.5756 4 +90.7118 26.995 4 +90.3853 29.3784 4 +91.9259 25.297 4 +90.1195 26.5868 4 +92.591 27.0844 4 +91.8291 28.1403 4 +91.4011 29.3396 4 +93.0582 32.3108 4 +91.4498 25.6946 4 +90.751 27.5155 4 +91.4602 30.0453 4 +92.1166 26.5203 4 +90.6286 26.7077 4 +91.4566 27.9929 4 +91.7619 21.0296 4 +92.6422 24.9973 4 +91.6837 25.1544 4 +90.7574 26.5851 4 +90.2623 25.3736 4 +90.2408 25.9322 4 +90.3636 27.7679 4 +93.0433 26.2691 4 +90.3456 25.9149 4 +92.5928 27.8577 4 +91.8386 25.8612 4 +90.6975 26.614 4 +92.0151 26.7313 4 +87.8768 26.2049 4 +88.435 30.1644 4 +89.4816 25.8074 4 +89.9832 22.8605 4 +89.3518 27.9378 4 +90.6126 27.1129 4 +93.4874 26.1727 4 +89.1395 26.558 4 +90.6683 29.4576 4 +90.2914 27.8309 4 +88.7257 28.6311 4 +89.1031 23.3056 4 +90.6858 26.8134 4 +90.6457 27.1179 4 +90.2173 26.4178 4 +91.4241 26.3936 4 +89.2604 27.0415 4 +89.4668 24.5544 4 +92.2178 24.5295 4 +90.7077 28.9985 4 +92.2339 25.2276 4 +89.8906 25.019 4 +90.5106 31.0679 4 +90.4675 26.9606 4 +89.9945 24.0291 4 +92.0604 26.8875 4 +88.5457 27.5487 4 +91.3498 29.6584 4 +92.1397 27.6735 4 +94.6411 28.4039 4 +91.4722 25.951 4 +90.9964 24.5505 4 +90.7977 29.0235 4 +88.1699 26.1086 4 +88.905 27.5412 4 +90.1492 25.6711 4 +90.7858 26.3573 4 +88.566 24.85 4 +90.6651 26.7752 4 +90.021 26.4181 4 +89.5879 24.8532 4 +92.4591 28.2499 4 +92.6956 26.5025 4 +89.4804 29.1821 4 +91.4405 24.0908 4 +90.3535 26.2176 4 +88.9036 27.2917 4 +92.2926 26.5262 4 +95.2243 27.6474 4 +90.4325 26.4718 4 +88.068 26.5283 4 +89.2784 25.8961 4 +91.9309 25.4583 4 +91.9168 27.4116 4 +90.1169 25.7655 4 +92.6506 22.2658 4 +90.0457 28.4028 4 +90.3543 24.4808 4 +92.7355 23.1739 4 +90.8783 24.1287 4 +91.786 26.2046 4 +88.7722 26.9345 4 +90.8266 28.2891 4 +88.789 25.6881 4 +92.4348 25.7879 4 +90.9219 27.2295 4 +91.4017 25.1013 4 +91.1503 26.5223 4 +89.4192 24.1066 4 +90.8332 27.6948 4 +89.0772 25.1445 4 +88.1759 28.6175 4 +90.9373 26.3729 4 +92.843 26.2314 4 +91.3838 24.5404 4 +88.976 27.0877 4 +91.581 24.4955 4 +93.4245 27.2631 4 +91.147 25.7659 4 +89.1462 25.1933 4 +90.4053 26.1751 4 +90.0441 27.2868 4 +90.5743 26.9449 4 +90.103 25.5377 4 +89.8373 25.2346 4 +90.2871 33.6603 4 +89.8459 26.0444 4 +90.7001 23.9198 4 +90.6129 26.8572 4 +90.0107 26.898 4 +91.6055 24.0911 4 +92.1508 27.4122 4 +92.6512 27.797 4 +89.4823 27.4543 4 +91.1698 26.946 4 +89.7991 23.9718 4 +91.6375 28.4893 4 +90.2568 28.6949 4 +89.4447 30.0294 4 +91.5498 23.8889 4 +90.5709 25.8111 4 +91.9621 27.79 4 +91.5837 26.6053 4 +91.8624 24.9775 4 +92.7647 24.3805 4 +92.5599 25.7229 4 +89.5375 23.6246 4 +89.2872 26.4767 4 +90.8763 27.6425 4 +88.4581 25.8987 4 +88.8848 25.4981 4 +92.6461 26.5901 4 +92.6712 27.6029 4 +91.088 24.5292 4 +89.3503 20.8126 4 +90.8414 27.5455 4 +90.185 26.0746 4 +92.2745 25.1596 4 +90.0506 30.4402 4 +92.2351 24.8627 4 +89.5966 26.0208 4 +92.1886 29.2782 4 +89.5351 26.6449 4 +92.2264 26.3972 4 +89.6375 26.4345 4 +91.014 28.2277 4 +87.8676 26.1316 4 +90.0777 28.5869 4 +90.4841 26.8201 4 +89.5183 28.241 4 +90.7438 27.3458 4 +91.4075 25.0657 4 +90.2214 28.7614 4 +91.3736 26.4393 4 +89.4379 27.0212 4 +91.5826 24.4177 4 +92.0618 24.8452 4 +90.2 26.4186 4 +91.0427 27.729 4 +90.8863 22.5538 4 +89.5708 26.0742 4 +92.1803 24.3223 4 +90.8578 24.263 4 +92.6844 24.8197 4 +90.615 26.9866 4 +92.7103 25.5469 4 +91.3432 23.3244 4 +91.3293 24.6959 4 +90.8851 27.4971 4 +90.2636 26.2225 4 +89.8283 30.3716 4 +92.2707 23.889 4 +93.4133 25.1232 4 +88.3781 28.0142 4 +88.7215 24.4829 4 +89.0628 27.1402 4 +92.4659 25.061 4 +89.3753 24.9058 4 +90.9037 31.8957 4 +91.086 26.8256 4 +88.9895 29.171 4 +90.7835 25.7059 4 +91.2416 24.382 4 +93.523 25.4828 4 +90.7055 24.7443 4 +91.5216 25.8635 4 +91.6126 29.1513 4 +89.5577 22.1402 4 +91.55 24.9954 4 +87.1713 29.0131 4 +88.6679 28.6267 4 +90.8896 27.3246 4 +91.9702 25.2676 4 +90.115 27.8777 4 +92.7312 27.9704 4 +90.228 21.8559 4 +91.308 26.3749 4 +90.0861 25.107 4 +90.5469 27.1608 4 +90.9897 27.6804 4 +93.8508 25.2669 4 +89.6564 27.9189 4 +90.3725 26.0339 4 +90.8686 26.5653 4 +89.7784 27.0816 4 +91.1231 25.2911 4 +90.9732 27.6954 4 +91.0708 30.5316 4 +87.817 24.8397 4 +92.9265 27.3698 4 +91.2247 28.2971 4 +91.3348 24.9713 4 +93.2589 26.3927 4 +91.2791 24.5847 4 +89.2009 28.5092 4 +91.7797 30.0154 4 +88.9906 23.4283 4 +91.216 28.2823 4 +92.367 25.3266 4 +91.6419 26.0725 4 +92.4662 25.7127 4 +90.6701 27.1679 4 +91.1143 29.7778 4 +92.2739 24.0119 4 +91.4413 23.5201 4 +92.0196 29.8628 4 +91.0818 25.9817 4 +89.1357 29.5639 4 +89.571 26.882 4 +92.3279 29.3579 4 +89.788 27.5002 4 +91.3746 25.2047 4 +90.5895 25.7622 4 +90.1159 23.1072 4 +89.77 26.7014 4 +88.0015 25.3795 4 +88.2077 24.908 4 +87.0637 28.099 4 +89.0327 28.6303 4 +91.4685 26.9955 4 +91.3455 25.3371 4 +90.6186 29.7416 4 +92.1977 25.4636 4 +91.6136 29.1239 4 +91.0327 26.9506 4 +88.4428 24.3246 4 +90.7656 27.5968 4 +90.13 27.5494 4 +89.9753 28.044 4 +88.8746 26.4726 4 +90.1393 24.1829 4 +-1.65466 3.15554 5 +-1.95979 1.89509 5 +0.242731 6.30034 5 +-4.54983 5.83891 5 +-2.85125 -1.8993 5 +4.07533 -0.00279304 5 +3.64364 -0.388653 5 +11.5645 5.68943 5 +-0.14346 -6.13068 5 +-7.99011 -3.55738 5 +-0.177416 -0.497974 5 +-1.35756 6.00807 5 +3.25944 4.96499 5 +6.08788 7.19605 5 +2.21844 5.30573 5 +1.63419 -1.56224 5 +-2.36155 0.127156 5 +0.11425 -0.896811 5 +7.64785 1.49522 5 +2.30702 0.830296 5 +-1.21257 0.965462 5 +7.55589 0.0988247 5 +4.33746 -1.25607 5 +1.54874 9.68863 5 +-0.592713 -0.116108 5 +2.66729 1.71522 5 +1.31065 0.558702 5 +-6.38358 -2.22453 5 +-2.97827 3.83165 5 +-1.611 2.77637 5 +-3.91203 1.54852 5 +4.42151 -6.23474 5 +0.2244 -3.07489 5 +9.52907 1.73414 5 +2.50423 4.56043 5 +-1.84383 -1.48748 5 +-0.0484444 -5.97343 5 +-3.39596 6.11471 5 +0.855239 -1.1621 5 +1.10345 2.55092 5 +-5.31066 3.34637 5 +0.835511 -3.44371 5 +8.10291 -1.2116 5 +-4.96163 -2.42639 5 +10.8092 0.356932 5 +-3.32887 3.24998 5 +-0.397606 3.20236 5 +-3.2666 -5.72386 5 +-3.02228 1.00746 5 +-2.04176 -5.64454 5 +2.72495 2.27014 5 +-1.67995 3.55699 5 +6.0739 7.05283 5 +-1.27768 5.53267 5 +2.51899 -0.291185 5 +1.1463 -1.98053 5 +-5.294 0.724984 5 +6.12424 -1.91427 5 +2.5964 -6.36295 5 +5.63341 2.8208 5 +2.69827 -1.92172 5 +10.3994 1.19503 5 +4.32114 -0.206678 5 +6.66836 -3.70412 5 +1.64158 -3.79976 5 +9.7046 0.839301 5 +-3.57995 3.73176 5 +2.69933 9.35067 5 +-0.239075 -7.38483 5 +-0.438414 4.15476 5 +2.64711 -3.07873 5 +-2.21501 2.50166 5 +8.04171 -3.2728 5 +3.81812 2.24573 5 +4.87076 -1.61641 5 +-1.72199 3.93798 5 +-6.40525 0.557111 5 +-2.43844 -0.852453 5 +4.19113 -4.16546 5 +-5.93183 -2.45815 5 +6.24556 7.74392 5 +2.9709 -2.7168 5 +-7.30964 -2.61273 5 +-8.57655 1.14362 5 +-1.22235 -8.39053 5 +-1.07542 -1.48035 5 +-0.466294 -7.94737 5 +-0.937551 5.67085 5 +3.09871 3.89322 5 +9.56232 5.10074 5 +3.78911 -0.054962 5 +1.34379 2.37818 5 +1.68973 -5.34433 5 +-0.0720189 -6.59261 5 +-6.71218 4.20541 5 +-5.77796 -4.01372 5 +5.54546 1.02003 5 +-0.61054 1.97387 5 +4.32751 -0.4685 5 +0.0433711 -2.69711 5 +2.07737 -1.49538 5 +10.1146 -4.03963 5 +6.30502 4.85174 5 +-1.68707 -5.25781 5 +-6.1506 1.03138 5 +-0.954344 0.888134 5 +-2.58785 -2.37655 5 +5.19407 -2.79605 5 +8.55873 7.11099 5 +-1.46419 0.9145 5 +-3.58374 8.63403 5 +1.89922 0.160052 5 +6.98553 1.06818 5 +4.03384 -3.29934 5 +0.584499 -5.52117 5 +-0.128668 5.28011 5 +8.09119 -8.86059 5 +2.78583 1.13262 5 +1.39289 0.167642 5 +-3.46198 2.72315 5 +4.78413 -5.36212 5 +0.640676 -0.292248 5 +-3.33334 0.780647 5 +6.16653 4.72602 5 +-4.76767 3.1332 5 +-2.52385 2.44323 5 +-5.74168 -2.96422 5 +0.0622463 -1.03993 5 +0.72398 -2.56943 5 +-0.542308 -1.49573 5 +3.61572 3.45244 5 +0.943772 0.144619 5 +-3.63437 0.124569 5 +0.599637 5.76874 5 +1.86564 1.1967 5 +-4.01782 -0.79129 5 +-9.53771 3.26686 5 +-0.634747 -4.92272 5 +1.49663 3.41677 5 +-0.235596 -1.75087 5 +-1.96046 0.964119 5 +-4.39435 -3.37095 5 +-3.94655 5.02581 5 +-2.49111 6.54932 5 +-0.431078 0.490679 5 +1.93255 5.7082 5 +-0.719091 -4.62139 5 +12.2838 2.25227 5 +3.35946 0.431036 5 +-2.3539 2.52036 5 +3.71371 -0.501098 5 +-2.20401 -1.69065 5 +1.45176 -1.4088 5 +0.464342 0.0891036 5 +0.832195 -1.89687 5 +-4.93361 5.9575 5 +0.0122751 -0.155296 5 +-0.139144 3.87836 5 +3.26964 -3.66852 5 +4.16192 7.80085 5 +2.31779 -1.96063 5 +-1.61499 -1.37047 5 +5.56298 4.12885 5 +9.07988 -2.79007 5 +-0.211274 3.0923 5 +8.14108 -9.06238 5 +7.2831 11.3461 5 +-9.71298 2.76591 5 +14.7922 -1.53972 5 +-3.03625 3.14589 5 +3.24869 1.47472 5 +0.905788 -0.0489007 5 +2.08973 -4.71409 5 +5.76686 0.827778 5 +8.16547 3.32944 5 +3.22301 5.20771 5 +3.93875 5.30128 5 +-7.42484 5.19288 5 +0.633585 2.82469 5 +2.56726 1.31561 5 +-4.49471 1.84318 5 +0.380982 0.333542 5 +-3.46291 -1.35364 5 +-3.50238 -6.40089 5 +2.23613 6.05214 5 +3.66124 -0.0598393 5 +-1.83806 -1.33336 5 +8.52088 -0.68811 5 +1.32014 1.90211 5 +1.51614 -2.66772 5 +-9.19635 0.883039 5 +2.97915 1.03053 5 +4.46492 1.63294 5 +-3.06431 -2.32888 5 +0.597905 4.07005 5 +4.41701 -5.01487 5 +-0.953847 1.97457 5 +1.37149 3.47017 5 +4.88548 6.72843 5 +-1.04998 4.07991 5 +3.24584 -1.01001 5 +5.93121 1.00057 5 +4.6739 0.019708 5 +6.83384 4.41556 5 +-1.91565 5.70897 5 +6.80317 6.64806 5 +0.918914 1.20794 5 +0.8364 0.0173155 5 +-1.77346 -3.98593 5 +1.92042 0.596846 5 +-10.1495 -5.77052 5 +7.54711 -1.4167 5 +-9.94659 4.46867 5 +-4.14971 2.83657 5 +-4.20263 -2.70979 5 +-0.239809 -1.65895 5 +-3.54769 7.7192 5 +-4.41639 -2.63558 5 +5.90387 1.95566 5 +0.0737254 4.09633 5 +3.4177 0.0200606 5 +10.2639 -3.03816 5 +0.197503 1.81457 5 +8.96799 8.22514 5 +4.30686 -3.77064 5 +4.93563 -2.17216 5 +5.17733 -0.814761 5 +7.82605 3.60719 5 +-2.91463 7.86977 5 +-4.94531 6.7106 5 +1.62834 0.493812 5 +12.977 2.04322 5 +5.09127 -3.83338 5 +-8.04881 6.6609 5 +3.99283 0.0638659 5 +1.63371 3.56097 5 +8.02647 2.84756 5 +-6.10105 1.85929 5 +-1.1779 2.52419 5 +0.695207 2.71839 5 +-2.68079 5.70324 5 +11.7375 5.00656 5 +-1.77092 -1.68061 5 +-2.97868 3.41728 5 +-0.370456 6.7466 5 +5.00147 8.27174 5 +-2.2907 -1.43738 5 +-9.30166 -2.4587 5 +1.9714 1.94833 5 +0.397733 -0.76196 5 +3.31097 -5.1518 5 +-4.83887 1.15181 5 +0.639433 6.28158 5 +-7.3024 7.48131 5 +-5.50179 6.48834 5 +-9.60045 -4.2444 5 +-1.07479 2.3999 5 +-8.88191 0.72365 5 +-2.7492 3.65052 5 +2.35226 3.47701 5 +-1.36277 4.96686 5 +-2.24105 5.95415 5 +4.71727 -3.72103 5 +0.326285 6.77888 5 +-5.37655 -2.43309 5 +-5.62916 3.53113 5 +-4.18169 2.40695 5 +0.036091 0.456471 5 +1.91916 -3.79522 5 +-6.47782 -0.0190141 5 +-2.36081 -0.660907 5 +9.32368 3.00638 5 +-7.50842 -0.234816 5 +-0.94 4.59998 5 +3.41021 1.72389 5 +-4.18479 0.899722 5 +3.20191 -4.27056 5 +-3.19708 1.01505 5 +5.44536 2.25157 5 +10.0825 7.18699 5 +10.6657 5.67901 5 +3.51985 1.24137 5 +-2.35764 -6.09353 5 +-7.0898 3.66954 5 +0.70734 -1.14433 5 +-7.4583 -4.71297 5 +2.24185 -3.93383 5 +7.4003 2.09532 5 +4.03369 3.84064 5 +1.62249 0.168851 5 +1.73933 0.610429 5 +-7.23506 1.64027 5 +2.243 5.64408 5 +12.2009 -1.15147 5 +46.8561 97.8985 8 +46.8416 96.6635 8 +46.4602 96.2782 8 +46.7127 97.7423 8 +46.9914 97.2041 8 +46.9173 96.7827 8 +46.7745 96.4818 8 +46.9683 96.9228 8 +46.9475 97.0782 8 +46.9178 98.2688 8 +46.8158 97.132 8 +46.4592 97.4589 8 +46.7112 99.047 8 +46.3934 98.1286 8 +47.2699 99.4634 8 +46.888 98.1687 8 +47.1195 97.7149 8 +46.648 96.5271 8 +46.8689 97.8978 8 +46.8373 96.1379 8 +46.4721 97.5516 8 +46.3042 97.7456 8 +46.8441 97.9966 8 +46.9667 96.7757 8 +46.2576 97.174 8 +46.3537 96.7191 8 +46.788 98.84 8 +46.5896 96.865 8 +46.4405 97.9658 8 +46.6816 97.7828 8 +46.8654 97.9209 8 +46.5054 97.4591 8 +46.5314 97.4193 8 +47.0844 97.1519 8 +46.7607 97.3105 8 +46.1788 97.7681 8 +46.8031 97.6769 8 +46.6754 96.6076 8 +46.6825 96.8158 8 +46.5879 97.5057 8 +47.0293 97.8876 8 +47.1024 97.2003 8 +46.4841 97.8724 8 +46.7678 97.8517 8 +47.0438 99.4431 8 +46.475 98.5681 8 +46.9435 98.7066 8 +46.5785 98.1102 8 +46.6087 97.9767 8 +46.6545 98.4958 8 +46.5087 97.675 8 +46.8251 97.4383 8 +46.7483 96.9506 8 +46.8477 98.4845 8 +46.2725 98.7478 8 +46.3932 98.6142 8 +46.903 95.7448 8 +46.8512 95.8197 8 +47.2473 98.146 8 +46.6484 97.5435 8 +46.8626 96.9986 8 +47.0493 97.9576 8 +46.6599 97.2893 8 +46.8039 97.4159 8 +46.259 98.3545 8 +46.602 98.0131 8 +46.921 97.2904 8 +47.1647 98.8029 8 +47.1102 97.6287 8 +46.5269 98.4176 8 +46.6604 99.2336 8 +46.6316 96.5949 8 +46.5649 96.9664 8 +47.0506 98.1135 8 +46.8383 96.4201 8 +46.3531 97.3522 8 +46.5944 97.8713 8 +46.6731 95.1606 8 +46.5163 97.8681 8 +46.5566 97.0541 8 +46.531 97.2174 8 +46.7041 96.5078 8 +47.2848 97.2332 8 +46.9291 98.1139 8 +46.3256 99.8857 8 +47.102 98.9331 8 +46.814 96.7862 8 +46.9374 96.6155 8 +46.7145 97.6226 8 +46.715 98.1566 8 +46.5158 95.5454 8 +46.5629 97.0851 8 +46.9501 98.5567 8 +46.3124 97.7652 8 +46.2066 99.5194 8 +46.9503 97.9211 8 +46.339 97.7687 8 +45.9853 96.7089 8 +47.3146 97.2134 8 +46.2186 96.9146 8 +46.4874 98.0093 8 +46.6408 97.6948 8 +46.5774 96.5733 8 +46.1674 98.0757 8 +46.1367 97.3792 8 +46.1729 96.7925 8 +46.9602 95.183 8 +46.637 99.8563 8 +47.1634 97.7161 8 +46.9084 99.7199 8 +46.455 96.705 8 +46.955 98.8835 8 +46.765 98.7974 8 +46.1961 98.006 8 +46.3598 97.1438 8 +46.5656 98.3999 8 +47.1086 96.9564 8 +47.3158 99.949 8 +46.5392 96.9697 8 +47.5078 97.6512 8 +46.6645 97.5788 8 +46.4633 98.4374 8 +46.632 96.4211 8 +46.684 96.3748 8 +47.0257 96.4409 8 +46.5726 99.7075 8 +46.372 97.9994 8 +46.5176 97.0279 8 +46.5873 96.9607 8 +46.4106 97.5547 8 +46.5163 97.2247 8 +46.5243 98.0861 8 +46.5143 97.7893 8 +46.3077 97.8731 8 +46.9413 97.0721 8 +46.7776 97.7588 8 +46.9127 97.8808 8 +46.3164 97.2455 8 +46.9484 96.5465 8 +46.7762 98.4775 8 +46.989 98.1925 8 +46.7029 98.3393 8 +46.5889 98.5784 8 +46.9014 98.1903 8 +46.6347 96.7807 8 +46.3536 97.1091 8 +46.7157 99.4054 8 +46.7234 99.337 8 +46.7502 98.1035 8 +47.2217 97.0716 8 +46.2567 98.1482 8 +46.8522 94.8742 8 +46.3502 97.0685 8 +46.2311 98.0683 8 +47.02 97.9608 8 +46.8203 96.7425 8 +46.8181 97.7725 8 +46.4673 97.0973 8 +46.4067 99.07 8 +46.9564 98.5048 8 +46.6692 96.6604 8 +47.1612 98.1991 8 +46.6564 96.6772 8 +46.5594 98.7963 8 +47.4426 97.3721 8 +47.0102 98.0624 8 +46.5032 98.8213 8 +46.6145 96.7089 8 +47.1639 98.4716 8 +47.2586 98.2868 8 +46.9278 97.6147 8 +47.0204 98.9521 8 +45.9869 98.3687 8 +47.0106 97.5301 8 +46.7703 96.7064 8 +46.5817 96.6913 8 +46.5698 98.0398 8 +46.4025 97.1813 8 +46.189 98.2358 8 +46.193 97.6883 8 +47.0593 98.0335 8 +46.6658 97.8147 8 +46.4066 97.8696 8 +46.3388 97.914 8 +46.7286 98.4514 8 +46.9915 96.9698 8 +46.9412 97.1415 8 +46.5364 98.9139 8 +46.5315 96.4185 8 +47.1419 97.2853 8 +46.351 98.0415 8 +46.585 98.1207 8 +46.769 96.8816 8 +46.6161 99.2195 8 +46.8233 98.8489 8 +46.4523 96.1711 8 +46.8374 97.4622 8 +46.5149 96.9054 8 +46.602 96.1774 8 +46.5315 95.7907 8 +46.3252 97.3333 8 +46.7356 95.5964 8 +46.8493 97.1612 8 +46.3894 97.0569 8 +46.7776 99.1992 8 +47.0271 98.2515 8 +47.0145 97.8455 8 +46.898 97.5772 8 +46.5732 98.1306 8 +46.6545 98.2411 8 +46.5216 95.1804 8 +46.3795 96.0969 8 +46.9031 96.7382 8 +46.3574 97.2506 8 +47.1661 97.7714 8 +46.6209 99.8443 8 +46.77 97.9611 8 +46.6682 99.1463 8 +46.7765 98.5504 8 +46.9267 96.784 8 +46.5207 97.071 8 +46.5703 97.2067 8 +46.831 98.0702 8 +46.7175 98.2498 8 +46.7156 98.0367 8 +46.9933 96.9021 8 +46.7886 96.9757 8 +46.6007 97.5568 8 +46.5315 98.0102 8 +46.6238 96.7985 8 +47.1479 97.6063 8 +46.4097 96.8193 8 +46.6684 98.1812 8 +46.7959 96.8826 8 +46.8998 97.0426 8 +47.2447 96.8455 8 +46.5496 96.9662 8 +46.9293 98.9393 8 +47.0228 98.5483 8 +46.6132 96.7525 8 +46.6835 96.7918 8 +46.9555 99.3202 8 +46.625 97.9187 8 +46.5252 98.3655 8 +46.7008 98.0457 8 +46.5398 97.3689 8 +46.7512 99.3429 8 +47.0768 99.8496 8 +46.659 98.043 8 +46.5479 97.6389 8 +46.9157 98.0732 8 +46.6428 97.0618 8 +46.4175 98.5782 8 +47.0373 96.5907 8 +46.8521 95.2534 8 +46.2121 97.4255 8 +46.5087 98.0472 8 +46.4243 98.3533 8 +46.5749 97.7495 8 +46.5066 96.8138 8 +47.0033 96.7007 8 +46.3021 96.3472 8 +47.0555 97.6184 8 +46.7625 97.2768 8 +46.9152 96.8095 8 +46.8526 96.4927 8 +46.9735 98.3559 8 +46.5275 96.8696 8 +46.37 98.1412 8 +46.7295 98.0914 8 +46.6313 97.1242 8 +47.0642 97.8177 8 +46.7369 97.1109 8 +46.2172 97.8546 8 +46.3558 97.1101 8 +46.5212 97.8762 8 +47.078 98.0654 8 +46.9496 96.2408 8 +46.4143 96.7127 8 +46.6686 98.2456 8 +45.7663 96.8454 8 +46.9618 97.9479 8 +46.78 98.2831 8 +46.3811 97.5172 8 +47.1949 96.2542 8 +46.8597 98.2963 8 +46.9287 96.9239 8 +46.557 98.3573 8 +47.4469 97.1521 8 +46.8447 97.7708 8 +46.3489 96.9911 8 +46.8837 99.1218 8 +46.3846 97.9074 8 +46.8051 97.1442 8 +47.3268 97.373 8 +46.4207 98.3194 8 +46.5076 99.4655 8 +47.3039 95.6372 8 +46.9581 98.7394 8 +46.8243 97.1014 8 +47.0037 97.4976 8 +46.7505 96.9469 8 +46.6066 96.6853 8 +47.0229 97.6962 8 +46.8556 98.2446 8 +46.9865 97.807 8 +46.5313 97.7366 8 +46.3971 97.28 8 +46.5744 98.289 8 +46.9842 96.9101 8 +46.817 97.9921 8 +46.4645 96.9861 8 +46.1864 95.4522 8 +46.6734 96.5289 8 +46.7991 96.1429 8 +47.2485 96.8359 8 +46.7249 97.6652 8 +46.7152 99.2337 8 +46.7289 96.2303 8 +46.7253 97.4934 8 +47.0489 98.77 8 +46.7341 99.2624 8 +46.4837 98.9432 8 +46.8485 96.8085 8 +46.7738 98.1114 8 +46.4683 97.9079 8 +46.4505 96.4696 8 +46.6628 97.9374 8 +46.792 98.7427 8 +46.9446 96.5463 8 +46.4672 96.9506 8 +46.5609 97.4632 8 +46.5964 96.1828 8 +46.3169 96.7562 8 +47.121 97.4957 8 +46.5687 97.9135 8 +47.214 98.1828 8 +46.4651 96.1499 8 +46.6054 98.6599 8 +46.8178 98.2631 8 +46.8222 97.383 8 +46.6923 96.7786 8 +46.4988 98.0345 8 +46.8991 97.6042 8 +47.0519 96.4753 8 +46.1498 98.8999 8 +46.586 96.35 8 +46.6059 97.8301 8 +47.1183 98.0723 8 +46.6617 97.9003 8 +46.5575 97.9043 8 +46.6516 98.5847 8 +47.0235 97.1376 8 +47.1024 97.3328 8 +46.4445 96.9594 8 +46.5609 98.0655 8 +46.5731 97.5946 8 +46.1865 97.7227 8 +46.5671 98.1244 8 +46.4306 96.3438 8 +46.9301 98.5617 8 +46.8742 98.3594 8 +46.5588 98.7898 8 +46.5237 98.5861 8 +46.4943 97.162 8 +46.5252 98.6681 8 +46.766 98.6994 8 +46.6523 98.6087 8 +46.8653 97.4346 8 +46.6171 97.0944 8 +46.4471 97.8565 8 +46.893 96.7955 8 +46.7267 99.271 8 +46.9025 97.8068 8 +46.2772 98.0083 8 +46.4573 96.9402 8 +46.4523 96.1453 8 +46.4924 97.9978 8 +46.7979 97.0451 8 +47.0281 98.2777 8 +46.6854 98.829 8 +46.2903 96.7216 8 +46.6661 98.73 8 +46.6764 96.1902 8 +46.8709 98.1225 8 +46.9612 98.56 8 +46.8291 99.3309 8 +46.5931 96.7585 8 +47.0305 98.2756 8 +47.0987 98.5335 8 +46.5922 98.4491 8 +46.9719 96.9798 8 +46.5271 97.9006 8 +46.9003 97.1881 8 +46.9146 97.2717 8 +46.7988 97.5314 8 +46.7203 97.0126 8 +46.5724 98.0873 8 +46.1339 98.054 8 +46.3826 97.5336 8 +47.2287 98.2187 8 +46.9248 98.553 8 +46.4297 96.8159 8 +46.3007 96.6835 8 +47.1466 97.0955 8 +47.0695 96.4776 8 +46.726 98.2215 8 +47.0347 97.8555 8 +46.5335 99.3149 8 +46.5477 98.2022 8 +46.9019 96.3167 8 +46.7368 97.262 8 +46.7786 99.7681 8 +46.8741 99.1138 8 +46.5626 99.4614 8 +46.4747 97.4475 8 +46.2026 98.1928 8 +46.3383 98.3835 8 +46.542 97.2429 8 +46.7819 97.6607 8 +46.8051 97.8664 8 +46.6427 98.0271 8 +46.5849 97.398 8 +46.7824 96.4489 8 +46.7976 97.752 8 +46.7184 96.9687 8 +46.7825 98.4931 8 +46.9262 97.9827 8 +46.6928 97.5397 8 +46.6757 97.6326 8 +46.5386 98.556 8 +46.9401 97.3801 8 +47.1088 97.0551 8 +47.404 97.1537 8 +6.9742 63.5598 7 +6.46399 66.146 7 +18.5047 77.5835 7 +16.0333 73.5723 7 +7.42553 74.8369 7 +11.7781 75.2099 7 +13.3548 68.5617 7 +18.0088 72.8295 7 +9.93295 72.9016 7 +12.3635 72.4916 7 +16.8757 72.5421 7 +6.59346 79.6186 7 +11.4979 71.8487 7 +15.8975 79.1598 7 +16.0393 72.5746 7 +18.8133 77.0823 7 +12.974 65.8262 7 +17.7227 70.795 7 +15.8848 77.1236 7 +16.7038 78.8864 7 +14.7131 74.4971 7 +15.008 72.6344 7 +14.0303 76.2621 7 +19.836 74.8614 7 +12.3228 71.7349 7 +11.8228 60.8732 7 +17.1616 66.4786 7 +9.1945 74.8571 7 +10.9675 74.9959 7 +14.0197 75.2624 7 +17.8185 69.8292 7 +14.9716 74.8698 7 +11.3575 69.0807 7 +15.2966 72.657 7 +17.5655 75.8027 7 +13.5258 69.1893 7 +16.7934 67.3642 7 +17.9568 70.4081 7 +9.38253 69.0601 7 +10.0653 74.5443 7 +7.92786 74.4489 7 +14.5688 74.071 7 +12.0616 78.308 7 +18.8568 72.2338 7 +15.0005 77.0597 7 +17.6146 73.2862 7 +14.5691 80.9173 7 +14.5615 73.5849 7 +12.4247 65.1364 7 +21.0351 70.5554 7 +14.4129 66.9985 7 +16.8253 69.0902 7 +13.8975 70.8838 7 +4.83364 70.7908 7 +17.4459 69.786 7 +15.4855 73.1077 7 +6.61716 71.7575 7 +12.7626 67.7246 7 +21.7233 74.3631 7 +15.7184 62.5602 7 +18.4173 69.2612 7 +15.4037 76.1274 7 +16.1142 73.4925 7 +20.2021 67.7087 7 +18.6125 71.3553 7 +15.9821 81.7773 7 +14.7601 70.3693 7 +11.0119 77.4211 7 +14.9101 74.4998 7 +16.4344 79.3438 7 +22.9702 71.7193 7 +5.1016 79.3232 7 +14.3271 76.0561 7 +11.96 84.2657 7 +8.03136 75.8108 7 +11.6875 79.217 7 +13.3976 60.3978 7 +19.1962 77.9851 7 +17.5152 68.3059 7 +21.5956 73.967 7 +13.9858 72.2624 7 +14.5007 67.7301 7 +8.86643 76.7621 7 +11.913 63.5411 7 +17.4928 64.2277 7 +14.662 74.6725 7 +12.9914 71.8402 7 +14.6694 74.8898 7 +11.9876 73.1704 7 +6.79527 67.7802 7 +18.268 79.6573 7 +11.0498 77.0895 7 +18.1086 70.1339 7 +13.6122 74.0688 7 +6.93684 72.113 7 +12.58 77.3262 7 +15.1078 66.2657 7 +16.0514 75.7698 7 +10.383 67.3842 7 +15.9949 73.0173 7 +8.78849 80.0371 7 +15.9425 58.4478 7 +13.8141 68.9628 7 +23.1919 75.9825 7 +9.33767 72.7899 7 +13.1499 77.948 7 +9.31113 66.0853 7 +13.6298 77.9882 7 +14.7806 70.4936 7 +10.7807 77.9293 7 +12.1075 84.2081 7 +18.0637 73.155 7 +12.2869 72.1929 7 +17.8834 78.6057 7 +15.0611 71.2426 7 +12.6032 69.0315 7 +16.11 73.644 7 +17.0151 77.1487 7 +16.9914 76.5998 7 +13.863 67.3368 7 +13.7336 72.1281 7 +15.799 66.3803 7 +17.5132 70.087 7 +11.6782 68.8306 7 +17.9938 70.2958 7 +13.355 77.3186 7 +15.2698 74.2343 7 +21.8976 83.2627 7 +11.1427 82.1626 7 +15.2363 70.1339 7 +11.1334 70.5787 7 +13.1384 74.7592 7 +17.1843 76.3483 7 +16.9459 73.1542 7 +10.6792 78.5428 7 +13.1234 74.1113 7 +18.9347 62.8147 7 +10.8564 65.1915 7 +14.1361 74.144 7 +16.8179 73.4168 7 +20.4314 79.1002 7 +12.5282 71.6858 7 +16.3075 74.0084 7 +12.6015 76.6854 7 +11.4256 72.069 7 +8.67112 73.6595 7 +20.0546 77.4793 7 +5.66921 74.7665 7 +21.1012 86.303 7 +15.3943 70.1011 7 +7.07924 76.6519 7 +15.2409 78.2069 7 +11.3114 73.1903 7 +12.5313 69.8949 7 +9.56799 68.0229 7 +13.2154 72.8227 7 +10.9088 79.7561 7 +10.1041 74.6244 7 +15.213 67.1256 7 +13.5404 68.5892 7 +24.516 72.4898 7 +13.902 65.4107 7 +18.9457 67.3117 7 +15.8751 77.2214 7 +10.0324 70.5172 7 +18.7745 68.0842 7 +11.1172 67.8786 7 +15.6576 78.1547 7 +11.7784 62.7092 7 +10.6007 72.7629 7 +16.4342 70.7504 7 +16.0939 68.6336 7 +7.32682 80.992 7 +21.7923 77.9965 7 +20.7545 72.5261 7 +9.97794 71.7252 7 +16.5896 70.6464 7 +17.7794 70.8952 7 +17.0605 66.86 7 +4.44968 79.6235 7 +19.4552 65.6815 7 +10.8662 80.0937 7 +12.8369 73.5149 7 +14.0044 74.3141 7 +10.4842 72.3611 7 +15.4378 70.5417 7 +7.7826 79.7765 7 +15.2945 77.8664 7 +17.1188 73.3233 7 +17.8253 73.2815 7 +13.4018 68.7243 7 +12.8319 77.1705 7 +11.8416 71.5687 7 +15.4133 68.3427 7 +14.3874 75.0911 7 +14.7618 78.3312 7 +8.56969 76.0649 7 +4.87489 76.7773 7 +14.7324 79.746 7 +16.1758 68.1576 7 +11.6288 72.0451 7 +18.4902 73.4662 7 +3.62344 59.9285 7 +15.5947 74.5344 7 +10.878 79.1342 7 +14.8407 69.6396 7 +2.84344 71.5012 7 +12.4883 66.8669 7 +10.468 64.6173 7 +7.77496 71.3847 7 +18.6877 77.3514 7 +10.2618 81.514 7 +23.1101 77.8435 7 +8.29675 77.0656 7 +13.1048 78.2182 7 +14.0717 77.3593 7 +10.4853 70.9936 7 +8.14661 75.3408 7 +10.9537 72.6611 7 +19.3943 80.9806 7 +19.4368 71.8462 7 +11.8372 69.65 7 +13.8936 71.6775 7 +16.4462 68.2286 7 +9.35932 82.8769 7 +11.4419 75.8901 7 +8.00972 67.9883 7 +16.1423 72.6532 7 +17.5449 72.9405 7 +20.2077 79.7205 7 +12.0972 76.5809 7 +15.0473 66.1835 7 +18.005 68.9914 7 +15.5652 65.9837 7 +8.20881 72.9559 7 +13.2994 69.3226 7 +14.3928 71.4406 7 +13.144 76.8367 7 +13.4069 69.89 7 +15.2506 72.4894 7 +15.4718 65.3772 7 +6.28291 68.7217 7 +17.0008 71.9158 7 +12.782 73.8156 7 +15.6109 71.2024 7 +25.0523 67.318 7 +11.0317 70.1689 7 +14.3198 77.6605 7 +9.76055 76.678 7 +13.009 68.9532 7 +9.03985 70.387 7 +9.91819 67.126 7 +9.39186 67.6286 7 +9.23366 76.9973 7 +9.90062 72.9595 7 +13.7697 69.6652 7 +18.7182 71.6706 7 +19.3225 74.307 7 +18.034 83.5673 7 +18.4821 70.9698 7 +14.2428 70.0197 7 +15.9691 79.5589 7 +17.8546 64.5312 7 +17.3575 74.0294 7 +14.7628 73.0349 7 +17.5428 70.2942 7 +12.409 71.5285 7 +7.64793 75.4301 7 +23.4986 72.5452 7 +8.38578 70.7554 7 +9.747 68.1746 7 +9.07505 71.9796 7 +12.2811 73.9022 7 +11.2408 68.1408 7 +12.8555 73.0838 7 +15.6769 73.0767 7 +15.2056 63.572 7 +18.9136 71.6167 7 +11.0493 76.097 7 +14.999 79.7878 7 +17.6008 72.28 7 +7.44971 81.2882 7 +12.2055 76.7956 7 +18.1146 71.9282 7 +13.7783 78.709 7 +26.147 73.308 7 +16.1113 76.1851 7 +15.8876 74.961 7 +13.2603 72.4898 7 +20.6139 74.1227 7 +15.5693 72.1147 7 +7.4477 74.1965 7 +13.3477 72.3795 7 +11.4621 82.6934 7 +13.2552 81.1053 7 +15.5997 70.0399 7 +13.6189 80.0286 7 +11.752 78.6136 7 +11.9002 70.894 7 +15.2897 82.206 7 +14.2906 74.9315 7 +11.0522 73.673 7 +22.7165 64.5184 7 +15.378 77.9423 7 +10.8619 70.9644 7 +9.65983 76.2478 7 +15.5432 71.3917 7 +15.8865 75.6598 7 +12.1625 77.7504 7 +9.74072 70.1159 7 +15.6409 70.2935 7 +12.8535 76.8015 7 +13.4595 76.9247 7 +20.7965 72.3806 7 +18.9609 72.8208 7 +22.3784 75.6609 7 +14.1641 72.1781 7 +9.92617 69.1983 7 +18.2911 69.3891 7 +15.3908 72.8343 7 +10.0663 75.3633 7 +12.7845 67.7347 7 +12.7302 72.6837 7 +12.6735 67.9715 7 +16.9401 68.9921 7 +9.40018 70.906 7 +14.7253 71.9753 7 +5.26614 77.5098 7 +9.76337 68.8844 7 +16.3041 80.022 7 +18.6544 80.0636 7 +20.5745 76.1862 7 +13.8585 63.6911 7 +9.7573 63.8881 7 +12.1147 73.6008 7 +10.8968 73.0989 7 +12.5356 75.0092 7 +7.43643 74.1687 7 +13.3259 69.9454 7 +16.6829 75.7218 7 +12.5697 70.5723 7 +10.3905 75.958 7 +18.9164 76.0827 7 +14.6007 72.0524 7 +19.4285 74.9735 7 +19.9799 75.5132 7 +15.5005 68.7026 7 +16.0318 67.8982 7 +21.0952 64.5587 7 +13.9007 74.8945 7 +19.6489 74.7528 7 +12.4929 71.4185 7 +17.6386 76.1382 7 +8.57432 82.6621 7 +9.58557 66.1414 7 +11.0456 69.5803 7 +12.1605 70.8958 7 +14.9477 78.2299 7 +17.7285 67.1226 7 +13.2754 79.3836 7 +10.229 76.4249 7 +14.0693 71.434 7 +12.8931 71.7727 7 +17.9009 71.8102 7 +13.2442 77.9717 7 +9.36279 71.5327 7 +13.0456 63.7823 7 +9.42968 66.6865 7 +14.5659 72.133 7 +21.7401 73.3919 7 +11.9362 71.9542 7 +7.55315 76.3411 7 +9.42557 72.671 7 +17.4073 74.5066 7 +16.0269 73.4295 7 +7.34307 77.196 7 +16.7426 70.0379 7 +12.9911 75.7311 7 +16.858 69.2427 7 +16.0424 76.8963 7 +17.2367 81.0253 7 +18.8085 79.1206 7 +13.228 74.7781 7 +7.82159 70.8112 7 +8.82195 74.3393 7 +18.0928 62.4608 7 +14.4714 78.7609 7 +17.2222 70.2953 7 +14.0585 66.8945 7 +15.1509 71.3675 7 +23.0115 77.1704 7 +10.7838 66.9981 7 +14.0673 71.4014 7 +20.0259 75.849 7 +13.735 74.2524 7 +19.1428 75.8848 7 +14.5204 72.0799 7 +12.9293 71.9116 7 +7.91306 70.0406 7 +11.1569 72.5301 7 +18.5769 82.9214 7 +17.0431 77.3224 7 +19.8204 72.0764 7 +15.1146 73.3423 7 +14.9551 81.5398 7 +16.7977 64.5207 7 +20.8961 73.9012 7 +11.3243 75.4182 7 +15.4702 64.015 7 +12.9239 82.308 7 +13.1114 72.7146 7 +13.221 81.1251 7 +23.681 71.2745 7 +4.019 76.7883 7 +12.4485 75.9931 7 +19.9562 64.5198 7 +13.851 71.5423 7 +11.163 66.8932 7 +14.6376 76.2576 7 +16.9634 70.2364 7 +19.0134 78.3643 7 +10.6944 72.2111 7 +16.2133 65.9127 7 +10.9631 72.7751 7 +11.3727 71.7992 7 +18.5126 76.2785 7 +15.9101 74.2728 7 +18.5133 76.754 7 +15.8657 82.2787 7 +9.9406 78.2441 7 +14.0614 71.4062 7 +11.6339 73.6409 7 +18.1891 77.3399 7 +14.2462 70.3142 7 +14.2587 68.6824 7 +14.1859 77.6699 7 +41.4421 95.1835 8 +49.9689 93.1219 8 +48.9502 98.5986 8 +48.8835 101.19 8 +50.1349 94.0788 8 +44.9024 96.1416 8 +47.4277 96.6013 8 +48.7175 98.3238 8 +49.6 98.8651 8 +49.647 97.3412 8 +51.0073 96.0242 8 +45.4451 105.71 8 +52.1357 97.8324 8 +47.5369 96.3437 8 +48.0226 98.1668 8 +50.0173 97.4693 8 +46.9606 98.8998 8 +52.3675 98.3242 8 +47.3761 95.6861 8 +50.4993 95.3446 8 +48.3599 95.8236 8 +53.2012 99.5836 8 +48.834 97.0675 8 +51.4258 97.8536 8 +48.2486 98.0379 8 +50.5352 95.2385 8 +51.966 94.314 8 +51.0185 97.0484 8 +53.4679 93.897 8 +51.7624 94.7498 8 +55.3625 99.6402 8 +50.1651 95.5381 8 +48.5293 97.2518 8 +47.6447 97.9821 8 +50.6167 97.58 8 +50.9469 97.2312 8 +50.3737 98.3207 8 +50.9797 98.5861 8 +53.1431 97.0138 8 +45.5952 98.8883 8 +54.1421 95.9169 8 +51.5126 99.1836 8 +49.3575 94.2565 8 +55.9648 101.242 8 +54.0428 96.5008 8 +50.9739 97.871 8 +49.7275 93.3433 8 +52.4788 96.101 8 +47.9087 98.787 8 +49.5041 95.175 8 +51.7279 96.4927 8 +50.3544 99.4839 8 +48.0173 95.9962 8 +48.7575 95.0564 8 +45.5439 96.7317 8 +47.2433 92.9991 8 +50.1988 92.8083 8 +50.4409 95.9461 8 +51.6926 96.0898 8 +50.5479 97.1375 8 +47.9703 97.8309 8 +55.3622 97.4572 8 +51.2496 95.7789 8 +53.0253 96.6107 8 +48.7691 97.7165 8 +52.5326 99.717 8 +47.4153 96.1176 8 +54.98 100.573 8 +50.2622 99.4942 8 +46.1076 97.2104 8 +46.0329 94.5252 8 +51.6916 95.1614 8 +46.5102 96.4943 8 +51.3057 94.2738 8 +44.0614 94.5153 8 +51.6252 97.2491 8 +46.6135 99.319 8 +52.2948 98.226 8 +48.1176 98.1658 8 +51.9199 95.6656 8 +49.6601 97.6666 8 +48.2809 97.1118 8 +50.6258 98.7189 8 +54.5118 97.0744 8 +47.948 98.1689 8 +49.2226 94.6523 8 +53.3937 96.3825 8 +53.1772 96.6464 8 +53.2555 96.4591 8 +51.606 98.8852 8 +47.2193 96.1011 8 +45.934 98.4114 8 +47.952 92.6304 8 +51.9725 96.3493 8 +52.9004 102.211 8 +48.9986 96.982 8 +48.3003 96.289 8 +47.2406 96.6319 8 +45.0341 95.9396 8 +50.452 96.4533 8 +55.8699 93.6161 8 +49.1143 96.7294 8 +49.5852 99.4858 8 +46.9503 96.2251 8 +46.9918 95.9268 8 +50.3754 97.1761 8 +50.7271 100.905 8 +46.92 95.0981 8 +54.6489 96.057 8 +51.3893 93.5392 8 +42.223 98.2652 8 +47.255 96.2813 8 +50.7468 100.008 8 +53.5001 98.5525 8 +50.0758 95.7402 8 +52.6382 97.9511 8 +50.7758 93.3224 8 +49.7789 95.0243 8 +53.3533 95.3494 8 +50.7794 96.8392 8 +48.6835 93.7599 8 +50.5545 100.139 8 +49.9814 99.9025 8 +49.4176 100.063 8 +49.3004 98.1639 8 +51.9416 99.8599 8 +50.779 97.6581 8 +47.4913 95.4818 8 +50.0526 96.9909 8 +51.8662 98.7923 8 +45.192 96.118 8 +52.0513 95.2885 8 +45.1058 98.8115 8 +97.3191 68.0847 9 +99.9103 67.9731 9 +101.142 68.0599 9 +95.8612 68.0137 9 +95.3405 68.0971 9 +96.6713 68.2601 9 +97.7959 67.9033 9 +99.3944 68.066 9 +98.8196 68.1389 9 +100.835 68.3521 9 +96.0567 68.2631 9 +97.7124 67.987 9 +97.6818 68.1729 9 +95.6442 68.2786 9 +94.9751 67.9418 9 +97.0649 68.1848 9 +98.1745 68.299 9 +97.5609 68.0262 9 +97.6705 67.9386 9 +101.017 68.0252 9 +96.6478 68.1323 9 +94.2996 68.1649 9 +96.9756 68.3145 9 +97.2107 67.9364 9 +97.7873 68.2199 9 +97.1539 68.1341 9 +94.7383 68.2297 9 +101.351 68.0265 9 +95.6913 67.955 9 +98.0526 67.943 9 +97.6307 68.0589 9 +96.5153 68.0757 9 +99.7218 68.0519 9 +100.13 68.0103 9 +96.6848 68.0285 9 +98.2577 68.0187 9 +97.8715 68.1369 9 +95.303 68.0653 9 +96.7226 68.0783 9 +96.6646 68.1718 9 +102.01 68.0171 9 +92.8552 68.1594 9 +98.4827 68.0471 9 +98.677 68.3001 9 +94.9963 68.1207 9 +95.0845 68.2416 9 +95.2289 67.9679 9 +98.8395 68.1763 9 +97.5372 67.8789 9 +95.0989 68.0631 9 +96.2249 68.1139 9 +100.754 67.9854 9 +94.6755 68.0948 9 +95.0181 67.8509 9 +98.3966 68.1505 9 +95.9037 68.2702 9 +98.3384 67.9264 9 +98.3108 68.0733 9 +98.3052 68.0953 9 +96.3574 68.0066 9 +97.6805 68.024 9 +98.1658 68.0928 9 +95.5992 68.1486 9 +96.6595 68.1624 9 +96.3046 68.1027 9 +97.6432 68.2355 9 +97.8414 67.9624 9 +99.2772 67.7924 9 +99.1261 68.0036 9 +100.67 68.1046 9 +97.6889 68.172 9 +99.9417 67.9191 9 +95.1743 68.2626 9 +98.7606 67.9607 9 +99.7031 68.0427 9 +94.3437 67.9619 9 +95.6103 68.2285 9 +97.7253 68.3245 9 +97.323 67.9701 9 +97.691 67.9551 9 +97.5687 68.1529 9 +97.2912 67.8588 9 +100.286 68.0849 9 +97.8297 67.9631 9 +95.4533 68.5077 9 +96.3836 68.1377 9 +95.3567 68.0426 9 +98.4426 68.0826 9 +94.4767 68.1639 9 +98.2559 68.0158 9 +96.5007 67.9212 9 +96.8852 68.1787 9 +96.834 67.9841 9 +98.4335 68.2043 9 \ No newline at end of file diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index ec86f64..327b3c0 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -1,56 +1,59 @@ -#include #include #include #include #include -#define MINIMUM_POINTS 4 // minimum number of cluster -#define EPSILON (0.75 * 0.75) // distance for clustering, metre^2 -std::vector readBenchmarkData() { - // load point cloud - std::vector points; - FILE *stream; - stream = fopen("benchmark_hepta.dat", "ra"); - - unsigned int minpts, num_points, cluster, i = 0; - fscanf(stream, "%u\n", &num_points); - - Point *p = (Point *)calloc(num_points, sizeof(Point)); - - while (i < num_points) { - fscanf(stream, "%f,%f,%d\n", &(p[i].x), &(p[i].y), &cluster); - p[i].clusterID = UNCLASSIFIED; - points.push_back(p[i]); - ++i; - } - - free(p); - fclose(stream); - return points; +#include "dbscan.h" +#define MINIMUM_POINTS 6 // minimum number of cluster +#define EPSILON (2.0) // distance for clustering, metre^2 + +std::vector readBenchmarkData(const std::string &filename) { + // load point cloud + std::vector points; + std::ifstream input; + input.open(filename.c_str()); + if (input.is_open()) { + unsigned int minpts, num_points, cluster, i = 0; + input >> num_points; + float x, y; + while (i < num_points) { + input >> x >> y >> cluster; + points.push_back(Point(x, y, UNCLASSIFIED)); + ++i; + } + input.close(); + return points; + } else + return {}; } void printResults(const vector &points, int num_points) { - int i = 0; - std::cout << "Number of Points: " << num_points << std::endl; - std::cout << "x\t\t\ty\t\t\t" << std::endl; - - while (i < num_points) { - std::cout << points[i] << std::endl; - ++i; - } + int i = 0; + std::cout << "Number of Points: " << num_points << std::endl; + std::cout << "x\t\t\ty\t\t\t" << std::endl; + + while (i < num_points) { + std::cout << points[i] << std::endl; + ++i; + } } -int main() { - // read point data - std::vector points = readBenchmarkData(); - - // constructor - DBSCAN ds(MINIMUM_POINTS, EPSILON, points); - // main loop - ds.run(); - // result of DBSCAN algorithm - printResults(ds.getPoints(), ds.getTotalPointSize()); - - return 0; +int main(int argc, char **argv) { + if (argc != 2) { + std::cerr << "Expected data filename" << std::endl; + exit(EXIT_FAILURE); + } + auto filename = argv[1]; + // read point data + std::vector points = readBenchmarkData(filename); + // constructor + DBSCAN ds(MINIMUM_POINTS, EPSILON, points); + // main loop + auto nClusters = ds.run(); + std::cout << "Number of clusters: " << ds.getNClusters() << std::endl; + // result of DBSCAN algorithm + // printResults(ds.getPoints(), ds.getTotalPointSize()); + + return 0; } diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h index 0fe829b..644311e 100644 --- a/include/dbscan/dbscan.h +++ b/include/dbscan/dbscan.h @@ -37,18 +37,18 @@ class DBSCAN { inline double calculateDistance(const Point& pointCore, const Point& pointTarget); - int getTotalPointSize() { return pointSize; } - int getMinimumClusterSize() { return minPoints; } - int getEpsilonSize() { return eps; } - const vector& getPoints() { return points; } - const unsigned int getNClusters() const { return nClusters; } + int getTotalPointSize() { return m_pointSize; } + int getMinimumClusterSize() { return m_minPoints; } + int getEpsilonSize() { return m_epsilon; } + const vector& getPoints() { return m_points; } + const unsigned int getNClusters() { return nClusters; } private: unsigned int nClusters; - unsigned int minPoints; - float eps; - unsigned int pointSize; - vector points; + unsigned int m_minPoints; + float m_epsilon; + unsigned int m_pointSize; + vector m_points; }; #endif // DBSCAN_H diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index 24818a4..e9cabfc 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -12,30 +12,31 @@ #include "dbscan.h" DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, - const vector& p) - : minPoints(minPts), eps(eps) { - pointSize = points.size(); - this->points = p; + const vector& points) + : nClusters(0), m_minPoints(minPts), m_epsilon(eps) { + m_pointSize = points.size(); + m_points = points; } int DBSCAN::run() { int clusterID = 1; typename vector::iterator iter; - for (iter = points.begin(); iter != points.end(); ++iter) { + for (iter = m_points.begin(); iter != m_points.end(); ++iter) { if (iter->clusterID == UNCLASSIFIED) { if (expandCluster(*iter, clusterID) != FAILURE) { clusterID += 1; } } + std::cout << *iter << std::endl; } - nClusters = clusterID; - return nClusters; + this->nClusters = clusterID; + return 0; } int DBSCAN::expandCluster(Point point, int clusterID) { vector clusterSeeds = calculateCluster(point); - if (clusterSeeds.size() < minPoints) { + if (clusterSeeds.size() < m_minPoints) { point.clusterID = NOISE; return FAILURE; } else { @@ -43,9 +44,9 @@ int DBSCAN::expandCluster(Point point, int clusterID) { vector::iterator iterSeeds; for (iterSeeds = clusterSeeds.begin(); iterSeeds != clusterSeeds.end(); ++iterSeeds) { - points.at(*iterSeeds).clusterID = clusterID; - if (points.at(*iterSeeds).x == point.x && - points.at(*iterSeeds).y == point.y) { + m_points.at(*iterSeeds).clusterID = clusterID; + if (m_points.at(*iterSeeds).x == point.x && + m_points.at(*iterSeeds).y == point.y) { indexCorePoint = index; } ++index; @@ -55,20 +56,20 @@ int DBSCAN::expandCluster(Point point, int clusterID) { for (vector::size_type i = 0, n = clusterSeeds.size(); i < n; ++i) { vector clusterNeighors = - calculateCluster(points.at(clusterSeeds[i])); + calculateCluster(m_points.at(clusterSeeds[i])); - if (clusterNeighors.size() >= minPoints) { + if (clusterNeighors.size() >= m_minPoints) { vector::iterator iterNeighors; for (iterNeighors = clusterNeighors.begin(); iterNeighors != clusterNeighors.end(); ++iterNeighors) { - if (points.at(*iterNeighors).clusterID == UNCLASSIFIED || - points.at(*iterNeighors).clusterID == NOISE) { - if (points.at(*iterNeighors).clusterID == + 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(); } - points.at(*iterNeighors).clusterID = clusterID; + m_points.at(*iterNeighors).clusterID = clusterID; } } } @@ -89,8 +90,8 @@ vector DBSCAN::calculateCluster(Point point) { int index = 0; typename vector::iterator iter; vector clusterIndex; - for (iter = points.begin(); iter != points.end(); ++iter) { - if (calculateDistance(point, *iter) <= eps) { + for (iter = m_points.begin(); iter != m_points.end(); ++iter) { + if (calculateDistance(point, *iter) <= m_epsilon) { clusterIndex.push_back(index); } index++; From ae288c8a5c2008481f85509a99cf81bf45b97f3d Mon Sep 17 00:00:00 2001 From: amarrerod Date: Wed, 6 Apr 2022 16:43:17 +0200 Subject: [PATCH 18/23] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Includes=20return=20?= =?UTF-8?q?in=20run=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dbscan/dbscan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index e9cabfc..d5241f9 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -30,7 +30,7 @@ int DBSCAN::run() { std::cout << *iter << std::endl; } this->nClusters = clusterID; - return 0; + return nClusters; } int DBSCAN::expandCluster(Point point, int clusterID) { From 346a13dfa7133e4b10e2ba224be5fd3a52a70252 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Thu, 7 Apr 2022 10:36:08 +0200 Subject: [PATCH 19/23] =?UTF-8?q?=E2=9C=A8=20Introduces=20new=20constructo?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/simpleExample.cpp | 4 ++-- include/dbscan/dbscan.h | 5 +++++ src/dbscan/dbscan.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index 327b3c0..d713cd8 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -14,7 +14,7 @@ std::vector readBenchmarkData(const std::string &filename) { std::ifstream input; input.open(filename.c_str()); if (input.is_open()) { - unsigned int minpts, num_points, cluster, i = 0; + unsigned int num_points, cluster, i = 0; input >> num_points; float x, y; while (i < num_points) { @@ -50,7 +50,7 @@ int main(int argc, char **argv) { // constructor DBSCAN ds(MINIMUM_POINTS, EPSILON, points); // main loop - auto nClusters = ds.run(); + ds.run(); std::cout << "Number of clusters: " << ds.getNClusters() << std::endl; // result of DBSCAN algorithm // printResults(ds.getPoints(), ds.getTotalPointSize()); diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h index 644311e..c4ea7e9 100644 --- a/include/dbscan/dbscan.h +++ b/include/dbscan/dbscan.h @@ -14,6 +14,8 @@ using namespace std; +using coords = std::pair; + typedef struct Point_ { float x, y; // X, Y position int clusterID; // clustered ID @@ -27,6 +29,9 @@ typedef struct Point_ { class DBSCAN { public: + DBSCAN() = delete; + DBSCAN(const unsigned int& minPts, const float& eps, + const vector& coordinates); DBSCAN(const unsigned int& minPts, const float& eps, const vector& points); ~DBSCAN() = default; diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index d5241f9..769a81d 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -11,6 +11,13 @@ #include "dbscan.h" +/** + * @brief Construct a new DBSCAN::DBSCAN object + * + * @param minPts + * @param eps + * @param points + */ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, const vector& points) : nClusters(0), m_minPoints(minPts), m_epsilon(eps) { @@ -18,6 +25,23 @@ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, m_points = points; } +/** + * @brief Construct a new DBSCAN::DBSCAN object + * + * @param minPts + * @param eps + * @param points + */ +DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, + const vector& coordinates) + : nClusters(0), m_minPoints(minPts), m_epsilon(eps) { + m_pointSize = coordinates.size(); + m_points.reserve(m_pointSize); + for (auto& [x, y] : coordinates) { + m_points.push_back(Point(x, y, UNCLASSIFIED)); + } +} + int DBSCAN::run() { int clusterID = 1; typename vector::iterator iter; From f4add23823d26b9e8fe41161b0e44090447dbd0f Mon Sep 17 00:00:00 2001 From: amarrerod Date: Mon, 25 Apr 2022 16:55:24 +0200 Subject: [PATCH 20/23] =?UTF-8?q?=E2=9C=A8=20Includes=20the=20cluster=20cl?= =?UTF-8?q?ass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- example/simpleExample.cpp | 15 +++-- include/dbscan/cluster.h | 45 ++++++++++++++ include/dbscan/dbscan.h | 7 +++ src/dbscan/cluster.cpp | 127 ++++++++++++++++++++++++++++++++++++++ src/dbscan/dbscan.cpp | 42 ++++++++++++- 6 files changed, 229 insertions(+), 9 deletions(-) create mode 100644 include/dbscan/cluster.h create mode 100644 src/dbscan/cluster.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f9efb49..448ef21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ 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 -fPIC") -add_library(${PROJECT_NAME} SHARED src/dbscan/dbscan.cpp) +add_library(${PROJECT_NAME} SHARED src/dbscan/dbscan.cpp src/dbscan/cluster.cpp) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 1) target_include_directories(${PROJECT_NAME} PUBLIC diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index d713cd8..2046497 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -8,9 +8,9 @@ #define MINIMUM_POINTS 6 // minimum number of cluster #define EPSILON (2.0) // distance for clustering, metre^2 -std::vector readBenchmarkData(const std::string &filename) { +std::vector readBenchmarkData(const std::string &filename) { // load point cloud - std::vector points; + std::vector points; std::ifstream input; input.open(filename.c_str()); if (input.is_open()) { @@ -19,7 +19,7 @@ std::vector readBenchmarkData(const std::string &filename) { float x, y; while (i < num_points) { input >> x >> y >> cluster; - points.push_back(Point(x, y, UNCLASSIFIED)); + points.push_back({x, y}); ++i; } input.close(); @@ -46,7 +46,7 @@ int main(int argc, char **argv) { } auto filename = argv[1]; // read point data - std::vector points = readBenchmarkData(filename); + std::vector points = readBenchmarkData(filename); // constructor DBSCAN ds(MINIMUM_POINTS, EPSILON, points); // main loop @@ -54,6 +54,11 @@ int main(int argc, char **argv) { std::cout << "Number of clusters: " << ds.getNClusters() << std::endl; // result of DBSCAN algorithm // printResults(ds.getPoints(), ds.getTotalPointSize()); - + auto clusters = ds.getClusters(); + for (auto &c : clusters) { + c.update(); + std::cout << c << std::endl; + } + std::cout << "Mean radius is: " << ds.radiusOfClusters() << std::endl; return 0; } diff --git a/include/dbscan/cluster.h b/include/dbscan/cluster.h new file mode 100644 index 0000000..54d0a79 --- /dev/null +++ b/include/dbscan/cluster.h @@ -0,0 +1,45 @@ + + +#ifndef CLUSTER_H +#define CLUSTER_H + +#include +#include +#include + +using coords = std::pair; + +class Cluster { + public: + Cluster() = default; + explicit Cluster(const unsigned int& id); + Cluster(const unsigned int& id, const std::vector& coordinates); + + const int getID() const { return id; } + const float getRadius(); + const coords getCentroid(); + + void addPoint(const coords& p) { points.push_back(p); } + void addPoints(const std::vector& points); + std::vector getPoints() const { return points; } + + void update(); + bool empty() const { return points.empty(); } + + friend std::ostream& operator<<(std::ostream& os, const Cluster& c); + + private: + float computeRadius(); + coords computeCentroid(); + + private: + unsigned int id; + float radius; + coords centroid; + std::vector points; + + protected: + const coords nullCoords = {-1.0, -1.0}; +}; + +#endif // \ No newline at end of file diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h index c4ea7e9..452b1eb 100644 --- a/include/dbscan/dbscan.h +++ b/include/dbscan/dbscan.h @@ -5,6 +5,8 @@ #include #include +#include "cluster.h" + #define UNCLASSIFIED -1 #define CORE_POINT 1 #define BORDER_POINT 2 @@ -47,6 +49,9 @@ class DBSCAN { int getEpsilonSize() { return m_epsilon; } const vector& getPoints() { return m_points; } const unsigned int getNClusters() { return nClusters; } + vector getClusters() const { return m_clusters; } + + float radiusOfClusters(); private: unsigned int nClusters; @@ -54,6 +59,8 @@ class DBSCAN { float m_epsilon; unsigned int m_pointSize; vector m_points; + + vector m_clusters; }; #endif // DBSCAN_H diff --git a/src/dbscan/cluster.cpp b/src/dbscan/cluster.cpp new file mode 100644 index 0000000..7af68c7 --- /dev/null +++ b/src/dbscan/cluster.cpp @@ -0,0 +1,127 @@ + + +#include "cluster.h" + +#include +/** + * @brief Construct a new Cluster:: Cluster object + * + * @param id + */ +Cluster::Cluster(const unsigned int& id) : id(id), radius(-1.0), points({}) { + centroid = nullCoords; +} + +/** + * @brief Construct a new Cluster:: Cluster object + * + * @param id + * @param coordinates + */ +Cluster::Cluster(const unsigned int& id, const std::vector& coordinates) + : id(id), radius(-1.0), points(coordinates) { + centroid = nullCoords; +} + +/** + * @brief Includes new points into the cluster + * + * @param pts + */ +void Cluster::addPoints(const std::vector& pts) { + for (const coords& p : pts) { + points.push_back(p); + } +} + +/** + * @brief Method to update the cluster and compute the Centroid and Radius + * + */ +void Cluster::update() { + computeCentroid(); + computeRadius(); +} +/** + * @brief Returns the radius of the cluster + * + * @return float + */ +const float Cluster::getRadius() { + if (radius == -1.0) { + radius = computeRadius(); + } + return radius; +} + +/** + * @brief Method to calculate the radius of the cluster. The radius is defined + * as the mean distance from each city to the centroid + * Definition extracted from: + * + * Smith-Miles, K., Van Hemert, J., & Lim, X. Y. (2010). Understanding TSP + * difficulty by learning from evolved instances. Lecture Notes in Computer + * Science (Including Subseries Lecture Notes in Artificial Intelligence and + * Lecture Notes in Bioinformatics), 6073 LNCS, 266–280. + * https://doi.org/10.1007/978-3-642-13800-3_29 + * @return float + */ +float Cluster::computeRadius() { + radius = 0.0f; + if (centroid == nullCoords) { + // Making sure the centroid is already calculated + computeCentroid(); + } + for (auto [x, y] : points) { + radius += sqrt(((x - centroid.first) * (x - centroid.first)) + + ((y - centroid.second) * (y - centroid.second))); + } + radius /= points.size(); + return radius; +} + +/** + * @brief Returns the centroid of the cluster + * + * @return const coords + */ +const coords Cluster::getCentroid() { + if (centroid == nullCoords) { + centroid = computeCentroid(); + } + return centroid; +} + +/** + * @brief Method to calculate the centroid of the cluster. + * + * @return coords + */ +coords Cluster::computeCentroid() { + auto cX = 0.0f; + auto cY = 0.0f; + for (auto [x, y] : points) { + cX += x; + cY += y; + } + cX /= points.size(); + cY /= points.size(); + centroid = {cX, cY}; + return centroid; +} + +/** + * @brief Prints the information of a Cluster object + * + * @param os + * @param c + * @return std::ostream& + */ +std::ostream& operator<<(std::ostream& os, const Cluster& c) { + os << "Cluster with id: " << c.id << std::endl; + os << "Radius: " << c.radius << std::endl; + os << "Centroid: (" << c.centroid.first << ", " << c.centroid.second << ")" + << std::endl; + os << "Number of points: " << c.points.size() << std::endl; + return os; +} \ No newline at end of file diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index 769a81d..12a5ac0 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -42,8 +42,13 @@ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, } } +/** + * @brief Method to run the DBSCAN algorithm + * + * @return int + */ int DBSCAN::run() { - int clusterID = 1; + int clusterID = 0; typename vector::iterator iter; for (iter = m_points.begin(); iter != m_points.end(); ++iter) { if (iter->clusterID == UNCLASSIFIED) { @@ -51,12 +56,28 @@ int DBSCAN::run() { clusterID += 1; } } - std::cout << *iter << std::endl; } this->nClusters = clusterID; + this->m_clusters.reserve(this->nClusters); + for (unsigned int i = 1; i <= this->nClusters; i++) { + m_clusters.push_back(Cluster(i)); + } + // Filling the cluster + for (const Point& p : m_points) { + if (p.clusterID != UNCLASSIFIED) { + m_clusters[p.clusterID].addPoint({p.x, p.y}); + } + } return nClusters; } +/** + * @brief + * + * @param point + * @param clusterID + * @return int + */ int DBSCAN::expandCluster(Point point, int clusterID) { vector clusterSeeds = calculateCluster(point); @@ -104,7 +125,7 @@ int DBSCAN::expandCluster(Point point, int clusterID) { } /** - * @brief Calculates the clusters in the points + * @brief Calculates the cluster the point belongs to * * @param point * @return vector @@ -135,4 +156,19 @@ 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)); +} + +/** + * @brief Computes the mean radius of the clusters in the points + * It is defined as the mean distance from any city in a cluster to the cluster + * centroid, averaged over all clusters + * @return float + */ +float DBSCAN::radiusOfClusters() { + auto radius = 0.0f; + for (auto& c : m_clusters) { + auto cr = c.getRadius(); + radius += cr; + } + return radius / m_clusters.size(); } \ No newline at end of file From 05c2d58c98f3bb1ad3765e93dbb2968dd6b9f195 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Mon, 2 May 2022 16:37:25 +0200 Subject: [PATCH 21/23] =?UTF-8?q?=F0=9F=90=9B=20Fixes=20a=20bug=20in=20the?= =?UTF-8?q?=20DBSCAN=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/sklearn_example.data | 7 +++++++ example/simpleExample.cpp | 10 +++++----- include/dbscan/dbscan.h | 15 ++++++++++++--- src/dbscan/dbscan.cpp | 26 ++++++++++---------------- 4 files changed, 34 insertions(+), 24 deletions(-) create mode 100644 data/sklearn_example.data diff --git a/data/sklearn_example.data b/data/sklearn_example.data new file mode 100644 index 0000000..151f5ce --- /dev/null +++ b/data/sklearn_example.data @@ -0,0 +1,7 @@ +6 +1 2 0 +2 2 0 +2 3 0 +8 7 1 +8 8 1 +25 80 -1 \ No newline at end of file diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index 2046497..23cbce4 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -5,8 +5,8 @@ #include #include "dbscan.h" -#define MINIMUM_POINTS 6 // minimum number of cluster -#define EPSILON (2.0) // distance for clustering, metre^2 +#define MINIMUM_POINTS 2 // minimum number of cluster +#define EPSILON (3.0) // distance for clustering, metre^2 std::vector readBenchmarkData(const std::string &filename) { // load point cloud @@ -51,9 +51,9 @@ int main(int argc, char **argv) { DBSCAN ds(MINIMUM_POINTS, EPSILON, points); // main loop ds.run(); - std::cout << "Number of clusters: " << ds.getNClusters() << std::endl; - // result of DBSCAN algorithm - // printResults(ds.getPoints(), ds.getTotalPointSize()); + for (auto p : ds.getPoints()) { + std::cout << p << std::endl; + } auto clusters = ds.getClusters(); for (auto &c : clusters) { c.update(); diff --git a/include/dbscan/dbscan.h b/include/dbscan/dbscan.h index 452b1eb..b1ac20f 100644 --- a/include/dbscan/dbscan.h +++ b/include/dbscan/dbscan.h @@ -21,34 +21,43 @@ using coords = std::pair; 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; + return os << "(" << p.x << ", " << p.y + << ") in cluster: " << p.clusterID; } } Point; class DBSCAN { public: DBSCAN() = delete; + DBSCAN(const unsigned int& minPts, const float& eps, const vector& coordinates); + DBSCAN(const unsigned int& minPts, const float& eps, const vector& points); + ~DBSCAN() = default; int run(); vector 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& getPoints() { return m_points; } + const unsigned int getNClusters() { return nClusters; } + vector getClusters() const { return m_clusters; } float radiusOfClusters(); diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index 12a5ac0..246789e 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -38,7 +38,12 @@ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, m_pointSize = coordinates.size(); m_points.reserve(m_pointSize); for (auto& [x, y] : coordinates) { - m_points.push_back(Point(x, y, UNCLASSIFIED)); + Point p; + p.x = x; + p.y = y; + p.clusterID = UNCLASSIFIED; + m_points.push_back(p); + std::cout << p << std::endl; } } @@ -48,8 +53,8 @@ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, * @return int */ int DBSCAN::run() { - int clusterID = 0; - typename vector::iterator iter; + int clusterID = 1; + vector::iterator iter; for (iter = m_points.begin(); iter != m_points.end(); ++iter) { if (iter->clusterID == UNCLASSIFIED) { if (expandCluster(*iter, clusterID) != FAILURE) { @@ -57,18 +62,7 @@ int DBSCAN::run() { } } } - this->nClusters = clusterID; - this->m_clusters.reserve(this->nClusters); - for (unsigned int i = 1; i <= this->nClusters; i++) { - m_clusters.push_back(Cluster(i)); - } - // Filling the cluster - for (const Point& p : m_points) { - if (p.clusterID != UNCLASSIFIED) { - m_clusters[p.clusterID].addPoint({p.x, p.y}); - } - } - return nClusters; + return 0; } /** @@ -133,7 +127,7 @@ int DBSCAN::expandCluster(Point point, int clusterID) { vector DBSCAN::calculateCluster(Point point) { int index = 0; - typename vector::iterator iter; + vector::iterator iter; vector clusterIndex; for (iter = m_points.begin(); iter != m_points.end(); ++iter) { if (calculateDistance(point, *iter) <= m_epsilon) { From e5cecaf05c551e20e20d2084f5dd8ba2552136db Mon Sep 17 00:00:00 2001 From: amarrerod Date: Mon, 2 May 2022 16:52:33 +0200 Subject: [PATCH 22/23] =?UTF-8?q?=F0=9F=90=9B=20Fixes=20the=20algorithm=20?= =?UTF-8?q?an=20cluster=20generation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 5 ++++- example/simpleExample.cpp | 3 ++- src/dbscan/dbscan.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 69decad..81b3601 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,6 +16,9 @@ "makefile_output_printer": "makefile", "makefile_migration_topology": "makefile", "*.tcc": "cpp", - "fstream": "cpp" + "fstream": "cpp", + "deque": "cpp", + "string": "cpp", + "vector": "cpp" } } \ No newline at end of file diff --git a/example/simpleExample.cpp b/example/simpleExample.cpp index 23cbce4..08b0cbb 100644 --- a/example/simpleExample.cpp +++ b/example/simpleExample.cpp @@ -50,7 +50,8 @@ int main(int argc, char **argv) { // constructor DBSCAN ds(MINIMUM_POINTS, EPSILON, points); // main loop - ds.run(); + auto nClusters = ds.run(); + std::cout << "There are " << nClusters << " clusters " << std::endl; for (auto p : ds.getPoints()) { std::cout << p << std::endl; } diff --git a/src/dbscan/dbscan.cpp b/src/dbscan/dbscan.cpp index 246789e..969ca59 100644 --- a/src/dbscan/dbscan.cpp +++ b/src/dbscan/dbscan.cpp @@ -11,6 +11,8 @@ #include "dbscan.h" +#include + /** * @brief Construct a new DBSCAN::DBSCAN object * @@ -43,7 +45,6 @@ DBSCAN::DBSCAN(const unsigned int& minPts, const float& eps, p.y = y; p.clusterID = UNCLASSIFIED; m_points.push_back(p); - std::cout << p << std::endl; } } @@ -62,7 +63,26 @@ int DBSCAN::run() { } } } - return 0; + // Creating the clusters + std::map> clusters; + + for (unsigned int i = 1; i <= this->nClusters; i++) { + m_clusters.push_back(Cluster(i)); + } + // Filling the cluster + for (const Point& p : m_points) { + if (p.clusterID != UNCLASSIFIED) { + if (clusters.find(p.clusterID) != clusters.end()) { + clusters.insert({p.clusterID, {}}); + } + clusters[p.clusterID].push_back({p.x, p.y}); + } + } + for (auto [id, points] : clusters) { + this->m_clusters.push_back(Cluster(id, points)); + } + this->nClusters = clusters.size(); + return nClusters; } /** From 48c0bd8f4b3a5632d4808c88901ae39b0e80aa57 Mon Sep 17 00:00:00 2001 From: amarrerod Date: Tue, 18 Oct 2022 11:02:36 +0100 Subject: [PATCH 23/23] =?UTF-8?q?=F0=9F=91=B7=20Updates=20installation=20c?= =?UTF-8?q?onfiguration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 448ef21..1c3cc15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,6 @@ set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE ON) 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 -fPIC") - add_library(${PROJECT_NAME} SHARED src/dbscan/dbscan.cpp src/dbscan/cluster.cpp) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 1) @@ -27,14 +26,12 @@ install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) -install(FILES ${CMAKE_BINARY_DIR}/dbscan.pc - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig - ) +) +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY lib/ DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(EXPORT ${PROJECT_NAME}Config DESTINATION share/${PROJECT_NAME}/cmake) export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}.cmake) - add_executable(example example/simpleExample.cpp) target_link_libraries(example PRIVATE ${PROJECT_NAME}) \ No newline at end of file