unit1.cpp
来自「此程序采用K均值的方法对样本数据进行模式分类」· C++ 代码 · 共 302 行
CPP
302 行
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void TForm1::InitClusters()
{
/*ClusterMember[0][0]=0;
ClusterMember[0][0]=50;
ClusterMember[0][0]=100;
for(int j=0;j<4;j++)
{
ClusterCenter[0][j]=Pattern[0][j];
ClusterCenter[1][j]=Pattern[50][j];
ClusterCenter[2][j]=Pattern[100][j];
} */
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;
}
}
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]++;
}
}
//重新计算各分类中心
int TForm1::CalcNewClustCenters()
{
int ConvFlag,PatternID,i,j,k;
double Tmp[4];
ConvFlag=1;
for(i=0;i<3;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)
{
SpeedButton2->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;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
ListView1->Items->Clear();//列表框清空
ListView2->Items->Clear();
ListView3->Items->Clear();
ListView4->Items->Clear();
Label1->Caption="共计 0 个样本";
Label2->Caption="共计 0 个样本";
Label3->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=ListView1->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);
}
}
/* //用加权系数调整样本各维(特征)数据大小
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]*10.0;
Pattern[j][2]=Pattern[j][2]*10.0;
} */
/* //样本各维(特征)数据标准化
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];
} */
ListView1->Visible=true;
SpeedButton2->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
Screen->Cursor=crHourGlass;
//清空上次分类结果
ListView2->Items->Clear();
ListView3->Items->Clear();
ListView4->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();
}
// 显示分类后各类样本数量
Label1->Caption="共计"+IntToStr(ClusterNumMembers[0])+"个样本";
Label2->Caption="共计"+IntToStr(ClusterNumMembers[1])+"个样本";
Label3->Caption="共计"+IntToStr(ClusterNumMembers[2])+"个样本";
//显示第一类中心
TListItem *p;
p=ListView2->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=ListView2->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=ListView3->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=ListView3->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=ListView4->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=ListView4->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::SpeedButton3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?