?? algorithm.cpp
字號:
// Algorithm.cpp: implementation of the CAlgorithm class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Algorithm.h"
#include "iostream.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAlgorithm::CAlgorithm()
{
srand(time(NULL));
}
CAlgorithm::~CAlgorithm()
{
}
int CAlgorithm::Step1()//參數設置、模式輸入、隨機產生初始分類
{
// ParaSet();
// PatternInput();
int i;
for(i=1;i<=Nc;i++)
{
AddNullCluster();
AddPatToClus(SelectPattern(Random(UnClusPatNum)),GetClusPointer(i));
}
for(i=1;i<=ClusNum;i++)
CalClusCent(GetClusPointer(i));
return 0;
}
int CAlgorithm::Step2()//根據模式與每個類之間的距離,將其加入距離最小的一個類
{
int minpos;
double temp1=0,temp2=10000000;
PATTERN_S *p;
//計算模式與每個類之間的距離,將其加入距離最小的一個類
while (UnClusPatNum!=0)
{
minpos=1;
temp1=0;
temp2=10000000;
p=SelectPattern(1);
for(int i=1;i<=ClusNum;i++)
{
temp1=CalPatClusCentDis(p,GetClusPointer(i));
if(temp2>temp1)
{
temp2=temp1;
minpos=i;
}
}
AddPatToClus(p,GetClusPointer(minpos));
}
return 0;
}
int CAlgorithm::Step3()//如果類太小,合并并返回第二步
{
int i;
int del=0;
int temp=ClusNum;
for(i=1;i<=temp;i++)
{
if(GetClusPointer(i)==NULL)
break;
if(CountPattern(GetClusPointer(i)->pPat)<Thn)
{
DeleteCluster(i);
del=1;
}
}
if(del==0)
return 0;
else
return 2;
}
int CAlgorithm::Step4()//計算類心、模式類心平均距離
{
int i;
for(i=1;i<=ClusNum;i++)
{
CalClusCent(GetClusPointer(i));
CalPatCentMeanDis(GetClusPointer(i));
}
CalTotalMeanDis();
return 0;
}
int CAlgorithm::Step5()//根據類的數量判斷是交分裂處理還是交給合并處理
{
if(Ip==I)
{
ThD=0;
return 9;
}
if(ClusNum<=c/2)
return 6;
if(ClusNum>=2*c)
return 9;
if((ClusNum>c/2)&&(ClusNum<2*c))
{
if((int)c%2==0)return 9;
if((int)c%2==1)return 6;
}
return 0;
}
int CAlgorithm::Step6_7()//計算類內距離的標準差矢量的最大值
{
int i;
for(i=1;i<=ClusNum;i++)
{
CalClusMaxBiaozhuncha(GetClusPointer(i));//計算類內距離的標準差矢量的最大值
}
return 0;
}
int CAlgorithm::Step8()//根據類內距離的標準差矢量的最大值判斷是否分裂并分裂
{
CLUSTER_S *pTemp;
int i;
int sepornot=0;
for(i=1;i<=ClusNum;i++)
{
pTemp=GetClusPointer(i);
if(pTemp->MaxBiaozhuncha>Ths&&((pTemp->PatCentMeanDis>TotalMeanDis&&CountPattern(pTemp->pPat)>2*(Thn+1))||ClusNum<=c/2))
{
SeperateCluster(pTemp);
sepornot=1;
}
}
if(sepornot==1)
{
Ip++;
return 2;
}
return 0;
}
int CAlgorithm::Step9_10()//根據類心間距離判斷是否合并并合并
{
int i,j;
int time=0;
double temp1,temp2;
int pos1=0,pos2=0;
do
{
temp1=0;
temp2=9999999999;
for(i=1;i<ClusNum;i++)
for(j=i+1;j<=ClusNum;j++)
{
if(GetClusPointer(i)->CombineOrNot==0&&GetClusPointer(j)->CombineOrNot==0)
{
temp1=CalClusCentDis(i,j);
if(temp1<temp2)
{
temp2=temp1;
pos1=i;
pos2=j;
}
}
}
if(temp2<ThD)
{
CombineCluster(pos1,pos2);
time++;
}
}
while(temp2<ThD&&time<L);
for(i=1;i<=ClusNum;i++)
GetClusPointer(i)->CombineOrNot=0;
return 0;
}
int CAlgorithm::Step11()//判斷是否繼續迭代或結束
{
if(Ip==I)
return 0;
else
{
Ip++;
return 2;
}
}
int CAlgorithm::ParaSet()
{
c=4;//預期的類數
Nc=10;//初始聚類中心個數
Thn=3;//每一類中允許的最小模式數目
Ths=10;//類內各個分量分布的標準差上限
ThD=10;//兩類中心之間的最小距離下限
L=2;//在每次迭代中可以合并的類的最多對數
I=4;//允許的最多迭代次數
k=0.5;//類分裂時用的系數k
PatNum=20;//設定模式的個數
PatDim=2;//設定模式的維數
UnClusPatNum=0;
ClusNum=0;
Ip=0;//實際迭代的次數
pPattern=NULL;
pCluster=NULL;
return 0;
}
int CAlgorithm::PatternInput()//讀入模式數據
{
PATTERN_S *pTemp;
PATTERN_S *pEnd;
int i,j;
cout<<"模式的個數為:"<<PatNum;
cout<<"模式的維數為:"<<PatDim<<endl;
cout<<"請輸入模式數據:"<<endl;
for(i=0;i<PatNum;i++)
{
pTemp=new PATTERN_S;
for(j=0;j<PatDim;j++)
{
if(j==0)
pTemp->pat=new double[PatDim];
cin>>pTemp->pat [j];
}
cout<<endl;
if(pPattern==NULL)
{
pPattern=pTemp;
pEnd=pTemp;
}
else
{
pEnd->pNext=pTemp;
}
pEnd=pTemp;
}
pEnd=pTemp;
pEnd->pNext =NULL;
UnClusPatNum=PatNum;
return 0;
}
int CAlgorithm::PatternOutput()////顯示模式數據
{
PATTERN_S *pTemp;
pTemp=pPattern;
int i;
while(pTemp!=NULL)
{
for(i=0;i<PatDim;i++)
{
cout<<pTemp->pat[i]<<" ";
}
cout<<endl;
pTemp=pTemp->pNext;
}
return 0;
}
int CAlgorithm::AddCluster(CLUSTER_S *p)//添加一個類節點
{
CLUSTER_S *pTemp;
if(p==NULL)
return 1;
if(pCluster==NULL)//在空鏈條加入
{
pCluster=p;
ClusNum++;
return 0;
}
else //在尾部加入
{
pTemp=pCluster;
while(pTemp->pNext!=NULL)
{
pTemp=pTemp->pNext;
}
pTemp->pNext=p;
ClusNum++;
return 0;
}
}
int CAlgorithm::DeleteCluster(int position)////刪除一個類
{
CLUSTER_S *pTemp;
CLUSTER_S *pDel;
pTemp=pCluster;
if(pTemp==NULL||position<1||position>ClusNum)
return 1;
if(position==1)//在鏈條頭刪除
{
pCluster=pCluster->pNext;
FreePatInClus(pTemp->pPat);
delete pTemp;
ClusNum--;
return 0;
}
else //在指定位置刪除
{
for(int i=1;i<position-1;i++)
pTemp=pTemp->pNext;
pDel=pTemp->pNext;
pTemp->pNext=pDel->pNext;
FreePatInClus(pDel->pPat);
delete pDel;
ClusNum--;
return 0;
}
}
int CAlgorithm::AddPatToClus(PATTERN_S *p,CLUSTER_S *c)
{
if(p==NULL||c==NULL)//輸入為空
return 1;
PATTERN_S *pTemp;
pTemp=c->pPat;
if(pTemp==NULL)//類中模式指針為空
{
c->pPat=p;
return 0;
}
while(pTemp->pNext!=NULL)
{
pTemp=pTemp->pNext;
}
pTemp->pNext=p;
return 0;
}
PATTERN_S* CAlgorithm::SelectPattern(int position)//根據位置參數返回模式結構指針
{
if(position<1||position>UnClusPatNum)
return NULL;
PATTERN_S *pTemp;
PATTERN_S *pSel;
pTemp=pPattern;
if(pTemp==NULL)
return NULL;
if(position==1)
{
pPattern=pPattern->pNext;
pTemp->pNext=NULL;
UnClusPatNum--;
return pTemp;
}
else
{
for(int i=1;i<position-1;i++)
pTemp=pTemp->pNext;
pSel=pTemp->pNext;
pTemp->pNext=pSel->pNext;
pSel->pNext=NULL;
UnClusPatNum--;
return pSel;
}
}
int CAlgorithm::CalClusCent(CLUSTER_S *c)//計算類中心
{
if(c==NULL)//空類
return 1;
double *pCenter;//臨時類心
double *pDelCent;
pCenter=new double[PatDim];
for(int i=0;i<PatDim;i++)
pCenter[i]=0;
PATTERN_S *pTemp;//臨時模式指針
pTemp=c->pPat;
int length=CountPattern(pTemp);//模式鏈長度
if(pTemp==NULL)//模式鏈為空
{
c->pCenter=NULL;
return 1;
}
//求類心
do
{
for(i=0;i<PatDim;i++)
{
pCenter[i]+=pTemp->pat[i];
}
pTemp=pTemp->pNext;
}
while(pTemp!=NULL);
for(i=0;i<PatDim;i++)
{
pCenter[i]=pCenter[i]/length;
}
pDelCent=c->pCenter;
c->pCenter=pCenter;
delete []pDelCent;
return 0;
}
int CAlgorithm::DisplayPattern(PATTERN_S *p)
{
PATTERN_S *pTemp;
pTemp=p;
int i;
if(pTemp==NULL)
{
cout<<"此模式為空"<<endl;
return 0;
}
while(pTemp!=NULL)
{
for(i=0;i<PatDim;i++)
{
cout<<pTemp->pat[i]<<" ";
}
cout<<endl;
pTemp=pTemp->pNext;
}
return 0;
}
int CAlgorithm::DisplayCluster(CLUSTER_S *c)
{
if(c==NULL)
{
cout<<"此類為空"<<endl;
return 0;
}
if(c->pCenter==NULL)
cout<<"類心為空"<<endl;
else
{
cout<<"類心是"<<" ";
for(int i=0;i<PatDim;i++)
{
cout<<c->pCenter[i]<<" ";
}
}
cout<<endl;
cout<<"是否在一個循環內被合并過"<<c->CombineOrNot<<endl;
cout<<"模式到類心的平均距離:"<<c->PatCentMeanDis<<endl;
cout<<"類內距離的標準差矢量最大值"<<c->MaxBiaozhuncha<<endl;
cout<<"類內距離的標準差矢量最大值位置"<<c->MaxBiaozhunchaPos<<endl;
PATTERN_S *pTemp;
pTemp=c->pPat;
cout<<"此類中模式信息:"<<endl;
DisplayPattern(pTemp);
cout<<endl;
return 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -