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

📄 attentropyreduce.cpp

📁 某个实验事编写粗糙集智能信息处理的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// AttEntropyReduce.cpp: implementation of the CAttEntropyReduce class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "RSet.h"
#include "AttEntropyReduce.h"
#include "stdio.h"
#include"math.h"
#include "stdlib.h"
#include "string.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define MAX 100
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAttEntropyReduce::CAttEntropyReduce()
{

	pIntTable = NULL;
    pBlockTable = NULL;
    pAttName = NULL;
	pDataType = NULL;
	pAttReduce = NULL;
	struWCutRecord = NULL;
    iInteger = 0;
	iRecordNum = 0;
	iAttNum = 0;
    iBlockNum = 0;
    iStage = -1;
    bSaveTempResult = FALSE;
	bCuts = FALSE;//表示是否存在断点集合
	bBlock = FALSE;
}

CAttEntropyReduce::~CAttEntropyReduce()
{
   FreeContent(); 
}
bool CAttEntropyReduce::AttEntropyReduce()
{
    //double duration;
//	CString str;
   // clock_t  finish	,start;
//	start = clock();
    InitTable();
 //把字符型表转化为int类型
//建立可辨识矩阵与array中,其中不保存重复的属性组合,也没有
//保存该属性组合是属于哪两个记录的,并且对于每个属性组合只保
//留了前两个使他们不同的属性,因为计算核属性既是只有一个属性
//能区分这两个记录的属性,所以不用全部记录下来
//array[i][0]保存的是第i个属性组合的个数(不是1就是2)
   if(Create_Table()==0)//建立决策初始表//建立可辨识矩阵或决策矩阵
      return false;
	if( Create_Array()==1)//success
	{
		if(!Reduct_Table())//计算核属性的表格
	      return false; 
	}
	else 
		return false;
    if(!Get_Att(result,reduct_num))//得到属性值
		return false;
   // finish = clock();
	//duration = (double)(finish - start) / CLOCKS_PER_SEC;
	//str.Format (" 约简运行时间:%f 秒",duration);
    //AfxMessageBox(str);  
	return true;
}

bool  CAttEntropyReduce::GetData(char* FileName)
{//get the privilege pInformation from the file given.
	FILE* fp;

	//return when fail to read the file
	if((fp = fopen(FileName,"r")) == NULL)
	{
//		printf("Can't open the File!\n");
		AfxMessageBox("Can't open the File!");
		return false; 
	}
   // cStyle= new char[100];
	fscanf(fp,"Style:%s\n",cStyle);
	fscanf(fp,"Stage:%d\n",&iStage);
	fscanf(fp,"Condition attributes number:%d\n",&iAttNum);
	fscanf(fp,"Records number:%d\n",&iRecordNum);
	//ipriRecNum=iRecNum;
	SetAttName(fp,iAttNum+1);
	SetDataType(fp,iAttNum+1);
	SetIntegerTable(fp,iAttNum+1,iRecordNum);//fill the integertable
	if(!SetCutResult(fp))
		return false;
	fclose(fp);
	return  true;
}



bool CAttEntropyReduce::SetAttName(FILE* fp, int count)//count是总共的属性数目
{
	int i;
	if(pAttName == NULL)//还没有赋值
	{
		try
		{
			pAttName = new char*[count];
		}
		catch(CMemoryException* e)
		{
			::MessageBeep(MB_ICONHAND);
			AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
			e->Delete();
			return FALSE;
		}

		for(i=0;i < count;i++)
		{
			try
			{
				pAttName[i]=new char[100];
			}
			catch(CMemoryException* e)
			{
				::MessageBeep(MB_ICONHAND);
				AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
				e->Delete();
				return FALSE;
			}
		}//end for
	}//end if

	for(i=0;i < count;i++)
		fscanf(fp,"%s",pAttName[i]);
	return true;
}

