22 #ifndef CRNkMedoids_HEADER
23 #define CRNkMedoids_HEADER
49 std::vector<size_t>
operator()(
const std::vector<std::vector<double>> &distmat)
const;
60 PAM(
size_t n_classes):k(n_classes) {}
61 std::vector<size_t>
operator()(
const std::vector<std::vector<double>> &distmat)
const;
74 void operator()(std::vector<size_t> &medoids,
const std::vector<std::multimap<double, size_t>> &clusters,
const std::vector<std::vector<double>> &distmat)
const;
83 void operator()(std::vector<size_t> &medoids,
const std::vector<std::multimap<double, size_t>> &clusters,
const std::vector<std::vector<double>> &distmat)
const;
95 template<
typename Init,
typename Update> std::tuple<std::vector<size_t>, std::vector<std::multimap<double, size_t>>, std::vector<size_t>>
Run(Init init, Update update,
const std::vector<std::vector<double>> &distmat,
size_t maxiter = std::numeric_limits<size_t>::max())
97 const auto nelem = distmat.size();
99 for (
const auto &row : distmat)
100 if (row.size() != nelem)
103 auto medoids = init(distmat);
104 const auto k = medoids.size();
112 auto clusters = std::vector<std::multimap<double, size_t>>(k);
113 auto distsum = 0.0, precsum = std::numeric_limits<double>::max();
114 auto iter =
size_t{0};
115 while (precsum != distsum)
120 std::vector<std::multimap<double, size_t>>(k).swap(clusters);
121 for (
auto o =
size_t(0); o < nelem; ++o)
123 auto ndist = std::numeric_limits<double>::max();
124 auto nclass =
size_t{0};
125 for (
auto m =
size_t(0); m < k; ++m)
126 if (distmat[o][medoids[m]] < ndist)
128 ndist = distmat[o][medoids[m]];
131 clusters[nclass].insert(std::make_pair(ndist, o));
135 update(medoids, clusters, distmat);
137 if (++iter >= maxiter)
140 auto classnum = std::vector<size_t>(nelem, 0);
141 for (
auto c =
size_t(0); c < k; ++c)
142 for (
const auto &o : clusters[c])
143 classnum[o.second] = c;
144 return std::make_tuple(std::move(classnum), std::move(clusters), std::move(medoids));
std::vector< size_t > operator()(const std::vector< std::vector< double >> &distmat) const
void operator()(std::vector< size_t > &medoids, const std::vector< std::multimap< double, size_t >> &clusters, const std::vector< std::vector< double >> &distmat) const
Finds the k most central elements.
std::vector< size_t > operator()(const std::vector< std::vector< double >> &distmat) const
void operator()(std::vector< size_t > &medoids, const std::vector< std::multimap< double, size_t >> &clusters, const std::vector< std::vector< double >> &distmat) const
Gets the element with the lower distance to other elements in the cluster.
std::tuple< std::vector< size_t >, std::vector< std::multimap< double, size_t > >, std::vector< size_t > > Run(Init init, Update update, const std::vector< std::vector< double >> &distmat, size_t maxiter=std::numeric_limits< size_t >::max())
k medoids
Central(size_t n_classes)