K-means算法

K-means算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<math.h>
 
using namespace std;
 
#define K 4 /*数据维度*/
#define C 8 /*聚类数*/
#define N 150 /*样本数*/
#define IterMax 5/*最大迭代数*/
#define IterTherhold  0.0000001 /*结束条件*/
 
/*样本数据*/
typedef struct{
    double p[K];
    int Lable;
    double dis[K];
}Data;
 
Data dat[N];
double cluster[C][K] = {0.0};
double oldfitness = 0.0;
double fitness = 0.0;
 
bool is_equal(int rand_num[], int n, int index)
{
    for(int i = 0; i < n; i++) {
        if(rand_num[i] == index) {
            return true;
        }
    }
    return false;
}
 
void input_data()
{
    ifstream in("test.data", ios::in);
 
    int i = 0;
    while(i < N) {
        for(int k = 0; k < K; k++){
            in >> dat[i].p[k];
        }  
        i++;
    }
}
//初始化质心
void Init_center()
{
    int rand_num[C] ={0} ;
    int i = 0;
    while(i < C) {
        int index = rand()%N;
        if(!is_equal(rand_num, i, index)) {
            rand_num[i++] = index;
        }
    }
    for(int i = 0; i < K ; i++) {
        for(int j = 0; j < C; j++) {
            cluster[j][i] = dat[rand_num[j]].p[i];
        }
    }
}
double Eulid_dis(int x, int y) {
    double distance = 0.0;
    for(int i = 0 ; i < K ; i++) {
        distance += pow(dat[x].p[i] - cluster[y][i], 2);
    }
    distance = sqrt(distance);
    return distance;
}
void Make_new_cluster()
{
    double bias = 0.0;
    for(int i = 0; i < N; i++) {
        double mindis = dat[i].dis[0];
        dat[i].Lable = 0;
        for(int j = 1; j < C; j++) {
            if(mindis > dat[i].dis[j]) {
                mindis = dat[i].dis[j];
                dat[i].Lable = j;
            }
        }
    }
    for(int i = 0; i < N; i++) {
        bias += dat[i].dis[dat[i].Lable];
    }
     
    oldfitness = fitness;
    fitness = bias;
}
void calculate_distance()
{
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < C; j++) {
            dat[i].dis[j] = Eulid_dis(i, j);
        }
    }
}
void Make_new_center()
{
    for(int i = 0; i < C; i++) {
        for(int k = 0; k < K; k++) {
            double tmp = 0.0;
            int total = 0;
            for(int j = 0; j < N; j++) {
                if(dat[j].Lable == i) {
                    tmp += dat[j].p[k];
                    total++;
                }
            }
            if(total > 0) {
                cluster[i][k] = tmp/total;
            }
        }
    }
}
/************************************
*              主函数               *
************************************/
int main()
{
    input_data();
    Init_center();
    int i = 0;
    double differ = 1.0;
    while(i < IterMax && differ > IterTherhold) {
        calculate_distance();
        Make_new_cluster();
        Make_new_center();
        differ = abs(oldfitness - fitness);
        cout << fitness << endl;
        i++;
    }
    for (int i = 0; i < C; ++i) {
        for(int j = 0; j < K ; j++) {
            cout << cluster[i][j] << "\t";
        }
        cout << endl;
    }
    return 0;
}

  

posted @   bitgirl_coder  阅读(194)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
点击右上角即可分享
微信分享提示