整个框架分为kmeans类,和主函数
主函数如下:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kmeans.h"
using namespace std;
int main(int argc, char ** argv)
{
kmeans t;
t.readfile("textV1.txt");
t.calKmeans();
t.saveC();
t.display(argc, argv);
return 0;
}
kmeans类 其中data表示的是样本数据,c表示的是对应样本数据的类别
kmeans.h 如下
#ifndef KMEANS_H
#define KMEANS_H
#include <iostream>
using namespace std;
class kmeans
{
public:
kmeans();
int readfile(string s);
void calKmeans(int len = 1000);
void saveC();
void display(int argc, char **argv);
private:
int data[1000][2];
int c[1000];
};
#endif // KMEANS_H
kmeans.cpp如下
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include <ctime>
#include <cstdlib>
#include "kmeans.h"
using namespace std;
int random(int start, int end)
{
return start + rand()%(end-start);
}
void print(int data[][2], int len)
{
for(int j=0; j<len; j++){
cout << data[j][0] << " " << data[j][1] << endl;
}
}
double norm(int *p1, int *p2)
{
return sqrt(pow(fabs(p1[0] - p2[0]), 2) + pow(fabs(p1[1] - p2[1]),2));
}
double norm2(double *p1, int *p2)
{
return sqrt(pow(fabs(p1[0] - p2[0]), 2) + pow(fabs(p1[1] - p2[1]),2));
}
int min(double *dis, int len)
{
int index = 0;
double min = 1e99;
for(int i=0; i<len; i++){
if(min > dis[i]){
min = dis[i];
index = i;
}
}
return index;
}
double maxValue(double *dis, int len)
{
double max = 0;
for(int i=0; i<len; i++){
if(max < dis[i]){
max = dis[i];
}
}
return max;
}
kmeans::kmeans()
{
for(int i=0; i<1000; i++){
for(int j=0; j<2; j++){
data[i][j] =0;
}
c[i] = 0;
}
}
int kmeans::readfile(string s)
{
FILE *fp = NULL;
if(!(fp = fopen(s.c_str(), "r"))){
cout << "open error \n";
}
int x,y;
int i=0;
int ret = fscanf(fp, "%d,%d", &x, &y);
while(!feof(fp)){
if(ret == EOF) cout << "error\n";
data[i][0] = x;
data[i][1] = y;
ret = fscanf(fp, "%d,%d", &x, &y);
i++;
}
fclose(fp);
return 0;
}
void kmeans::calKmeans(int len)
{
int iter=0;
int N = 5;
int u[N][2] = {0};
for(int i=0; i<N; i++)
for(int j =0; j<2; j++)
u[i][j] = random(1, 100);
while(iter < 100){
// classify the differnt classes
for(int i=0; i<len; i++){
double dis[N] = {0};
for(int j =0; j<N; j++){
dis[j] = norm(data[i], u[j]);
}
c[i] = min(dis, 5);
}
// define new center
double sum[N][2] = {0};
int num[N] = {0};
for(int i=0; i<len; i++){
for(int j=0; j<N; j++){
if(c[i] == j){
sum[j][0] += data[i][0];
sum[j][1] += data[i][1];
num[j]++;
}
}
}
double ut[N][2] = {0};
for(int i=0; i<N; i++){
ut[i][0] = 1.0*sum[i][0]/num[i];
ut[i][1] = 1.0*sum[i][1]/num[i];
}
// stop condition
double udis[N] = {0};
for(int i=0; i<N; i++){
udis[i] = norm2(ut[i], u[i]);
}
if(maxValue(udis, N) < 1e-10){
break;
}
for(int i=0; i<N; i++)
for(int j=0; j<2; j++){
u[i][j] = ut[i][j];
}
iter++;
}
}
void kmeans::saveC()
{
FILE *fp = NULL;
if(!(fp = fopen("classes.txt", "w"))){
cout << "open error \n";
}
int index = 0;
while(index < 1000){
fprintf(fp, "%d\n", c[index]);
index ++;
}
fclose(fp);
}
void init()
{
glClearColor(1,1,1,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-50, 150, -50, 150);
}
void lineSegment(void)
{
//将窗口颜色的设置显示到窗口上,参数是颜色缓存的位值
glClear(GL_COLOR_BUFFER_BIT);
//设置显示内容颜色
//绘制内容
// glBegin(GL_LINES);
// glVertex2i(180, 15);
// glVertex2i(10, 145);
// glEnd();
FILE *fp1 = NULL, *fp2 = NULL;
int c[1000] = {0};
int data[1000][2] = {0};
if(!(fp1 = fopen("textV1.txt", "r"))){
cout << "error textV1.txt \n";
}
if(!(fp2 = fopen("classes.txt", "r"))){
cout << "error classes.txt \n";
}
int x,y,z;
int index = 0;
int ret = fscanf(fp1, "%d,%d", &x, &y);
while(!feof(fp1)){
if(ret == EOF) cout << " fscanf error\n";
data[index][0] = x;
data[index][1] = y;
ret = fscanf(fp1, "%d,%d", &x, &y);
index++;
}
index =0;
ret = fscanf(fp2, "%d", &z);
while(!feof(fp2)){
if(ret == EOF) cout << "fscanf error\n";
c[index++] = z;
ret = fscanf(fp2, "%d", &z);
}
glPointSize(3);
glBegin(GL_POINTS);
for(int i=0; i<1000; i++){
switch (c[i]) {
case 0:
glColor3f(1.0, 0.0, 0.0);
glVertex2i(data[i][0], data[i][1]);
break;
case 1:
glColor3f(0.0, 1.0, 0.0);
glVertex2i(data[i][0], data[i][1]);
break;
case 2:
glColor3f(0.0, 0.0, 1.0);
glVertex2i(data[i][0], data[i][1]);
break;
case 3:
glColor3f(1.0, 1.0, 0.0);
glVertex2i(data[i][0], data[i][1]);
break;
case 4:
glColor3f(1.0, 0.0, 1.0);
glVertex2i(data[i][0], data[i][1]);
break;
case 5:
glColor3f(0.0, 1.0, 1.0);
glVertex2i(data[i][0], data[i][1]);
break;
default:
break;
}
}
glEnd();
glFlush();
}
void kmeans::display(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50,100);
glutInitWindowSize(800, 600);
glutCreateWindow("Test Opengl Program");
init();
glutDisplayFunc(lineSegment);
glutMainLoop();
}