C++ kmeans 同时绘图opengl

整个框架分为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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值