Skip to content

Commit

Permalink
#589, #588, #587, #379: Optimized balanced KD-tree for C++ pyclusteri…
Browse files Browse the repository at this point in the history
…ng. DBSCAN, OPTICS, CURE optimization.
  • Loading branch information
annoviko committed Feb 18, 2020
1 parent d53287b commit 2d4a03a
Show file tree
Hide file tree
Showing 19 changed files with 501 additions and 599 deletions.
18 changes: 9 additions & 9 deletions ccore/include/pyclustering/cluster/dbscan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <cmath>
#include <algorithm>

#include <pyclustering/container/kdtree.hpp>
#include <pyclustering/container/kdtree_balanced.hpp>

#include <pyclustering/cluster/dbscan_data.hpp>

Expand Down Expand Up @@ -60,21 +60,21 @@ Implementation based on paper @cite inproceedings::dbscan::1.
*/
class dbscan {
private:
const dataset * m_data_ptr = nullptr; /* temporary pointer to input data that is used only during processing */
const dataset * m_data_ptr = nullptr; /* temporary pointer to input data that is used only during processing */

dbscan_data * m_result_ptr = nullptr; /* temporary pointer to clustering result that is used only during processing */
dbscan_data * m_result_ptr = nullptr; /* temporary pointer to clustering result that is used only during processing */

std::vector<bool> m_visited = { };
std::vector<bool> m_visited = { };

std::vector<bool> m_belong = { };
std::vector<bool> m_belong = { };

double m_initial_radius = 0.0; /* original radius that was specified by user */
double m_initial_radius = 0.0; /* original radius that was specified by user */

size_t m_neighbors = 0;
size_t m_neighbors = 0;

dbscan_data_t m_type = dbscan_data_t::POINTS;
dbscan_data_t m_type = dbscan_data_t::POINTS;

container::kdtree m_kdtree = container::kdtree();
container::kdtree_balanced m_kdtree = container::kdtree_balanced();

public:
/*!
Expand Down
8 changes: 4 additions & 4 deletions ccore/include/pyclustering/cluster/optics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <set>
#include <tuple>

#include <pyclustering/container/kdtree.hpp>
#include <pyclustering/container/kdtree_balanced.hpp>

#include <pyclustering/cluster/optics_data.hpp>
#include <pyclustering/cluster/optics_descriptor.hpp>
Expand Down Expand Up @@ -100,11 +100,11 @@ class optics {

optics_data_t m_type = optics_data_t::POINTS;

container::kdtree m_kdtree = container::kdtree();
container::kdtree_balanced m_kdtree = container::kdtree_balanced();

optics_object_sequence * m_optics_objects = nullptr;
optics_object_sequence * m_optics_objects = nullptr;

std::list<optics_descriptor *> m_ordered_database = { };
std::list<optics_descriptor *> m_ordered_database = { };

public:
/*!
Expand Down
93 changes: 62 additions & 31 deletions ccore/include/pyclustering/container/kdnode.hpp
Original file line number Diff line number Diff line change
@@ -1,51 +1,53 @@
/**
*
* @authors Andrei Novikov (pyclustering@yandex.ru)
* @date 2014-2020
* @copyright GNU Public License
*
* GNU_PUBLIC_LICENSE
* pyclustering is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* pyclustering is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
/*!
@authors Andrei Novikov (pyclustering@yandex.ru)
@date 2014-2020
@copyright GNU Public License
@cond GNU_PUBLIC_LICENSE
pyclustering is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyclustering is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
@endcond
*/


#pragma once


#include <functional>
#include <memory>
#include <vector>

#include <pyclustering/definitions.hpp>


namespace pyclustering {

namespace container {

/**
*
* @brief Node of KD Tree.
*
*/
class kdnode {
/*!
friend class kdtree;
@brief Node of KD Tree.
*/
class kdnode : public std::enable_shared_from_this<kdnode> {
public:
using ptr = std::shared_ptr<kdnode>;
using ptr = std::shared_ptr<kdnode>;

private:
using weak_ptr = std::weak_ptr<kdnode>;
using weak_ptr = std::weak_ptr<kdnode>;
using search_node_rule = std::function< bool(const kdnode&) >;

private:
std::vector<double> m_data = { };
Expand All @@ -68,13 +70,17 @@ friend class kdtree;

virtual ~kdnode() = default;

private:
public:
void set_left(const kdnode::ptr & p_node);

void set_right(const kdnode::ptr & p_node);

void set_parent(const kdnode::ptr & p_node);

void set_data(const point & p_data);

void set_payload(void * p_payload);

void set_discriminator(const std::size_t disc);

public:
Expand All @@ -84,7 +90,32 @@ friend class kdtree;

kdnode::ptr get_parent() const;

void * get_payload();
void * get_payload() const;

/*!
@brief Find node in KD-tree using current node as a root of a subtree, the first founded node with
specified coordinates is returned.
@param[in] p_point: coordinates of searched node.
@return Pointer to found node in the sub-tree.
*/
kdnode::ptr find_node(const point & p_point);

/*!
@brief Find node using specified rule, it returns the first node that satisfy search rule.
@param[in] p_point: coordinates of searched node.
@param[in] p_cur_node: node from which search is performed.
@param[in] p_rule: rule that should be satisfied by searched node.
@return Return the smallest node in specified subtree in line with discriminator.
*/
kdnode::ptr find_node(const point & p_point, const search_node_rule & p_rule);

const std::vector<double> & get_data() const;

Expand Down

0 comments on commit 2d4a03a

Please sign in to comment.