8 #ifndef PAAL_K_MEANS_CLUSTERING_ENGINE_HPP
9 #define PAAL_K_MEANS_CLUSTERING_ENGINE_HPP
15 #include <boost/range/combine.hpp>
16 #include <boost/range/adaptor/indexed.hpp>
17 #include <boost/range/algorithm_ext/iota.hpp>
18 #include <boost/range/algorithm/for_each.hpp>
32 template <
class RangeLeft,
class RangeRight>
34 assert(!boost::empty(lrange));
35 assert(boost::distance(lrange) == boost::distance(rrange));
38 decltype(*std::begin(lrange) * *std::begin(rrange)) dist{};
39 for (
auto point_pair : boost::combine(lrange, rrange)) {
40 auto diff = boost::get<0>(point_pair) - boost::get<1>(point_pair);
52 template <
class Po
int,
class Centers>
55 auto dist = std::numeric_limits<coor_t>::max();
57 for (
auto center : centers | boost::adaptors::indexed()){
60 if (new_dist < dist) {
62 new_center = center.index();
76 template <
class Center,
class New_center>
77 void move_center(Center &last_center, New_center &new_center) {};
99 template <
class Points,
102 class ClosestTo,
class OutputIterator,
104 class Visitor=k_means_visitor >
105 auto k_means(Points &&points, Centers & centers,
107 OutputIterator result,
108 CentroidEqual c_equal = CentroidEqual{},
109 Visitor visitor=Visitor{}) {
110 using point_t = range_to_elem_t<Points>;
111 using points_bag = std::vector<point_t>;
113 std::vector<points_bag> cluster_points;
114 cluster_points.resize(centers.size());
117 visitor.new_iteration();
119 boost::for_each(cluster_points, std::mem_fn(&points_bag::clear));
121 for (
auto && point : points) {
122 cluster_points[
closest_to(point)].push_back(point);
125 for (
auto point : cluster_points | boost::adaptors::indexed()) {
126 if(point.value().empty())
continue;
127 auto && old_center = centers[point.index()];
128 auto && new_center = centroid(point.value());
129 if (!c_equal(new_center, old_center)) {
130 visitor.move_center(old_center, new_center);
131 old_center = new_center;
135 }
while (zm ==
true);
136 for (
int cur_cluster :
irange(cluster_points.size())) {
137 for (
auto const & point : cluster_points[cur_cluster]) {
138 *result = std::make_pair(point, cur_cluster);
150 template <
typename Po
ints,
typename OutputIterator,
typename RNG = std::default_random_engine>
152 RNG && rng = std::default_random_engine{}) {
154 std::vector<int> centers(points.size());
155 boost::iota(centers, 0);
156 std::shuffle(centers.begin(),centers.end(), rng);
157 centers.resize(number_of_centers);
158 for (
auto && center : centers) {
169 template <
typename Po
ints,
typename RNG = std::default_random_engine>
171 RNG && rng = std::default_random_engine{}) {
172 std::vector<typename std::decay<Points>::type> clusters(number_of_clusters);
173 std::uniform_int_distribution<> dis(0, number_of_clusters - 1);
175 for (
auto o : points) {
176 clusters[distribution(rng)].push_back(o);
typename boost::range_value< Range >::type range_to_elem_t
for given range returns type of its element
auto get_random_clusters(Points &&points, int number_of_clusters, RNG &&rng=std::default_random_engine{})
void new_iteration()
new iteration
auto closest_to(Point &&point, Centers &¢ers)
auto k_means(Points &&points, Centers &¢ers, OutputIterator result, Visitor visitor=Visitor{})
this is solve k_means_clustering problem and return vector of cluster example:
auto irange(T begin, T end)
irange
This file contains set of simple useful functors or functor adapters.
auto get_random_centers(Points &&points, int number_of_centers, OutputIterator out, RNG &&rng=std::default_random_engine{})
auto distance_square(RangeLeft &&lrange, RangeRight &&rrange)
void move_center(Center &last_center, New_center &new_center)