⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.cpp

📁 模式识别中的聚类k均值算法用C++ builder编码实现是cpp文件
💻 CPP
字号:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  TListItem  *ListItem;
}
//---------------------------------------------------------------------------

void TForm1::InitClusters()
{
  int i,j;
  for(i=0;i<3;i++)
  {
    ClusterMember[i][0]=i;
    for(j=0;j<4;j++)
      ClusterCenter[i][j]=Pattern[i][j];
  }
}
//欧式范数计算
double TForm1::EucNorm(int p,int c)
{
   double dist;
   int i;
   dist=0;
   for(i=0;i<4;i++)
       dist+=(Pattern[p][i]-ClusterCenter[c][i])*(Pattern[p][i]-ClusterCenter[c][i]);
   return dist;
}
//求离样本最近的聚类中心
 int TForm1::FindClosestCluster(int pat)
{
   int i,ClustID;
   double MinDist,d;
   MinDist=9.9e+99;//
   ClustID=-1;
   for(i=0;i<3;i++)
   {
     d=EucNorm(pat,i);
     if(d<MinDist)
     {
       MinDist=d;
       ClustID=i;//这里的i是初始聚类中心的序号
     }
   }
   return ClustID;
}
//样本分类
 void TForm1::DistributeSamples()
 {
    int i,pat,Clustid,MemberIndex;
    for(i=0;i<3;i++)
    ClusterNumMembers[i]=0; //分类后各样本个数
    for(pat=0;pat<150;pat++)
    {
      Clustid=FindClosestCluster(pat);
      MemberIndex=ClusterNumMembers[Clustid]; //和下面的有联系的
      ClusterMember[Clustid][MemberIndex]=pat;//样品序号
      ClusterNumMembers[Clustid]++;//第Clustid类的样品个数
    }
  }
//重新计算各分类(聚类)中心
  int TForm1::CalcNewClustCenters()
  {
     int ConvFlag,PatternID,i,j,k;
     double Tmp[4];
     ConvFlag=1;
     for(i=0;i<3;i++) //这里i的取值是指三个聚类
     {
       for(j=0;j<4;j++)
         Tmp[j]=0.0;

       for(j=0;j<ClusterNumMembers[i];j++)
       {
         PatternID=ClusterMember[i][j];
         for(k=0;k<4;k++)
           Tmp[k]+=Pattern[PatternID][k];//这里有四个特征矢量,分别计算其和
        }

        for(j=0;j<4;j++)
        {
          Tmp[j]=Tmp[j]/ClusterNumMembers[i];
          if(Tmp[j]!=ClusterCenter[i][j])
          {
            ConvFlag=0;
            ClusterCenter[i][j]=Tmp[j];
          }
        }
     }
      return ConvFlag;
  }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  btn3->Enabled=false;
  for(int i=0;i<150;i++)
      for(int j=0;j<4;j++)
         Pattern[i][j]=0;
  //设置载入文件初始目录
  String InitDir=GetCurrentDir();
  OpenDialog1->InitialDir=InitDir;
  rb1->Checked=true;;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn1Click(TObject *Sender)
{
  lvClassOne->Items->Clear();//列表框清空
  lvClassTwo->Items->Clear();
  lvClassThree->Items->Clear();
  lvDate->Items->Clear();

  lbl1->Caption="共计  0  个样本";
  lbl2->Caption="共计  0  个样本";
  lbl3->Caption="共计  0  个样本";

  StatusBar1->Panels->Items[0]->Text="分类迭代次数:0 次";

  int SampleSN=0;//模式样本序号
  //ListView1->Visible=false;
  int iFileHandle,iFileLength,iBytesRead;
  char *PatternBuffer;
  if(OpenDialog1->Execute())
  {
    try
    {
      iFileHandle=FileOpen(OpenDialog1->FileName,fmOpenRead);
      iFileLength=FileSeek(iFileHandle,0,2);
      FileSeek(iFileHandle,0,0);
      PatternBuffer=new char[iFileLength+1];
      iBytesRead=FileRead(iFileHandle,PatternBuffer,iFileLength);
      FileClose(iFileHandle);
      bool ReadFlag=false;  //数据加入与否标志
      AnsiString EData="";  //读入有效数据
      TListItem *p;
      int DataDim=0;  //样本的维
      for(int i=0;i<iBytesRead;i++)
      {
         if((PatternBuffer[i]>='0'&&PatternBuffer[i]<='9')||PatternBuffer[i]=='.')
            {ReadFlag=true;EData+=PatternBuffer[i];}
         else
            {
              if(ReadFlag)
                 {
                   if(DataDim==0)
                   {
                     p=lvDate->Items->Add();
                     p->Caption=EData;
                   }
                   else{
                        p->SubItems->Add(EData);
                        Pattern[SampleSN][DataDim-1]=atof(EData.c_str());
                        }
                   EData="";
                   ReadFlag=false;
                   DataDim++;
                   if(DataDim==5)
                   {
                     DataDim=0;
                     SampleSN++;
                   }
                   
                 }
            }
      }
delete[] PatternBuffer;
    }
    catch(...)
    {
      Application->MessageBox("不能进行以下文件操作:打开、寻找、读取和关闭。", "File Error", IDOK);
    }
  }

if(rb2->Checked)
{
    for(int j=0;j<150;j++)
    {
      Pattern[j][0]=Pattern[j][0]*1.0;
      Pattern[j][1]=Pattern[j][1]*1.0;
      Pattern[j][2]=Pattern[j][2]*3.0;
      Pattern[j][2]=Pattern[j][2]*20.0;
    }
}
//样本各维(特征)数据标准化------------------------------------------------------
if(rb3->Checked)
{
  double sum[4];
  for(int i=0;i<4;i++)
  {
    sum[i]=0.0;
    for(int j=0;j<150;j++)sum[i]+=Pattern[j][i];
    sum[i]=sum[i]/150.0;
    for(int k=0;k<150;k++)Pattern[k][i]=Pattern[k][i]/ sum[i];
  }
}
  
 lvDate->Visible=true;
 btn3->Enabled=true;

}
//---------------------------------------------------------------------------

void __fastcall TForm1::btn3Click(TObject *Sender)
{
  Screen->Cursor=crHourGlass;

  //清空上次分类结果
  lvClassOne->Items->Clear();
  lvClassTwo->Items->Clear();
  lvClassThree->Items->Clear();
  InitClusters(); //初始化
  //K-Means方法计算
  int Converged; //收敛标志
  int IterNum;  //分类迭代次数
  IterNum=1;
  Converged=0;
  while(Converged==0)
  {
    IterNum++;
    StatusBar1->Panels->Items[0]->Text="分类迭代次数:"+IntToStr(IterNum)+"次";
    DistributeSamples();
    Converged=CalcNewClustCenters();
   }
  // 显示分类后各类样本数量
  lbl1->Caption="共计"+IntToStr(ClusterNumMembers[0])+"个样本";
  lbl2->Caption="共计"+IntToStr(ClusterNumMembers[1])+"个样本";
  lbl3->Caption="共计"+IntToStr(ClusterNumMembers[2])+"个样本";

  //显示第一类中心
  TListItem *p;
  p=lvClassOne->Items->Add();
  p->Caption="中心";
  for(int k=0;k<4;k++)
    p->SubItems->Add(String(int(ClusterCenter[0][k]*10)/10.0));
  //显示第一类各样本数据
  for(int i=0;i<ClusterNumMembers[0];i++)
  {
   p=lvClassOne->Items->Add();
   p->Caption=String(ClusterMember[0][i]+1);
   for(int k=0;k<4;k++)
      p->SubItems->Add(String(Pattern[(ClusterMember[0][i])][k]));
   }
  // 显示第二类中心
  p=lvClassTwo->Items->Add();
  p->Caption="中心";
  for(int k=0;k<4;k++)
    p->SubItems->Add(String(int(ClusterCenter[1][k]*10)/10.0));
  //  显示第二类各样本数据
  for(int i=0;i<ClusterNumMembers[1];i++)
  {
   p=lvClassTwo->Items->Add();
   p->Caption=String(ClusterMember[1][i]+1);
   for(int k=0;k<4;k++)
      p->SubItems->Add(String(Pattern[(ClusterMember[1][i])][k]));
   }
  //显示第三类中心
  p=lvClassThree->Items->Add();
  p->Caption="中心";
  for(int k=0;k<4;k++)
    p->SubItems->Add(String(int(ClusterCenter[2][k]*10)/10.0));
  //显示第三类各样本数据
  for(int i=0;i<ClusterNumMembers[2];i++)
  {
   p=lvClassThree->Items->Add();
   p->Caption=String(ClusterMember[2][i]+1);
   for(int k=0;k<4;k++)
      p->SubItems->Add(String(Pattern[(ClusterMember[2][i])][k]));
   }
   Screen->Cursor=crDefault;        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btn2Click(TObject *Sender)
{
  Close();         
}
//---------------------------------------------------------------------------


void __fastcall TForm1::btn4Click(TObject *Sender)
{

   ///////////////////////////////////
 
   TForm2* form2=new TForm2(this);
   form2->ShowModal();;
   delete form2;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -