void kmedians::calculate_median(cluster & current_cluster, point & median) { const dataset & data = *m_ptr_data; const std::size_t dimension = data[0].size(); for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) { std::sort(current_cluster.begin(), current_cluster.end(), [this](std::size_t index_object1, std::size_t index_object2) { return (*m_ptr_data)[index_object1] > (*m_ptr_data)[index_object2]; }); std::size_t relative_index_median = (std::size_t) (current_cluster.size() - 1) / 2; std::size_t index_median = current_cluster[relative_index_median]; if (current_cluster.size() % 2 == 0) { std::size_t index_median_second = current_cluster[relative_index_median + 1]; median[index_dimension] = (data[index_median][index_dimension] + data[index_median_second][index_dimension]) / 2.0; } else { median[index_dimension] = data[index_median][index_dimension]; } } }
void agglomerative::calculate_center(const cluster & cluster, point & center) { const std::vector<point> & data = *m_ptr_data; const size_t dimension = data[0].size(); center.resize(dimension, 0.0); for (auto index_point : cluster) { for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) { center[index_dimension] += data[index_point][index_dimension]; } } for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) { center[index_dimension] /= cluster.size(); } }
double kmeans::update_center(const cluster & p_cluster, point & p_center) { point total(p_center.size(), 0.0); /* for each object in cluster */ for (auto object_index : p_cluster) { /* for each dimension */ for (size_t dimension = 0; dimension < total.size(); dimension++) { total[dimension] += (*m_ptr_data)[object_index][dimension]; } } /* average for each dimension */ for (size_t dimension = 0; dimension < total.size(); dimension++) { total[dimension] = total[dimension] / p_cluster.size(); } const double change = m_metric(p_center, total); p_center = std::move(total); return change; }