Kmeans聚类算法C++实现

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]);
    }
}
 

转载于:https://my.oschina.net/lCQ3FC3/blog/1583825

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值