root@iZ25x7gak9qZ:/data/script/C_script# cat mykmeans.cpp
#include <iostream>
#include <vector>
#include <limits>
#include <array>
#include <cassert>
#include <cmath>
using std::cout;
using std::endl;
using std::vector;
using std::array;
const int P=12;
const int M=3;
template <typename T>
void show(const T& t){
for(auto& x: t)
cout << x << " ";
cout << endl;
}
void init_center(vector<double>& center,
const array<int,P>& X){
srand(time(0));
for(int i=0;i<M;++i){
int j=rand()%P;
j=3;
cout << "j " << j << endl;
center[i]=X[j];
}
}
int nearest(const vector<double>& center,
double sample){
double dist=std::numeric_limits<double>::max();
int rect=-1;
for(int i=0;i<center.size();++i){
if(fabs(center[i]-sample)<dist){
dist=fabs(center[i]-sample);
rect=i;
}
}
return rect;
}
inline double calCenter(const vector<double>& g){
double sum=0.0;
for(auto& i:g)
sum+=i;
size_t s=(g.size()>0)?g.size():1;
return sum/s;
}
inline double calDistance(const vector<double>& dvec1,
const vector<double>& dvec2){
assert(dvec1.size()==dvec2.size());
double err=0;
for(int i=0;i<dvec1.size();++i){
err+=fabs(dvec1[i]-dvec2[i]);
}
return err;
}
int main(int argc, char** argv){
array<int,P> X ={1,2,3,4,5,6,7,8,9,10,20,23};
assert(P%M==0);
vector<vector<double> > group(M);;
vector<double> center(M);
vector<double> ncenter(M);
double gap=0.1;
init_center(center,X);
assert(group.size()==center.size());
assert(center.size()==ncenter.size());
show(center);
while(true){
for(int i=0;i<group.size();++i){
group[i].clear();
}
for(int i=0;i<P;++i){
int n=nearest(center,X[i]);
group[n].push_back(X[i]);
}
for(int i=0;i<center.size();++i){
double m=calCenter(group[i]);
ncenter[i]=m;
}
double dist=calDistance(center,ncenter);
center=ncenter;
cout << dist << endl;
if(dist < gap){
break;
}
}
show(center);
for(int i=0;i<group.size();++i){
cout << i << "[";
show(group[i]);
}
}