bool CAttEntropyReduce::SetDataType(FILE *fp, int count)
{
	int i;
	try
	{
		pDataType = new char*[count];
	}
	catch(CMemoryException* e)
	{
		::MessageBeep(MB_ICONHAND);
		AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
		e->Delete();
		return FALSE;
	}
	for(i = 0;i < count;i++)
	{
		try
		{
		  pDataType[i]=new char[MAX];
		}
		catch(CMemoryException* e)
		{
		  ::MessageBeep(MB_ICONHAND);
		  AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
		  e->Delete();
		  return FALSE;
		}
	}//end for

	for(i = 0;i < count;i++)
		fscanf(fp,"%s",pDataType[i]);
	return true;
}

bool CAttEntropyReduce::SetCutResult(FILE* fp)//读入属性断点
{
	int n;
	int iColumn;
	int iCuts;
	struct WCutRecord* pHead = NULL;
	struct WCutRecord* pEnd = NULL;
	char* temp;
	if((temp= new char[MAX])==0)
		return false;//MAX=100
	if(fscanf(fp,"%s",temp) == -1)
	{
		delete[] temp;
		return true;
	}
	if(strcmp(temp,"[Cuts]") != 0)
	{
		delete[] temp;
		return false;
	}
//	bCuts = true;
	while(fscanf(fp,"%d",&iColumn) != -1)//iColumn为属性所在的列
	{
		fscanf(fp,"%d",&iCuts);//iCuts断点数
		pEnd = new WCutRecord;//WCutRecord为断点链表
		if((pEnd->cpCut=new char*[iCuts])==0)
			return false;
		for(int i=0;i<iCuts;i++)
		{
			if(0==(pEnd->cpCut[i] = new char[MAX]))
				return false;
		}//end for
		pEnd->iColumn=iColumn;
		pEnd->iCuts=iCuts;
		pEnd->next=NULL;//下一个断点集
		for(i=0;i<iCuts;i++)
		{
			fscanf(fp,"%s",temp);//[*,*]当成字符串处理
			fscanf(fp,"%d",&n);//离散化值
			strcpy(pEnd->cpCut[n],temp);
		}//end for
		if(pHead == NULL)
		{
			struWCutRecord = pEnd;
			//struWCutRecord为放置断点的链表的入口
			pHead = pEnd;//指向同一个节点
		}//end if
		else
		{
			if(pHead->iColumn>=pEnd->iColumn)
			{
				AfxMessageBox("断点表设置有误!");
                struWCutRecord =NULL;
				return false;
			}
			pHead->next = pEnd;//加入断点链表
			pHead = pEnd;
		}//end else
	}//end while

	delete[] temp;
	return true;
}
bool CAttEntropyReduce::SetIntegerTable(FILE* fp,int column, int row)
{
	int i,j;
	char* string;
	if((string=new char[100])==0)
		return false;
	try
	{
	  pIntTable = new int*[row];
	}
	catch(CMemoryException* e)
	{
	  ::MessageBeep(MB_ICONHAND);
	  AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
	  e->Delete();
	  return FALSE;
	}
	for(i = 0;i<row;i++)
	{
	  if((pIntTable[i] = new int[column])==0)
			return false;
	}//end for

	for(i=0;i<row;i++)
	{
		for(j=0;j<column;j++)
		{
			fscanf(fp,"%s",string);
			if(strcmp(string,"-") == 0)
				pIntTable[i][j] = -1;
			else
				pIntTable[i][j] = atoi(string);
		}//end for
	}//end for
	delete []string;
	return true;
}


void CAttEntropyReduce::InitTable()//输入离散后的初始化决策表
{
	int i,j;
    rec_num = iRecordNum;//记录对象数   
	con_num = iAttNum;//条件属性数
	if((info=new int *[rec_num])==0)//原始表,以转化为int指针
	{
        AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
    	return;
	}
	for (i=0;i<rec_num;i++)
	{
		try
		{
			info[i]=new int [con_num+1];
		}
		catch(CMemoryException* e)
		{
	     ::MessageBeep(MB_ICONHAND);
	     AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
	     e->Delete();
	     return;
		}
	}
	for (i=0;i<rec_num;i++)
	   for (j=0;j<con_num+1;j++)
		info[i][j] = pIntTable[i][j]; 
}

