QT+VS实现Kmeans++
1、Kmeans++的原理如下:
(1)首先选取样本中任一数据点作为第一个聚类中心;
(2)计算样本每一个数据点至现所有聚类中心的最近距离,并记录下来;
(3)逐一挑选所有数据点最近距离之中的最大值,即最远距离,最大值对应的数据点为待求聚类中心;
(4)剔除已选为聚类中心的样本点,重新计算(2)、(3)步骤,得到指定的最终的聚类中心点数。
2、实现结果如下:

计算K个初始聚类中心的代码如下:
void Kmeans::CalK()
{vPointKData.push_back(vPointData.at(0));CalDistance();while (vPointKData.size() != K){qDebug() <<vPointKData.size()<< vPointKData.at(vPointKData.size()-1).number;vS.clear();CalDistance();std::vector<pointXY> vk; int t3 = vPointKData.size();while (vk.size() != t3){pointXY p9 = vPointKData.at(0); int t2=0;for (int i = 1; i < vPointKData.size(); i++){if (p9.number < vPointKData.at(i).number){p9 = vPointKData.at(i);t2 = i;}}vPointKData.erase(vPointKData.begin() + t2);//删除下标为t2的元素;vk.push_back(p9);}for (int i = vk.size() - 1; i >= 0; i--){vPointKData.push_back(vk.at(i));}for (auto& val : vPointKData){qDebug() << val.number << val.x << val.y;}int cv = 1;for (auto& val : vPointKData){vS.erase(vS.begin() + (val.number-cv));//删除下标为val.number的元素;cv++;}double s0 = 0;pointXY kk;kk = { 0,0,0 };for (auto& valS : vS){if (s0 <= valS.distance){s0 = valS.distance;kk.number = valS.number;kk.x = valS.x;kk.y = valS.y;}}vPointKData.push_back(kk);}int count = 1;for (auto& val : vPointKData){val.number = count;count++;qDebug() << val.number << val.x << val.y;}
}
void Kmeans::CalDistance()
{Dis ss;for (auto& valP : vPointData){double s0 = 0; int c = 1;double x1 = valP.x;double y1 = valP.y;for (auto& valK : vPointKData){double x2 = valK.x;double y2 = valK.y;x2 = x2 - x1;y2 = y2 - y1;double s = sqrt(x2 * x2 + y2 * y2);if (c == 1){s0 = s;ss.number = valP.number;ss.numberK = valK.number;ss.x = valP.x;ss.y = valP.y;ss.distance = s;c++;}if (s0 == 0){ss.number = valP.number;ss.numberK = valK.number;ss.x = valP.x;ss.y = valP.y;ss.distance = s;break;}if (s < s0){s0 = s;ss.number = valP.number;ss.numberK = valK.number;ss.x = valP.x;ss.y = valP.y;ss.distance = s;}}vS.push_back(ss);}
}