Added RandomPointSelection module
This commit is contained in:
@@ -4,6 +4,7 @@ set(SOURCES
|
||||
dbscan.hpp
|
||||
dbscan_impl.hpp
|
||||
random_point_selection.hpp
|
||||
ordered_point_selection.hpp
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
|
||||
@@ -192,13 +192,14 @@ void DBSCAN<RangeSearchType, PointSelectionPolicy>::BatchCluster(
|
||||
// Now loop over all points.
|
||||
for (size_t i = 0; i < data.n_cols; ++i)
|
||||
{
|
||||
// Union to all neighbors.
|
||||
for (size_t j = 0; j < neighbors[i].size(); ++j)
|
||||
uf.Union(i, neighbors[i][j]);
|
||||
// Get the next index.
|
||||
const size_t index = pointSelector.Select(i, data);
|
||||
for (size_t j = 0; j < neighbors[index].size(); ++j)
|
||||
uf.Union(index, neighbors[index][j]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dbscan
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <mlpack/core/tree/binary_space_tree.hpp>
|
||||
#include <mlpack/core/tree/rectangle_tree.hpp>
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
|
||||
#include <mlpack/methods/dbscan/random_point_selection.hpp>
|
||||
#include "dbscan.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
@@ -76,6 +76,8 @@ PARAM_FLAG("single_mode", "If set, single-tree range search (not dual-tree) "
|
||||
"will be used.", "S");
|
||||
PARAM_FLAG("naive", "If set, brute-force range search (not tree-based) "
|
||||
"will be used.", "N");
|
||||
PARAM_FLAG("random_selection", "If set, random point selection (not ordered) "
|
||||
"will be used.", "R");
|
||||
|
||||
// Actually run the clustering, and process the output.
|
||||
template<typename RangeSearchType>
|
||||
@@ -86,13 +88,26 @@ void RunDBSCAN(RangeSearchType rs = RangeSearchType())
|
||||
|
||||
// Load dataset.
|
||||
arma::mat dataset = std::move(CLI::GetParam<arma::mat>("input"));
|
||||
|
||||
|
||||
const double epsilon = CLI::GetParam<double>("epsilon");
|
||||
const size_t minSize = (size_t) CLI::GetParam<int>("min_size");
|
||||
|
||||
DBSCAN<RangeSearchType> d(epsilon, minSize, !CLI::HasParam("single_mode"),
|
||||
rs);
|
||||
|
||||
// Check if random selection is used.
|
||||
if (!CLI::HasParam("random_selection"))
|
||||
{
|
||||
DBSCAN<RangeSearchType> d(epsilon, minSize, !CLI::HasParam("single_mode"),
|
||||
rs);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBSCAN<RangeSearchType, RandomPointSelection> d(epsilon, minSize,
|
||||
!CLI::HasParam("single_mode"), rs);
|
||||
}
|
||||
|
||||
DBSCAN<RangeSearchType, RandomPointSelection> d(epsilon, minSize,
|
||||
!CLI::HasParam("single_mode"), rs);
|
||||
|
||||
// If possible, avoid the overhead of calculating centroids.
|
||||
arma::Row<size_t> assignments;
|
||||
if (CLI::HasParam("centroids"))
|
||||
|
||||
@@ -27,16 +27,24 @@ class RandomPointSelection
|
||||
/**
|
||||
* Select the next point to use, randomly.
|
||||
*
|
||||
* @param unvisited Bitset indicating which points are unvisited.
|
||||
* @param data Unused data.
|
||||
* @param point Unused data.
|
||||
* @param data Dataset to cluster.
|
||||
*/
|
||||
template<typename MatType>
|
||||
static size_t Select(const boost::dynamic_bitset<>& unvisited,
|
||||
const MatType& /* data */)
|
||||
size_t Select(const size_t /* point */,
|
||||
const MatType& data /* data */)
|
||||
{
|
||||
// Initialize the length of the unvisited bitset
|
||||
size_t size = data.n_cols; // Get the size of points.
|
||||
if (unvisited.size() != size)
|
||||
{
|
||||
unvisited.resize(size); // Resize & Set bitset to one
|
||||
unvisited.set();
|
||||
}
|
||||
|
||||
const size_t max = unvisited.count();
|
||||
const size_t index = math::RandInt(max);
|
||||
|
||||
|
||||
// Select the index'th unvisited point.
|
||||
size_t found = 0;
|
||||
for (size_t i = 0; i < unvisited.size(); ++i)
|
||||
@@ -45,14 +53,20 @@ class RandomPointSelection
|
||||
++found;
|
||||
|
||||
if (found > index)
|
||||
{
|
||||
unvisited[i].flip(); // Set unvisited point to visited point
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Not sure if it is possible to get here.
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
// Bitmask for unvisited points, If true, mean unvisited.
|
||||
boost::dynamic_bitset<> unvisited;
|
||||
};
|
||||
|
||||
} // namespace dbscan
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user