⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attentropyreduce.cpp

📁 某个实验事编写粗糙集智能信息处理的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -