function kMedoids(data, k, maxIterations = 100) {
const n = data.length;
let medoids = [];
for (let i = 0; i < k; i++) {
medoids.push(data[Math.floor(Math.random() * n)]);
}
let iterations = 0;
let converged = false;
while (!converged && iterations < maxIterations) {
const assignments = assignToMedoids(data, medoids);
const newMedoids = [];
for (let i = 0; i < k; i++) {
const cluster = assignments
.map((assignment, j) => (assignment === i ? j : -1))
.filter(index => index !== -1);
const bestMedoidIndex = findBestMedoid(cluster, data);
newMedoids.push(data[bestMedoidIndex]);
}
converged = JSON.stringify(medoids) === JSON.stringify(newMedoids);
medoids = newMedoids;
iterations++;
}
const finalAssignments = assignToMedoids(data, medoids);
const finalCost = calculateCost(data, medoids, finalAssignments);
return { medoids, assignments: finalAssignments, cost: finalCost };
}