int CAttEntropyReduce::Create_Table()//初步简化决策表,删除多余的行
{//成功:1  失败:0
	int i,j,k,t;          
	int ** infoset;     //删除重复记录后的信息表//新的决策表
	int new_rec_num=0;  //新信息表中的记录数.对象数
	int sum=0;          //统计属性值相同的个数
	bool find=FALSE;//缺省的BOOL值
   	int * same_rec;//指向相同对象的指针编号
	if((same_rec=new int[rec_num])==0)
		return 0;//成功时返回1,失败返回0
    int same_num=0;
	//把重复记录编号存在same_rec中,same_num中为重复记录数目
    for(i=0;i<rec_num-1;i++)//i表示记录数
		for(j=i+1;j<rec_num;j++)
		{	//比较两条记录是否完全相等
			for(k=0;k<con_num+1;k++)
			{    //··········!!##修改过的地方
				if(info[i][k]==info[j][k])
					sum++;
				else
					break;
			}
			if(sum==(con_num+1))//完全相同的属性值
			{
				for(t=0;t<same_num;t++)  
			//same_num是相同的数量,与T的量分开
            //如果记录中有i,说明第j条记录已存在same_rec中了
					if(same_rec[t]==i)
					{
					    find=TRUE;
					    break;
					}
				if(find==FALSE)//缺省值
					//same_num指相同的条件属性的个数
			    	same_rec[same_num++]=j;
			}
			find=FALSE;
			sum=0;
		}//浏览整个决策表如果有重复记录,采取的措施
	if(same_num>0)
	{
    	//为新表分配空间
		if((infoset=new int * [rec_num-same_num])==0)
			return 0;//分配新的决策表
		for(i=0;i<(rec_num-same_num);i++)
		{
			if((infoset[i]=new int[con_num+1])==0)
				return 0;
		}
		bool a;//判断标志
    	for(i=0;i<rec_num;i++)
		{
			a=false;
	    	for(j=0;j<same_num;j++)
	    		if(i==same_rec[j])//此时在same_rec中,
				{
					a=true;
					break;
				}
			if(!a)  //说明第i条记录不在same_rec中
			{
		        for(j=0;j<con_num+1;j++)
				{//new_rec_num初始值为0
					infoset[new_rec_num][j]=info[i][j];
				}
				new_rec_num++;
			}
		}
		for(i=0;i<rec_num;i++)
			delete []info[i];
    	delete []info;
		info=infoset;//重新初始化
		rec_num-=same_num;//决策表改变得到互不相同的记录的数目
	}
	delete []same_rec;
	if((IND_Attrb= new  int*[rec_num+1])==0)//为IND_Attrb分配内存
		return 0;// 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 0;
	}
	return 1;
}
int CAttEntropyReduce:: Create_Array()//建立可辩识矩阵
{
	int i,j,k,l,n;         //循环变量
    int * att;            //条件属性组合
	int find=FALSE;
	int m=0,num=0;
	element=0;//可辩识(决策)矩阵中的元素个数
    if((att=new int[con_num+1])==0)
		return 0;//不成功返回为0,成功返回为1
    for(i=0;i<rec_num-1;i++)
		for(j=i+1;j<rec_num;j++)
			if(info[i][con_num]!=info[j][con_num])
			{//如果决策属性不相等  con_num为条件属性数
			//把不相等的条件属性记录下来,放在att中
			   for(k=0;k<con_num;k++)
				{
				   if(m>1) //m初始化为0  最多只记录两个不一致属性
					 break;
					if(info[i][k]!=info[j][k])
					{
						att[++m]=k;//k为不一致的属性位置
					}            
			    }
			    att[0]=m;//att[0]表示不一致属性数目 m=1或2  
			    m=0;
			    for(l=0;l<element;l++)//在可辨识矩阵中寻找满足该不一致属性位置和大小的记录
				{//array 表示可辨识矩阵
				    if(array[l][0]==att[0])
					{//array[l][0]存储区别属性的数目
			 	       for(n=1;n<=att[0];n++)
						   if(array[l][n]==att[n])
                                 num++;//num初始化是0
				       if(num==att[0])
					   {
				            find=TRUE;//表示在可辨识矩阵中找到此差异属性
						   	break;//退出
					   }
					}
					num=0;
				}
			   	if(find==FALSE)
				{
					int ** newarray;
					//建立新表来存储决策表的样例的差异属性
					if((newarray=new int *[element+1])==0)
						return 0;
					for(l=0;l<element;l++)
					{
					    if((newarray[l]=new int[array[l][0]+1])==0)
							return 0;
						for(n=0;n<array[l][0]+1;n++)
							newarray[l][n]=array[l][n];//拷贝原表到暂时表中
					}
			    	if(element>0)
			       		delete []array;//删除原表
			    	array=newarray;//重新初始化
				
			    	if((array[element]=new int[att[0]+1])==0)//再分配一行
						return 0;
			       	for(l=0;l<att[0]+1;l++)
				       	array[element][l]=att[l];//写入新行中
				   	element++;
				}
				find=FALSE;
				num=0;
			}
    delete []att;
    return 1;
}

bool CAttEntropyReduce::Reduct_Table() //计算结果属性组合
{   
	double  H_DR_ALL;
	int count=0;
	int ncount=0;
	int i,j,k; //循环变量
 
   	redu_att_num=0;
	redu_num=0;
    red_dec_num=1;
   	if((attallreductset=new int[con_num+1])==0)
		return false;//全局熵的计算指针,con_num:条件属性数
    if((reductset=new int[con_num+1])==0)
		return false;//*计算核属性 con_num =7 rec_num=89 是
    if((attreductset= new int[con_num+1])==0)
		return false;///约简条件属性集
    if((decreductset= new int[2])==0)
		return false;//约简后的决策属性集
	if((resultset= new int[con_num+1])==0)
		return false;//约简结果
	if((attreductsetxu=new int[2])==0)
		return false;
    attreductsetxu[0]=1;//计算单个条件熵
	reductset[0]=0;
	attreductset[0]=0;
 //找出核属性/约简后的核属性数:redu_att_num=5 核属性数为 0 1 4 5 6 
    for(i=0;i<element;i++)//element:可辩识(决策)矩阵中的元素个数
		if(array[i][0]==1)
		{
			reductset[++redu_att_num]=array[i][1];//取第一个属性
			reductset[0]=redu_att_num;//核属性数目redu_att_num
		} 
  //找出非核属性//redu_att_num=2 核属性为 2 3
    for(k=0;k<con_num;k++)////条件属性数con_num
	{
   	  for(j=1;j<=redu_att_num;j++)
		{
			if(k!=reductset[j])
				   count++;//用count是否为核属性数目来判断是否是非核属性
		}
        if(count==redu_att_num)//此时属性k为非核属性
		{
			 attreductset[++redu_num]=k;//加入非核条件属性集
			 attreductset[0]=redu_num;//非核条件属性数目
		}
			count=0;//清零,为下次循环准备
	}
    //决策属性数的个数及属性号码
     decreductset[0]=1;	//约简后的决策属性集
	 decreductset[1]=con_num;
     //初始化约简结果的值(核属性)
	result_num=redu_att_num;//初始化为核属性数目
	resultset[0]=result_num;
	attreductset[0]=redu_num;//attreductset为约简结果集
	for(i=1;i<=result_num;i++)
	{  
		resultset[i]=reductset[i];
	}
    for(i=1;i<=con_num;i++)
	{  
		attallreductset[i]=i-1;//为了求entropy
	}
   ////////全集条件熵的计算
   //Entropy(int *q,int Q,int *p,int P)求条件熵H(q|p)
	H_DR_ALL=Entropy(decreductset,1, attallreductset,con_num);
    if(H_DR_ALL==-1)//计算失败

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -