📄 unit1.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 + -