?? fence.cpp
字號:
//該函數實現對exemplar部分的訓練
/*
輸入參數:
prototype -- 指向prototype部分的指針
N -- prototype部分的結點個數
exemplar -- 指向exemplar部分指針的指針
M -- exemplar部分結點的個數
sample -- 輸入模式
L -- 輸入模式的維數
classnum -- 輸入模式屬于的類號
輸出參數:
經過更新以后exemplar部分的結點個數
*/
#include <math.h>
#include <iostream.h>
#include <assert.h>
#include <stdio.h>
#include "FuzzyNN.h"
#include "tools.h"
int fence(ProtoNode *prototype,int N,ExemNode **exemplar,int M,FuzzyNum *sample,int L,int classnum)
{
double rou; //結點大小指定參數限制
int *candidate; //用來標記每個exemplar結點是否滿足候選條件
candidate=new int[M+1];
mcheck(candidate);
int i,j,k;
for(i=1;i<=M;i++)
candidate[i]=0;
//cout<<"請輸入對exemplar結點大小進行限制的參數:"<<endl;
//cin>>rou;
rou=0.3;
//計算對當前輸入模式,哪個結點勝出
int pmark;
int emark;
//-計算s1,s2,...,sN,并求其最大值
double *s;
s=new double[N+1];
mcheck(s);
for(j=1;j<=N;j++)
{
s[j]=0;
for(i=1;i<=L;i++)
s[j]+=(coa(sample[i])-coa((prototype[j].w)[i]))*(coa(sample[i])-coa((prototype[j].w)[i]));
s[j]=s[j]/L;
s[j]=sqrt(s[j]);
s[j]=1-s[j];
}
double pmax; //s1,s2,...,sN中的最大值
int pindex; //最大值對應的下標
pmax=s[1];
pindex=1;
for(i=2;i<=N;i++)
if(s[i]>pmax)
{
pmax=s[i];
pindex=i;
}
//-如果*exemplar不為空的話,計算r1,r2,...,rM,并求其最大值
double emax=0; //r1,r2,...,rM中的最大值
int eindex=0; //最大值對應的下標
if((*exemplar)!=NULL)
{
double *r;
r=new double[M+1];
mcheck(r);
j=0;
ExemNode *p=*exemplar;
int flag;
while(p!=NULL)
{
j++;
r[j]=0;
flag=1;
for(i=1;i<=L;i++)
if(!((p->v)[i].w1<=sample[i].w1 && (p->v)[i].w2>=sample[i].w2))
flag=0;
if(flag)
{
for(i=1;i<=L;i++)
r[j]+=(sample[i].w1-(p->v)[i].w1)*(sample[i].w1-(p->v)[i].w1)+(sample[i].w2-(p->v)[i].w2)*(sample[i].w2-(p->v)[i].w2);
r[j]=r[j]/L;
r[j]=sqrt(r[j]);
r[j]=2-r[j];
}
p=p->next;
}
emax=r[1];
eindex=1;
for(i=2;i<=M;i++)
if(r[i]>emax)
{
emax=r[i];
eindex=i;
}
delete []r;
}
if((*exemplar)==NULL)
{
pmark=pindex;
emark=0;
}
else
{
if(pmax>emax)
{
pmark=pindex;
emark=0;
}
else
{
pmark=0;
emark=eindex;
}
}
ExemNode *p,*q;
k=0;
int flag;
p=*exemplar;
while(p!=NULL)
{
k++; //記錄exemplar結點當前的索引號
if(p->classnum==classnum)
{
ExemNode E;
E.classnum=classnum;
E.v=new FuzzyNum[L+1];
mcheck(E.v);
E.h=NULL;
E.next=NULL;
for(i=1;i<=L;i++)
{
if((p->v)[i].w1<sample[i].w1)
{
(E.v)[i].w1=(p->v)[i].w1;
(E.v)[i].a=(p->v)[i].a;
}
else
{
(E.v)[i].w1=sample[i].w1;
(E.v)[i].a=sample[i].a;
}
if((p->v)[i].w2>sample[i].w2)
{
(E.v)[i].w2=(p->v)[i].w2;
(E.v)[i].b=(p->v)[i].b;
}
else
{
(E.v)[i].w2=sample[i].w2;
(E.v)[i].b=sample[i].b;
}
}
flag=1;//假設E結點滿足候選條件
//檢查E結點是否和其他的結點重疊
q=*exemplar;
while(q!=NULL)
{
int *overlap;
overlap=new int[L+1];
mcheck(overlap);
int flag0=0; // 檢查是否出現零
for(i=1;i<=L;i++)
{
overlap[i]=0;
if((E.v)[i].w1<=(q->v)[i].w1 && (q->v)[i].w1<(E.v)[i].w2 && (E.v)[i].w2<=(q->v)[i].w2)overlap[i]=1;
if((q->v)[i].w1<=(E.v)[i].w1 && (E.v)[i].w1<(q->v)[i].w2 && (q->v)[i].w2<=(E.v)[i].w2)overlap[i]=2;
if((E.v)[i].w1<(q->v)[i].w1 && (q->v)[i].w1<=(q->v)[i].w2 && (q->v)[i].w2<(E.v)[i].w2)overlap[i]=3;
if((q->v)[i].w1<(E.v)[i].w1 && (E.v)[i].w1<=(E.v)[i].w2 && (E.v)[i].w2<(q->v)[i].w2)overlap[i]=4;
}
for(i=1;i<=L;i++)
if(overlap[i]==0)
{
flag0=1;
break;
}
if(!(q->classnum==E.classnum || sum(overlap,L)==3*L || sum(overlap,L)==4*L || flag0))flag=0;
assert(overlap);
delete []overlap;
q=q->next;
}
//檢查E結點的大小是否滿足要求
if(flag)
{
if(emark==0)
{
if(!(size(E,L)<=rou))flag=0;
}
else
{
q=*exemplar;
for(i=1;i<emark;i++)//這里將q移動到exemplar第emark個結點
q=q->next;
if(!(size(E,L)<=rou*size(*q,L)))flag=0;
}
q=*exemplar;
while(q!=NULL)
{
int *overlap;
overlap=new int[L+1];
mcheck(overlap);
for(i=1;i<=L;i++)
{
overlap[i]=0;
if((E.v)[i].w1<=(q->v)[i].w1 && (q->v)[i].w1<(E.v)[i].w2 && (E.v)[i].w2<=(q->v)[i].w2)overlap[i]=1;
if((q->v)[i].w1<=(E.v)[i].w1 && (E.v)[i].w1<(q->v)[i].w2 && (q->v)[i].w2<=(E.v)[i].w2)overlap[i]=2;
if((E.v)[i].w1<(q->v)[i].w1 && (q->v)[i].w1<=(q->v)[i].w2 && (q->v)[i].w2<(E.v)[i].w2)overlap[i]=3;
if((q->v)[i].w1<(E.v)[i].w1 && (E.v)[i].w1<=(E.v)[i].w2 && (E.v)[i].w2<(q->v)[i].w2)overlap[i]=4;
}
if(sum(overlap,L)==3*L)
{
if(!(size(*q,L)<=rou*size(E,L)))flag=0;
}
delete []overlap;
q=q->next;
}
}
//將滿足候選條件的加入candidate
if(flag)
{
candidate[k]=1;
}
}
p=p->next;
}
if(sum(candidate,M)==0) //沒有滿足候選條件,要新建一個exemplar結點
{
ExemNode* Enew;
Enew=new ExemNode;
mcheck(Enew);
Enew->classnum=classnum;
Enew->v=new FuzzyNum[L+1];
mcheck(Enew->v);
Enew->h=NULL;
Enew->next=NULL;
for(i=1;i<=L;i++)
{
(Enew->v)[i].w1=sample[i].w1;
(Enew->v)[i].w2=sample[i].w2;
(Enew->v)[i].a=sample[i].a;
(Enew->v)[i].b=sample[i].b;
}
p=*exemplar;
if(p==NULL)*exemplar=Enew;
else
{
while((p->next)!=NULL)
p=p->next;
p->next=Enew;
}
}
else
{
double max;
int index;
max=-100;
index=0;
for(j=1;j<=M;j++)
{
if(candidate[j]==1)
{
//計算第i個exemplar結點和輸入模式的相似性
p=*exemplar;
for(i=1;i<j;i++)
p=p->next;
double s=0;
for(i=1;i<=L;i++)
s+=(coa(sample[i])-coa((p->v)[i]))*(coa(sample[i])-coa((p->v)[i]));
s=s/L;
s=sqrt(s);
s=1-s;
if(s>max)
{
max=s;
index=j;
}
}
}
p=*exemplar;
for(j=1;j<index;j++)
p=p->next;
for(i=1;i<=L;i++)
{
if((p->v)[i].w1<sample[i].w1)
{
(p->v)[i].w1=(p->v)[i].w1;
(p->v)[i].a=(p->v)[i].a;
}
else
{
(p->v)[i].w1=sample[i].w1;
(p->v)[i].a=sample[i].a;
}
if((p->v)[i].w2>sample[i].w2)
{
(p->v)[i].w2=(p->v)[i].w2;
(p->v)[i].b=(p->v)[i].b;
}
else
{
(p->v)[i].w2=sample[i].w2;
(p->v)[i].b=sample[i].b;
}
}
}
delete []s;
int temp=sum(candidate,M);
delete [] candidate;
if(temp==0)return(M+1);
else return M;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -