28 using namespace kmedoids;
32 const auto nelem = distmat.size();
35 auto lsum = std::vector<double>(nelem);
36 std::transform(distmat.begin(), distmat.end(), lsum.begin(),
37 [](
const std::vector<double> &l){
return std::accumulate(l.begin(), l.end(), 0.0); });
40 auto v = std::vector<double>(nelem, 0.0);
41 for (
size_t j = 0; j < nelem; ++j)
42 for (
size_t i = 0; i < nelem; ++i)
43 v[j] += distmat[i][j] / lsum[i];
46 auto medoids = std::vector<size_t>(k);
47 for (
size_t tmp = 0; tmp < k; ++tmp)
49 auto minit = std::min_element(v.begin(), v.end());
50 medoids[tmp] = minit - v.begin();
51 *minit = std::numeric_limits<double>::max();
59 const auto nelem = distmat.size();
62 auto lsum = std::vector<double>(nelem);
63 std::transform(distmat.begin(), distmat.end(), lsum.begin(),
64 [](
const std::vector<double> &l){
return std::accumulate(l.begin(), l.end(), 0.0); });
66 auto medoids = std::vector<size_t>(k);
68 medoids[0] = std::min_element(lsum.begin(), lsum.end()) - lsum.begin();
70 for (
size_t m = 1; m < k; ++m)
73 auto g = std::vector<double>(nelem, 0.0);
74 for (
size_t i = 0; i < nelem; ++i)
78 for (
size_t tmp = 0; tmp < m; ++tmp)
79 if (medoids[tmp] == i) { found =
true;
break; }
81 for (
size_t j = 0; j < nelem; ++j)
84 auto ndist = std::numeric_limits<double>::max();
85 for (
size_t tmp = 0; tmp < m; ++tmp)
86 if (distmat[j][medoids[tmp]] < ndist)
88 ndist = distmat[j][medoids[tmp]];
90 g[i] +=
crn::Max(ndist - distmat[j][i], 0.0);
93 medoids[m] = std::max_element(g.begin(), g.end()) - g.begin();
98 void update::Local::operator()(std::vector<size_t> &medoids,
const std::vector<std::multimap<double, size_t>> &clusters,
const std::vector<std::vector<double>> &distmat)
const
100 for (
size_t m = 0; m < medoids.size(); ++m)
102 auto ndist = std::numeric_limits<double>::max();
103 auto nobj =
size_t{0};
104 for (
const auto &o : clusters[m])
107 for (
const auto &n : clusters[m])
109 sdist += distmat[n.second][o.second];
121 void update::PAM::operator()(std::vector<size_t> &medoids,
const std::vector<std::multimap<double, size_t>> &clusters,
const std::vector<std::vector<double>> &distmat)
const
123 size_t mini = 0, minh = 0;
124 auto mintih = std::numeric_limits<double>::max();
125 for (
size_t i = 0; i < medoids.size(); ++i)
127 for (
size_t c = 0; c < clusters.size(); ++c)
128 for (
const auto &h : clusters[c])
131 if (h.second == medoids[c])
continue;
133 for (
size_t tc = 0; tc < clusters.size(); ++tc)
134 for (
const auto &j : clusters[tc])
136 if (distmat[medoids[i]][j.second] > j.first)
137 tih +=
crn::Min(distmat[j.second][h.second] - j.first, 0.0);
140 auto ndist = std::numeric_limits<double>::max();
141 for (
size_t tk = 0; tk < clusters.size(); ++tk)
143 if (tk == tc)
continue;
144 if (distmat[j.second][medoids[tk]] < ndist)
146 ndist = distmat[j.second][medoids[tk]];
149 tih +=
crn::Min(distmat[j.second][h.second], ndist) - j.first;
164 medoids[mini] = minh;
std::vector< size_t > operator()(const std::vector< std::vector< double >> &distmat) const
const T & Max(const T &a, const T &b)
Returns the max of two values.
void operator()(std::vector< size_t > &medoids, const std::vector< std::multimap< double, size_t >> &clusters, const std::vector< std::vector< double >> &distmat) const
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
const T & Min(const T &a, const T &b)
Returns the min of two values.