#include <iostream>
#include <vector>
#include <cmath>
#include <omp.h>
float
distance(
const
std::vector<
float
>& point1,
const
std::vector<
float
>& point2) {
float
sum = 0.0f;
for
(
int
i = 0; i < point1.size(); i++) {
sum += std::
pow
(point1[i] - point2[i], 2);
}
return
std::
sqrt
(sum);
}
void
assignDataPointsToClusters(
const
std::vector<std::vector<
float
>>& dataPoints,
const
std::vector<std::vector<
float
>>& clusterCenters,
std::vector<
int
>& assignedClusters) {
int
numDataPoints = dataPoints.size();
#pragma omp parallel for
for
(
int
i = 0; i < numDataPoints; i++) {
float
minDistance = std::numeric_limits<
float
>::max();
int
assignedCluster = -1;
for
(
int
j = 0; j < clusterCenters.size(); j++) {
float
d = distance(dataPoints[i], clusterCenters[j]);
if
(d < minDistance) {
minDistance = d;
assignedCluster = j;
}
}
assignedClusters[i] = assignedCluster;
}
}
void
updateClusterCenters(
const
std::vector<std::vector<
float
>>& dataPoints,
const
std::vector<
int
>& assignedClusters,
std::vector<std::vector<
float
>>& clusterCenters) {
int
numClusters = clusterCenters.size();
int
numDimensions = clusterCenters[0].size();
std::vector<
int
> clusterSizes(numClusters, 0);
std::vector<std::vector<
float
>> newClusterCenters(numClusters, std::vector<
float
>(numDimensions, 0.0f));
for
(
int
i = 0; i < dataPoints.size(); i++) {
int
cluster = assignedClusters[i];
clusterSizes[cluster]++;
for
(
int
j = 0; j < numDimensions; j++) {
newClusterCenters[cluster][j] += dataPoints[i][j];
}
}
for
(
int
i = 0; i < numClusters; i++) {
int
size = clusterSizes[i];
for
(
int
j = 0; j < numDimensions; j++) {
if
(size > 0) {
newClusterCenters[i][j] /= size;
}
}
}
clusterCenters = newClusterCenters;
}
int
main() {
std::vector<std::vector<
float
>> dataPoints = {{1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f}, {7.0f, 8.0f}};
std::vector<std::vector<
float
>> clusterCenters = {{1.5f, 2.5f}, {6.0f, 6.0f}};
std::vector<
int
> assignedClusters(dataPoints.size());
int
numIterations = 10;
for
(
int
i = 0; i < numIterations; i++) {
assignDataPointsToClusters(dataPoints, clusterCenters, assignedClusters);
updateClusterCenters(dataPoints, assignedClusters, clusterCenters);
}
for
(
int
i = 0; i < assignedClusters.size(); i++) {
std::cout <<
"Data point "
<< i <<
" belongs to cluster "
<< assignedClusters[i] << std::endl;
}
return
0;
}