📄 attentropyreduce.cpp
字号:
return false;
//计算单属性的条件熵/////
double *H_DR;
if((H_DR=new double[con_num+1])==0)
return false;
if(result_num!=0)//核属性不为空
H_DR[0]=Entropy(decreductset,1, resultset,result_num);
//得到核条件属性的条件熵
if(H_DR[0]==-1)//计算失败
return false;
for(j=0;j<redu_num;j++)//redu_num:非核的条件属性个数
{
if(result_num==0)//没有核属性
{
for(i=1;i<=redu_num;i++)//redu_num约简后的条件属性个数
{//attreductset约简条件属性集
attreductsetxu[1]=attreductset[i];
H_DR[i]=Entropy(decreductset,1, attreductsetxu,1);
//得到非核属性的第i个属性的熵
if(H_DR[i]==-1)
return false;
}
double t=H_DR[1];
int m,temp=-1;//
///////找出最大 的互信息的元数
for(i=1;i<=redu_num;i++)
{
if(t>H_DR[i])
t=H_DR[i]; //得到最小熵
}
for(i=1;i<=redu_num;i++)
{
if(t==H_DR[i])
{ //int *resultset 约简结果
if(temp!=-1)
{//有两个属性同时具有最大的互信息,计算得到属性值组合数最小的属性
resultset[result_num+1]=attreductset[m];
IND(resultset,result_num+1,rec_num);
int m1=IND_Order;
resultset[result_num+1]=attreductset[i];
IND(resultset,result_num+1,rec_num);
int m2=IND_Order;
if(m1>m2)
m=i;
}
else
{ //first time
m=i;//此时为满足条件的第一个最小熵值对应属性:没考虑到同时有多个属性满足条件的情况
temp=i;
}
}//end if
}//end for
resultset[result_num+1]=attreductset[m];
///////////换号码///////////////
if(m!=con_num-result_num)
//con_num-result_num得到剩下的非约简的属性数目
//con_num为条件属性数,m不在最后
{//result_num为核属性数目,开始时为0
int k;
for(i=m;i<con_num-result_num;i++)//m以后的属性依次向前移
{
k=attreductset[i+1];
attreductset[i]=k;
}
}
result_num++;
H_DR[0]=t; //0位置保存现有的约简属性的熵值,此时只有一个属性
} //等于零算到此
else /////核属性不为零
if(H_DR_ALL!=H_DR[0])//若H(D|B)= H(D|C)则终止,否则进行下列处理
{
//H_DR[0]=Entropy(decreductset,1, resultset,result_num); 已经处理了
//H(D|R);
for(i=1;i<=con_num-result_num;i++)//对每个非核属性都计算熵
{
resultset[result_num+1]=attreductset[i];
H_DR[i]=Entropy(decreductset,1,resultset,result_num+1);//H(D|RVa)
if(H_DR[i]==-1)
return false;
}
double t=H_DR[1];
int m,temp=-1;//m是最大互信息的属性顺序数
for(i=1;i<=con_num-result_num;i++)
{
if(t>H_DR[i])//找出最大 的互信息的元数
t=H_DR[i];
}
for(i=1;i<=con_num-result_num;i++)
{
if(t==H_DR[i])
{
if(temp==-1)
{//first time
m=i;
temp=i;
}
else
{//有两个属性同时具有最大的互信息,计算得到属性值组合数最小的属性
resultset[result_num+1]=attreductset[m];
IND(resultset,result_num+1,rec_num);
int m1=IND_Order;
resultset[result_num+1]=attreductset[i];
IND(resultset,result_num+1,rec_num);
int m2=IND_Order;
if(m1>m2)
m=i;
}
}//end if(t=H_DR[i])
}//end for
resultset[result_num+1]=attreductset[m];//为最大的互信息的属性号码数
//////////换号码///////////////
if(m!=con_num-result_num)
{
int k;
for(i=m;i<con_num-result_num;i++)
{//移出选中的属性,并将后面的非核属性前移
k=attreductset[i+1];
// attreductset[i+1]=attreductset[i+2];
attreductset[i]=k;
// attreductset[i+1]
}
}//end if
result_num++; //得到最终的约简结果属性的数目
H_DR[0]=t;//核的熵值
if(H_DR[0]==H_DR_ALL)
break;
} //end else if
}//end 最外层的for循环
//约简结果
resultset[0]=result_num;//最终约简结果的条件属性数目
reduct_num=1;
if((result=new int * [reduct_num])==0)
return false;
if((result[0]=new int[redu_att_num+1])==0)
return false;
result[0][0]=result_num;
for(i=0;i<result_num;i++)
result[0][i+1]=resultset[i+1];
SelectSort(result[0]);//SelectSort(int * att)
//用选择法对约简后的属性重新排列,对数组att中的元素按从小到大排序
/////////////////////////////
delete []reductset; //核条件属性集
delete []attreductset; //非核条件属性集
delete []decreductset;//决策属性集
delete []resultset;//约简结果集
delete []attallreductset;
delete []attreductsetxu;
delete []H_DR;
return true;
}
bool CAttEntropyReduce::Get_Att(int ** att,int num)//得到属性表
{ //将pAttName 拷贝到reduct_att中
int i,j;
redu_att_num=att[0][0]; //决策属性数
/* int **attredu=new int * [reduct_num];
for(i=0;i<num;i++)
{
attredu[i]=new int[redu_att_num+1];
for(j=0;j<redu_att_num+1;j++)
attredu[i][j]=att[i][j];
} */
if((reduct_att=new char ** [reduct_num])==0)
return false;//属性约简后的条件属性集
for(i=0;i<reduct_num;i++)
{
if((reduct_att[i]=new char * [att[i][0]])==0)
return false;
for(j=0;j<att[i][0];j++)
if((reduct_att[i][j]=new char[MAX])==0)//MAX=1000
return false;
for(j=0;j<att[i][0];j++)
strcpy(reduct_att[i][j],pAttName[att[i][j+1]]);
}
return true;
}
void CAttEntropyReduce::SelectSort(int * att)
{//用选择法对约简后的属性重新排列,对数组att中的元素按从小到大排序
int i,j; //循环变量
int min_item; //具有最小值的项
int transfer;
for(i=0;i<att[0]-1;i++)//att[0]中保存有约简后的条件属性数目
{
min_item=i;
for(j=i+1;j<att[0];j++)
if(att[j+1]<att[min_item+1])
min_item=j;
if(min_item!=i)
{
transfer=att[i+1];
att[i+1]=att[min_item+1];
att[min_item+1]=transfer;
}
}
}
bool CAttEntropyReduce::SaveFile(char* pFileName)
{
int *a;
a=new int[iAttNum];
if(a==NULL)
return false;//计算得到的属性
nSelected=0;
int i,j,t,k,m=0,n;
FILE* fp;
if(nSelected == -1)//?
return FALSE;
if((fp = fopen(pFileName,"w")) == NULL)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Couldn't save the file",MB_OK|MB_ICONSTOP);
return FALSE;
}//end if
fprintf(fp,"Style:%s\n",cStyle);
fprintf(fp,"Stage:%d\n",3);
//去除“—”的程序变化
fprintf(fp,"Condition attributes number:%d\n",result_num);
for(i = 0;i < iAttNum;i++)
{
t=0;
for(k=0;k<result[nSelected][0];k++)//约简结果result
{
if(result[nSelected][k+1] == i)//表示此时属性在约简结果中
t=1;
}
if(t!=1)
a[m++]=i;//a指针记录非约简结果属性位置,m表示删除了的属性数目
}
fprintf(fp,"The Number of Condition attributes deleted:%d\n",m);
fprintf(fp,"The position of Condition attributes deleted:");
if(m>0)
for(i=0;i<m;i++)
fprintf(fp," %d",a[i]);
fprintf(fp,"\n");
fprintf(fp,"Records number:%d\n",iRecordNum);
for(i = 0;i < iAttNum;i++)
{
t=0;
for(k=0;k<result[nSelected][0];k++)
{
if(result[nSelected][k+1] == i) //表示此时属性在约简结果中
t=1;
}
if(t==1)
fprintf(fp,"%s ",pAttName[i]);
}
fprintf(fp,"%s ",pAttName[iAttNum]);
fprintf(fp,"\n");
for(i = 0;i < iAttNum;i++)
{
t=0;
for(k=0;k<result[nSelected][0];k++)
{
if(result[nSelected][k+1] == i) //表示此时属性在约简结果中
t=1;
}
if(t==1)
fprintf(fp,"%s ",pDataType[i]);
}
fprintf(fp,"%s ",pDataType[iAttNum]);
fprintf(fp,"\n");
for(i=0;i<iRecordNum;i++)
{
for(j=0;j<iAttNum;j++)
{
t=0;
for(k=0;k<result[nSelected][0];k++)
{
if(result[nSelected][k+1] == j) //表示此时属性在约简结果中
t=1;
}
if(t==1)
fprintf(fp,"%d ",pIntTable[i][j]);//输出属性值
// else
// fprintf(fp,"%c ",'-');
}
fprintf(fp,"%d ",pIntTable[i][iAttNum]);//输出决策
fprintf(fp,"\n");
}
if(struWCutRecord == NULL)//断点集为零
{
fclose(fp);
return TRUE;
}
else
{
struct WCutRecord* tem= struWCutRecord;
if(tem!=NULL)
fprintf(fp,"[Cuts]\n");
n=0;
while(tem != NULL)
{
bool flag=true;
for(i=0;i<m;i++)//m表示删除了的属性数目
if (a[i]==tem->iColumn)
{
flag=false;//标记为false表示不予输出
n++;//统计false数目
break;//跳出for循环
}
if(flag)
{
fprintf(fp,"%d\n",(tem->iColumn)-n);
fprintf(fp,"%d\n",tem->iCuts);
for(i = 0;i < tem->iCuts;i++)
{
fprintf(fp,"%s ",tem->cpCut[i]);
fprintf(fp,"%d\n",i);
}//end for
}//end if
tem = tem->next;
}//end while
fclose(fp);
delete a;
return true;
}//end else
}
//根据属性集合b对决策表进行划分,B表示属性集合b的元素个数,rownum
//表示要划分的记录的个数,划分结果保存在IND_Attrb中,
//IND_Order表示划分成的集合的个数,IND_MaxNum表示所有集合中
//元素最多的集合所包含的元素的个数
void CAttEntropyReduce::IND(int *b, int B, int rownum)//划分
{
int ind_order;
int ind_num,num_colattrsame=0,j,k,m;
int p,q,i,number=0;
int *flag;//标记已经分类了的样例
if((flag= new int[rownum])==0)
AfxMessageBox("分配内存失败");
for (i=0; i<rownum;i++) // 初始化FLAG=0;
flag[i]=0;
for (i=1;i<=rec_num;i++)//rec_num记录对象数
for(j=0;j<=rec_num;j++)
IND_Attrb[i][j]=0; // 初始化IND_Attrb为0
//---------------------------
i=0;
ind_order=0;
IND_MaxNum = 0;
while(i<rownum)
{
ind_order += 1;//划分的个数加一
ind_num = 1;
IND_Attrb[ind_order][0]=1;//初始化样例i的一个等价类
IND_Attrb[ind_order][1]=i+1;
flag[i]=1;
for (j=i+1; j<rownum;j++)//扫描一遍样例,添加等价类
{
if (flag[j]==1)
continue;
for (k=1; k<=B; k++)//B为b包含样例的个数
{
p = info[i][b[k]];
q = info[j][b[k]];
if (p == q)
num_colattrsame +=1;//相同的条件属性数目
}
if (num_colattrsame == B)//如果都相同,则将其添加到等价类中
{
ind_num +=1;
IND_Attrb[ind_order][ind_num]=j+1;
flag[j]=1;//标志样例已经添加
IND_Attrb[ind_order][0]=ind_num;//记录第ind_order划分中对象的个数
}
num_colattrsame = 0;//清零
}
//确定i值
number=0;
for(m=1;m<rownum;m++)
{
if (flag[m] == 0) //还没有属于某个等价类
number +=1;//number统计还需分类的样例数目
if (number==1 && flag[m]==0)
{//第一个没有分类的样例令为i
i=m;
break;
}
}
if (number==0)//判断溢出条件
i=rownum+1;//最外层的while循环结束
if (ind_num>IND_MaxNum)
//IND_MaxNum表示所有集合中元素最多的集合所包含的元素的个数
IND_MaxNum = ind_num;
}
IND_Order = ind_order;//得到等价类数目
ind_order=0;
delete []flag;
}
////////////X 与Y的交集个数//Yj与Xi交的个数
int CAttEntropyReduce::YX_Jiao(int j, int i, int **IND_Y )
{
int pyx=0;
int p,q,a,b;
for(p=1;p<=IND_Attrb[i][0];p++)
{
a=IND_Attrb[i][p];
for (q=1;q<=IND_Y[j][0];q++)
{
b=IND_Y[j][q];
if (a==b)
pyx +=1;
}
}
return pyx;
}
////////熵值的计算//////////////
double CAttEntropyReduce::Entropy(int *q , int Q,int *p ,int P)//H(q|p)
{
double H,y;
int m,n,i,j,pyx;
int rownum=rec_num;//rec_num:记录对象数
int **IND_Y;
if((IND_Y=new int*[rec_num+1])==0)
return -1;
for(i=1;i<=rec_num;i++)
if((IND_Y[i]=new int[rec_num+1])==0)
return -1;
for(i=1;i<=rec_num;i++)
for(j=0;j<=rec_num;j++)
IND_Y[i][j]=0;//初始化为0
/*
if((IND_Attrb= new int*[rec_num+1])==0)
return -1;// IND_Attrb[i][0]=K, i号分内的个数为K
for(i=1;i<=rec_num;i++)
{
if((IND_Attrb[i]=new int[rec_num+1])==0)
return -1;
}
*/
//求q集的划分--------------------------
IND(q,Q,rownum);
m=IND_Order;//不可分辨关系的个数
for (i=1;i<=m;i++)
{
for (j=1;j<=IND_Attrb[i][0];j++)
IND_Y[i][j]=IND_Attrb[i][j];
IND_Y[i][0]=IND_Attrb[i][0];
}
//清零
//求p集的划分-------------------------------------
IND(p,P,rownum);
n=IND_Order;//不可分辨关系的个数
//求条件熵H(q|p)
H=0;
for (i=1;i<=n;i++)//n是条件属性的第几个不分辩关系n=89
{
for(j=1;j<=m;j++)//M是决策属性的个数m=8
{
pyx = YX_Jiao(j,i,IND_Y);//X 与Y的交集个数
if (pyx!=0)
{
y=(double ) IND_Attrb[i][0]/pyx; //条件概率的倒数
H=(double) pyx*log10(y)/log10(2)+H;
}
// else
// continue;
}
}
H=H/rownum;
for(i=1;i<=rec_num;i++)
{
delete []IND_Y[i];
}
delete []IND_Y;
/* for(i=1;i<=rec_num;i++)
{
delete []IND_Attrb[i];
}
delete []IND_Attrb;
*/
return H;
}
void CAttEntropyReduce::FreeContent()
{
int i;
for(i=0;i<iRecordNum;i++)
delete []pIntTable[i];
delete []pIntTable;
for(i=1;i<=iRecordNum;i++)
{
delete []IND_Attrb[i];
}
if(IND_Attrb)
{
delete []IND_Attrb;
IND_Attrb=NULL;
}
for (i=0;i<iRecordNum;i++)
delete []info[i];
delete []info;
for(i=0;i<iAttNum+1;i++)
{
delete []pDataType[i];
delete []pAttName[i];
}
delete []pDataType;
delete []pAttName;
//free struWCutRecord
struct WCutRecord* pHead=NULL;
while(struWCutRecord != NULL)
{
pHead = struWCutRecord->next;
for(int i = 0;i < struWCutRecord->iCuts;i++)
delete[] struWCutRecord->cpCut[i];
delete[] struWCutRecord->cpCut;
delete struWCutRecord;
struWCutRecord = pHead;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -