原创 模糊K均值算法的C++实现

2008-11-1 14:50 4641 7 8 分类: MCU/ 嵌入式
//****************************************************************************//
//文件名:kaverage.cpp                                                        //
//说明:模式识别模糊k均值算法实现方法程序                                     //
//原创:SkyCode@126.com                                                       //
//日期:2008.10.29                                                            //
//****************************************************************************//
//****************************************************************************//


//*****************包含的头文件**********************//
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <math.h>
using namespace std;


//********************相关宏定义*********************//
#define MaxClass   20                              //定义最多的类别数
#define MaxSample  100                             //最多的样本数
#define e          0.3                           //评价误差

//类的定义
class System
{
private:       
    string str;   
    int    K;                                      //分类数
    int    num;                                    //样本个数
    int    T_loop;                                 //记录迭代次数
    float  K_Degree[MaxSample];                    //随机生成0-1个元素作为初始化模糊分类矩阵用          
    float  Point_sample[MaxSample];                //样本点
    float  U_Matrix_Copy[MaxClass][MaxSample];     //拷贝模糊矩阵
    float  U_Matrix[MaxClass][MaxSample];          //模糊分类矩阵    
    int    a_sample_num,b_sample_num;              //记录两类样本个数
    float  class_Num[MaxClass];                    //聚类中心名Wi
    float  class_Num_Olddata[MaxClass];             //前一次的聚类中心名Wi
public:   
    System();
    bool LoadSamples();                            //load样本
    void CreatRandomArray();                       //产生随机数列函数产生个数等于输入样本的个数
    void CreatClassifyMatrix();                    //生成分类矩阵函数
    void InitClusterCentre();                       //初始化聚类中心
    void UpdataClusterMatrix();                       //更新模糊分类矩阵
    void UpdataClusterCenter();                    //更新聚类中心
    void CompareTheDifference();                   //比较误差函数
    void PrintDividedResult();                     //打印结果
};

//*****************************************************************//
//*函数名:       System ()                                       *//
//*类型:         公有                                            *//
//*功能描述:     构造函数初始化部分私有成员数据                  *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
System::System(void)
{   
    K = 0;
    num = 0;
    T_loop = 1;
    a_sample_num = 0;
    b_sample_num = 0;
}

//*****************************************************************//
//*函数名:       LoadSamples()                                   *//
//*类型:         公有                                            *//
//*功能描述:     读取样本序列函数                                *//
//*参数:          无                                             *//
//*返回值:       void                                            *//
//*****************************************************************//
bool System::LoadSamples(void)
{
    int j;
    int K_var;   
    char *Symbol_File = new char[20];
    cout << "输入样本文件:";
    cin >> Symbol_File;
    ifstream File_In;
    File_In.open(Symbol_File);
    if(File_In.is_open() == false)
    {
        cout << "读取样本文件失败" << endl;
    }
    else
        cout << "读取样本文件成功" << endl;
    while(File_In)
    {
        getline(File_In,str);
        cout << str << endl;
        num ++;
    }
    num = num - 1;
    cout << "样本个数:" << num << "\t";   
    ifstream in(Symbol_File);
    for(j=0; j<num; j++)
    {   
            in >> Point_sample[j];
    }
    File_In.close();
    in.close();
    cout << endl;
    for(j=0; j<num; j++)
    {   
        cout << Point_sample[j] << endl;
    }
    cout<<"请输入K值(K不大于"<<num<<"):";
    cin>> K_var;
    K = K_var;
    if(K > num)
    {
        cout << "!!!invalid data" << endl;
        delete [] Symbol_File;
        return false;
    }
   
    else
    {
        delete [] Symbol_File;
        return true;
    }
}

//*****************************************************************//
//*函数名:       CreatRandomArray()                              *//
//*类型:         公有                                            *//
//*功能描述:     产生随机数列                                    *//
//*参数:                                                         *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::CreatRandomArray(void)
{
    int  *RandomArray = new int[num];
    float *K_Degree_temp = new float[num];
    srand( (unsigned)time( NULL ) );   
    for( int a = 0; a < num; a++ )
    {
        RandomArray[a] = rand();
        K_Degree_temp[a] = (float)RandomArray[a]/32768;
        K_Degree[a] = K_Degree_temp[a];
         cout << K_Degree_temp[a] << endl;   
    }
    delete []  RandomArray;
    delete []  K_Degree_temp;
}

//*****************************************************************//
//*函数名:       CreatClassifyMatrix()                           *//
//*类型:         公有                                            *//
//*功能描述:     产生分类矩阵  U                                 *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::CreatClassifyMatrix(void)
{

    int H_row,V_vert;
    for (H_row = 0; H_row < K; H_row ++)
    {
        for (V_vert = 0; V_vert < num; V_vert ++)
        {
            U_Matrix[H_row][V_vert] = 0;
        }
    }

    for (H_row = 1; H_row < K; H_row ++)
    {
        U_Matrix[H_row][H_row] = K_Degree[H_row];
        U_Matrix[H_row-1][H_row] = 1 - K_Degree[H_row];
    }
    U_Matrix[0][0] = K_Degree[0];
    U_Matrix[1][0] = 1 - K_Degree[0];
    for (H_row = (K); H_row < num; H_row ++)
    {
        U_Matrix[0][H_row] = K_Degree[H_row];
        U_Matrix[1][H_row] = 1 - K_Degree[H_row];
    }

    cout << "随机模糊矩阵生成" << endl;
    for (H_row = 0; H_row < K; H_row ++)
    {
        for (V_vert = 0; V_vert < num; V_vert ++)
        {
        cout << "RandomMatrix    " << U_Matrix[H_row][V_vert] << endl;
        }
       
    }
}

//*****************************************************************//
//*函数名:       InitClusterCentre()                             *//
//*类型:         公有                                            *//
//*功能描述:     初始化聚类中心  Wi                              *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::InitClusterCentre(void)
{
    int i,j,s;
    float *class_Num_m = new float[K];
    float *class_Num_d = new float[K];   
    for (s = 0; s < K; s ++)
    {
        class_Num_d =0;
        class_Num_m =0;
    }
    cout << "初始化聚类中心" << endl;
    for (j = 0; j < K; j ++)
    {
        for (i = 0; i < num; i ++)
        {
            class_Num_m[j] += (U_Matrix[j] * U_Matrix[j] * Point_sample);
            class_Num_d[j] += (U_Matrix[j]*U_Matrix[j]);
        }
        class_Num[j] = class_Num_m[j] / class_Num_d[j];
      cout << "InitCenter    " << class_Num[j] << endl;
    }   
    delete [] class_Num_m;
    delete [] class_Num_d;
}

//*****************************************************************//
//*函数名:       UpdataClusterMatrix()                           *//
//*类型:         公有                                            *//
//*功能描述:     更新模糊矩阵                                    *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::UpdataClusterMatrix(void)
{
    float *U_Matrixtemp = new float[num];
    int i,j;
    for (i = 0 ; i < num; i ++)
    {
        U_Matrixtemp = 0;
    }

    for (i = 0; i < num; i++)
    {
        for (j = 0; j < K; j ++)
        {
            U_Matrixtemp += (1/((Point_sample - class_Num[j])*(Point_sample - class_Num[j])));   
        }
                                       
    }       
    cout << "更新的模糊矩阵" <<endl;
    for (i = 0; i < K; i ++)
    {
        for (j = 0; j < num; j ++)
        {   
            U_Matrix[j] = ((Point_sample[j] - class_Num)*(Point_sample[j] - class_Num));
            U_Matrix[j] = 1/(U_Matrixtemp[j] * U_Matrix[j]);
            cout << "UpdataMatrix    " << U_Matrix[j] << endl;
        }
    }
    delete []  U_Matrixtemp;
}

//*****************************************************************//
//*函数名:       UpdataClusterCenter()                           *//
//*类型:         公有                                            *//
//*功能描述:     更新聚类中心值                                  *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::UpdataClusterCenter(void)
{
    int i,j,s;
    float *class_Num_m = new float[K];
    float *class_Num_d = new float[K];   
    for (s = 0; s < K; s ++)
    {
        class_Num_d =0;
        class_Num_m =0;
    }
    cout << "更新聚类中心" <<endl;
    for (j = 0; j < K; j ++)
    {
        for (i = 0; i < num; i ++)
        {
            class_Num_m[j] += (U_Matrix[j] * U_Matrix[j] * Point_sample);
            class_Num_d[j] += (U_Matrix[j]*U_Matrix[j]);
        }
        class_Num[j] = class_Num_m[j] / class_Num_d[j];
        cout << "UpdataCenter    " << class_Num[j] << endl;
    }   
    delete [] class_Num_m;
    delete [] class_Num_d;   
}

//*****************************************************************//
//*函数名:       CompareTheDifference()                           *//
//*类型:         公有                                            *//
//*功能描述:     比较误差函数                                    *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::CompareTheDifference(void)
{
    bool flag = true;
    float E;
    while (flag)
    {
        for (int i = 0; i < num; i ++)
        {
            class_Num_Olddata = class_Num;
        }
        UpdataClusterMatrix();
        UpdataClusterCenter();
        T_loop ++;
        float a ,b;
        a = fabs(class_Num_Olddata[0] - class_Num[0]);
        b = fabs(class_Num_Olddata[1] - class_Num[1]);
        cout<< "success  " << a << "    " << b <<endl;
        E = a>b?a:b;
        if ( E< e )
        {
            flag = false;
            PrintDividedResult();
            cout << "E  " << E << endl;
            cout << "迭代次数:" << "   " << T_loop <<endl;
        }
    }   
}

//*****************************************************************//
//*函数名:       PrintDividedResult()                            *//
//*类型:         公有                                            *//
//*功能描述:     打印最终的分类结果                              *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void System::PrintDividedResult(void)
{
    cout << "第一类样本有:" << endl;
    for (int i = 0; i < num; i ++)
    {   
        if (U_Matrix[0] > U_Matrix[1])
        {
            a_sample_num ++;           
            cout << "   sample" << i << ":  " << Point_sample << endl;
        }
    }
    cout << "共有" << a_sample_num <<"个样本" <<endl;
    cout << endl;

    cout << "第二类样本有:" << endl;
    for (int j = 0; j < num; j ++)
    {   
        if (U_Matrix[0][j] < U_Matrix[1][j])
        {
            b_sample_num ++;           
            cout << "   sample" << j << ":  " << Point_sample[j] << endl;
        }
    }
    cout << "共有" << b_sample_num <<"个样本" <<endl;
    cout << endl;
       
}


//声明对象kmeans
System kmeans;                                     

//*****************************************************************//
//*函数名:       main()                                          *//
//*功能描述:     主函数                                          *//
//*参数:         无                                              *//
//*返回值:       void                                            *//
//*****************************************************************//
void main(void)
{   
    if (kmeans.LoadSamples() == true)
    {
        kmeans.CreatRandomArray();
        kmeans.CreatClassifyMatrix();       
        kmeans.InitClusterCentre();
        kmeans.CompareTheDifference();                       
    }   
}https://static.assets-stash.eet-china.com/album/old-resources/2008/11/1/64ccf7c1-649b-4ab4-96d8-dcfa6908673d.rarhttps://static.assets-stash.eet-china.com/album/old-resources/2008/11/1/8e7b881e-834a-470a-83ed-ddb4c97a346d.rar

文章评论1条评论)

登录后参与讨论

用户305805 2010-10-14 14:53

请问如何导入数据呀?
相关推荐阅读
用户165162 2010-10-15 23:43
CANopen简介
CANopen简介    CANopen协议集定义了基于CAN的分布式工业自动化系统的应用标准以及CAN应用层通信标准。CANopen是CAN-in-Automation(CiA)定义的标准之一,并且...
用户165162 2009-03-04 22:34
TServerSocket和TClientSocket地运用(转载)
在网络编程中,WinSocket API编程是最基本,也是最麻烦的地方(说句不怕影响形象的话,我对此就是一知半解)。但是,如果你是使用C++Builder作为编程平台,你就偷着乐吧,有了BCB,菜鸟变...
用户165162 2008-11-09 11:40
奥巴马就职演讲
Hello, Chicago!   芝加哥,你好!If there is anyone out there who still doubts that America is a place where...
用户165162 2008-11-02 12:43
STM32 RTC 对晶振的要求实在不地道
zhwxc 发表于 2008-8-19 18:00 ST MCU ←返回版面 楼主: STM32 RTC 对晶振的要求实在不地道今天到电子市场找了一下,几乎都是12.5p负载电容的32768晶...
用户165162 2008-10-20 17:50
10种软件滤波方法的示例程序[转帖]
1、限副滤波 /* A值可根据实际情况调整 value为有效值,new_value为当前采样值 滤波程序返回有效的实际值 */ #define A 10 char value; char filter...
我要评论
1
7
关闭 站长推荐上一条 /2 下一条