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

📄 indval.cpp

📁 某个实验事编写粗糙集智能信息处理的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "../rset.h"

#include "indval.h"
#include "stdio.h"
#include "stdlib.h"//function atoi();
#include "string.h"
#define MAX 1000
/////////////////////
// indattred class //
/////////////////////
 
IndValRed::IndValRed()
{
	pFileName=NULL;                //待处理的文件名
	pIntTable=NULL;                //原始表,为int类型,中间对象,转化为info表,最后处理用到
	pInfo=NULL;                    //原始表,已转化为int,处理中主要对象,约简对象
	cStyle=NULL;                   //数据集基本类型
	pAttName=NULL;                 //属性名称(安列分)
	pDataType=NULL;                //数据类型(安列分)
	struWCutRecord=NULL;	       //断点链表
	pUindD=NULL;				   //u|d
	pRules=NULL;				   //规则集
	pSameRec=NULL;				   //每条规则能覆盖的记录数
	pNoValCon=NULL;				   //被约掉的条件属性
    max1=0;
}


IndValRed::~IndValRed()
{
	FreeContent();
}
////////////////////////////////////////////////////////
//the implementation of the  public methods
/////////////////////////////////////////////////////////
bool IndValRed::GetInfo(char* FileName)//get the privilege pInformation from the file given.
{//success:return true; else return false
	FILE* fp;
	//return when fail to read the file
	if((fp = fopen(FileName,"r")) == NULL)
	{
		AfxMessageBox("打开文件失败!");
		return false; 
	}
	if((cStyle= new char[MAX])==0)
		return false;
	fscanf(fp,"Style:%s\n",cStyle);
	fscanf(fp,"Stage:%d\n",&iStage);
    //return if not the result of the attribute reduce
/*	if ((stricmp(cStyle,"train")!=0)||(iStage!=3))
	{
		printf("The unfit data set!\n");
		return false;
	}
*/
    fscanf(fp,"Condition attributes number:%d\n",&iConNum);
    fscanf(fp,"The Number of Condition attributes deleted: %d\n",&atbcount); 
	fscanf(fp,"The position of Condition attributes deleted:");
	if(atbcount!=0)
	{
	    if((atb=new int[atbcount])==0)
			return false;
    	for(int n=0;n<atbcount;n++)
		   fscanf(fp," %d\n",&atb[n]);
	}
//	char *s;
    fscanf(fp,"\n");
	fscanf(fp,"Records number:%d\n",&iRecNum);
	ipriRecNum=iRecNum;//读入样本数目
	SetAttName(fp,iConNum+1);
	SetDataType(fp,iConNum+1);
	SetIntegerTable(fp,iConNum+1,iRecNum);//fill the integertable
	SetCutResult(fp);
	fclose(fp);
	return true;
}

bool IndValRed::InitTable()//初始化决策表,得到int类型的表
{ //从文件中得到数据,得到int型表
	int i,j;
	if((pInfo=new int *[iRecNum])==0)
	{
		AfxMessageBox("内存分配错误!");
		return false;
	}
	for (i=0;i<iRecNum;i++)
		if((pInfo[i]=new int [iConNum+1])==0)
		{
	        AfxMessageBox("内存分配错误!");
	        return false;
		}   
	for (i=0;i<iRecNum;i++)
	{
		for (j=0;j<iConNum+1;j++)
		{
			pInfo[i][j] = pIntTable[i][j];  
		}
	}
	return true;
}

int IndValRed::DelOverlap()//删除重复的记录  生成新的表
{//success:return 1 ;else  0
	int i,j,k,t;           //循环变量
	int ** pInfoset;        //删除重复记录后的信息表
	int new_iRecNum=0;     //新信息表中的记录数
	int sum=0;             //统计属性值相同的个数
	bool find=false;
   	int * same_rec;
	if((same_rec=new int[iRecNum])==0)
		return 0;
	int same_num=0;
	//把重复记录编号存在same_rec数组中,same_num中为重复记录数目
	for(i=0;i<iRecNum-1;i++)
		for(j=i+1;j<iRecNum;j++)
		{
			//比较两条记录是否完全相等
			for(k=0;k<iConNum+1;k++)
				if(pInfo[i][k]==pInfo[j][k])
					sum++;
				else
					break;
			//表示完全相等
			if(sum==(iConNum+1))
			{
				for(t=0;t<same_num;t++)
                    //如果记录中有i,说明第j条记录已存在same_rec中了
					if(same_rec[t]==i)
					{
					    find=true;
					    break;
					}
				if(find==false)
			    	same_rec[same_num++]=j;
			}
			find=false;
			sum=0;
		}
	//如果有重复记录
	if(same_num>0)
	{  	//为新表分配空间
		if((pInfoset=new int * [iRecNum-same_num])==0)
			return 0;
		for(i=0;i<(iRecNum-same_num);i++)
		{
			if((pInfoset[i]=new int[iConNum+1])==0)
				return 0;
		}
    	for(i=0;i<iRecNum;i++)
		{
	    	for(j=0;j<same_num;j++)
	    		if(i==same_rec[j])//i为重复样例
	     			break;
	    		else
		    		sum++;   
			if(sum==same_num)
			{	//说明第i条记录不在same_rec中
		        for(j=0;j<iConNum+1;j++)
				{
					pInfoset[new_iRecNum][j]=pInfo[i][j];//new_iRecNum初始为0
				}
				new_iRecNum++;
			}//拷贝到新表
	    	sum=0;
		}
		for(i=0;i<iRecNum;i++)
			delete []pInfo[i];
    	if(pInfo) delete []pInfo;
		pInfo=pInfoset;//得到pInfoset的一个拷贝:pInfo
		iRecNum-=same_num;//为新的记录数目,用来推到规则用
	}
	delete []same_rec;
	return 1;
}

bool IndValRed::SetIntegerTable(FILE* fp,int column, int row)
{//success:return true; else false
	int i,j;
	char* string;
	if((string=new char[MAX])==0)
		return false;
	if((pIntTable = new int*[row])==0)
		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;
}

bool IndValRed::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;
	if(fscanf(fp,"%s",temp) == -1)
	{
		delete[] temp;
		return false;
	}
	if(strcmp(temp,"[Cuts]") != 0)
	{
		delete[] temp;
		return false;
	}
	//	bCuts = true;
	while(fscanf(fp,"%d\n",&iColumn) != -1)
	{//iColumn为列数
		 fscanf(fp,"%d",&iCuts);//iCuts为断点数
		  pEnd = new WCutRecord;
		  if((pEnd->cpCut=new char*[iCuts])==0)
			  return false;
		  for(int i=0;i<iCuts;i++)
		  {
			 if((pEnd->cpCut[i] = new char[MAX])==0)
				 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;
			pHead = pEnd;
		  }//end if
		  else
		  {
			pHead->next = pEnd;
			pHead = pEnd;//移到下一个断点结构
		  }//end else
		}//end while
	delete[] temp;
	return true;
}

bool IndValRed::SetAttName(FILE* fp, int count)
{
	int i;
	if((pAttName = new char*[count])==0)
		return false;
	for(i=0;i < count;i++)
	{
		if((pAttName[i]=new char[MAX])==0)
			return false;
	}//end for
	for(i=0;i < count;i++)
		fscanf(fp,"%s",pAttName[i]);
	return true;
}

bool IndValRed::SetDataType(FILE *fp, int count)
{
	int i;
	pDataType = new char*[count];
	for(i = 0;i < count;i++)
	{
		if((pDataType[i]=new char[MAX])==0)
			return false;
	}//end for
	for(i = 0;i < count;i++)
		fscanf(fp,"%s",pDataType[i]);
	return true;
}

bool IndValRed::SaveFile(char *pFileName)
{
	int i,j;
	FILE* fp;
	if((fp = fopen(pFileName,"w")) == NULL)
	{
		AfxMessageBox("不能打开写文件!\n");
		return false;
	}//end if
	cStyle="rule";
	fprintf(fp,"Style:%s\n",cStyle);
	fprintf(fp,"Stage:%d\n",0);
	fprintf(fp,"Condition attributes number:%d\n",iConNum);
    fprintf(fp,"The Number of Condition attributes deleted: %d\n",atbcount);
    fprintf(fp,"The position of Condition attributes deleted:");
    for(i=0;i<atbcount;i++)
		fprintf(fp," %d ",atb[i]);
		fprintf(fp,"\n");
	fprintf(fp,"Rules number:%d\n",iRulesNum);
	fprintf(fp,"Blocks number:%d\n",0);
	for(i = 0;i < iConNum+1;i++)
		fprintf(fp,"%s ",pAttName[i]);
	fprintf(fp,"\n");
	for(i = 0;i < iConNum+1;i++)
		fprintf(fp,"%s ",pDataType[i]);
	fprintf(fp,"\n");
	struct WCutRecord* pHead = NULL;
	for(i=0;i<iRulesNum;i++)
	{
		for(j=0;j<iConNum;j++)
		{
			if(pRules[i][j]==-1)//约简该属性值
				fprintf(fp,"- ");
			else
			{
				pHead=struWCutRecord;
				while((pHead!=NULL)&&(pHead->iColumn!=j))
					pHead=pHead->next;
				if((pHead!=NULL)&&(pHead->iCuts>pRules[i][j]))
				{
					fprintf(fp,"%s ",pHead->cpCut[pRules[i][j]]);
				}
				else
					fprintf(fp,"%d ",pRules[i][j]);
			}
		}
		fprintf(fp,"%d ",pRules[i][iConNum]);//决策属性单独处理
		fprintf(fp,"%.2f ",1.0);
		fprintf(fp,"%d ",pSameRec[i]);
		fprintf(fp,"%d\n",pSameRec[i]);
	}
	fclose(fp);
	return true;
}

//首先求U|ind(xset),再求U|D,然后求Pos(X)D
bool IndValRed::PosXD(int XNum,int* XSet,PosD* PosXD)
{	//求U|D,结果放在iClassNumD,UindD 中
	int iClassNumD=0;
	int DNum=1;
	int *DSet=new int[1];
	DSet[0]=iConNum;
	int **UindD;
	if((UindD=new int*[iRecNum])==0)
	{
		AfxMessageBox("内存分配错误!");
		return false;
	}
	for(int j=0;j<iRecNum;j++)
		if((UindD[j]=new int[iRecNum+1])==0)
		{
			AfxMessageBox("内存分配错误!");
			return false;
		}
	//call UindX()
	UindX(DNum,DSet,iClassNumD,UindD);
	delete []DSet;

	//求U|ind(X),结果放在iClassNumX,UindX中
	int iClassNumX=0;
	int **pUindX;
	if((pUindX=new int*[iRecNum])==0)
	{
		AfxMessageBox("内存分配错误!");
		return false;
	}
	for(j=0;j<iRecNum;j++)
		if((pUindX[j]=new int[iRecNum])==0)
		{
	 	   AfxMessageBox("内存分配错误!");
		   return false;
		}
	//call UindX()
	UindX(XNum,XSet,iClassNumX,pUindX);
	//求pos(x)D
	//就是包含在u|d中的uindX的并集
	//简化算法,如果uindx的某一类的元素全在U\D的同一类中,那么就是了。
	for(int i=0;i<iClassNumX;i++)//对uindx中的每一类
	{
		int flag=1;//全部元素都是同一类的sign
		int tempsame=-1;//统一的类
		int sameclass=-1;//临时的类
		for(int k=0;k<pUindX[i][0];k++)//每一类中的元素,与uindd中的每一类比较
		{
			for(int j=0;j<iClassNumD;j++)
			{
				int oneflag=0;
				for(int l=0;l<UindD[j][0];l++)
				{
					if(pUindX[i][k+1]==UindD[j][l+1])
					{//修改
						oneflag=1;
						break;
					}
				}
				if(oneflag==1)
				{
					sameclass=j;//找到条件子类中的一个元素属于决策集合的类
					break;
				}
			}
			
			if(tempsame<0)
			{
				tempsame=sameclass;
			}
			else
			{
				if(tempsame!=sameclass)
				{//属于不同的决策类
					flag=0;
					break;
				}
			}
		}//end for
		if(flag==1)//同类,加入到PosXD中
		{
			for(int j=0;j<pUindX[i][0];j++)
				PosXD->PosSet[PosXD->PosNum+j]=pUindX[i][j+1];
			PosXD->PosNum+=pUindX[i][0];
		}
	}//end for
	for(j=0;j<iRecNum;j++)
	{	delete []UindD[j];
		delete []pUindX[j];
	}
	delete []pUindX;
	delete []UindD;
	return true;
}

//求Unid(X)
void IndValRed::UindX(int XNum,int* XSet,int& iClassNumX,int**&pUindX)
{
	iClassNumX=0;
	//将第一条记录归入第一类
	pUindX[0][0]=1;
	pUindX[0][1]=0;
	iClassNumX++;//iClassNumX为1
//比较其他的类,对于剩下的每一条记录,如果相等归入同一类,不同就开辟新类
	for(int i=1;i<iRecNum;i++)
	{//第i个记录
		int flag=0;
		int sameClass=0;
		for(int j=0;j<iClassNumX;j++)//比较每一个已经存在的类
		{
			int oneflag=1;
			for(int k=0;k<XNum;k++)//对所有属性
			{//XSet[k]表示属性位置 
				if(pInfo[i][XSet[k]]!=pInfo[pUindX[j][1]][XSet[k]])
				{//最开始时后面的记录和第一条记录属性比较
					oneflag=0;
					break;//有一个属性值不等,说明不属于一类
				}
			}
			if(oneflag==1)//属于一类
			{
				flag=1;
				sameClass=j;//此时记录i属于类j
				break;
			}
		}
		if(flag==1)//同类
		{
			pUindX[sameClass][0]++;//类中的元素数目加一
			pUindX[sameClass][pUindX[sameClass][0]]=i;//增加一个元素
		}
		else//开辟一个新类
		{
			pUindX[iClassNumX][0]=1;
			pUindX[iClassNumX][1]=i;
			iClassNumX++;
		}
	}//endof for
}

//求negcoreCD的Xnum阶幂集,用递归算法
//首先求一阶的,再求2阶的,再求3阶,慢慢地递归调用而已
//当XNum降到2阶时,DemNum也恰好增大到最初XNum的值
//注意:求得的结果不是属性在原集合中的排列位置,其值是相对negCoreCD而言
bool IndValRed::DemSet(int XNum,int DemNum,int& iDemSetNum,
					   int XCoreNum,int*** pDemSet)
{//XNum:阶数  //结果放在DemSet,iDemSetNum中  // DemNum最小为2
////pDemSet:pCoreCD的幂集   iDemSetNum:pCoreCD幂集的元素个数
/*
    二阶时 tempDemSetNum最终为:1/2*CoreNum*(CoreNum-1)
i=0:	tempDemSet[0][0]=0  [0][1]=1  //一个二阶幂
	          [1][0]=0      [1][1]=2//一个二阶幂
			  [2][0]=0      [2][1]=3
i=1:  [XCoreNum-1][0]=1     [..][1]=2
              [..+1][0]=1   [..+1][1]=3
			  [..+2][0]=1   [..+2][1]=4
			  ...
*/
	if(XNum<2)//只计算高于2阶的幂子集 
		return true;
	int tempDemSetNum=0;
	int** tempDemSet;//存储临时的DemNum阶幂集
	if((tempDemSet=new int*[iDemSetNum*XCoreNum])==0)
		return false;
	for(int i=0;i<iDemSetNum*XCoreNum;i++)
		if((tempDemSet[i]=new int[iConNum])==0)
			return false;
	for(i=0;i<iDemSetNum;i++)
	{
		for(int j=(*pDemSet)[i][DemNum-2]+1;j<XCoreNum;j++)
		{
			for(int k=0;k<DemNum-1;k++)
				tempDemSet[tempDemSetNum][k]=(*pDemSet)[i][k];
			tempDemSet[tempDemSetNum++][DemNum-1]=j;
		}
	}
//	for(i=0;i<iDemSetNum*XCoreNum;i++)
//		delete [](*pDemSet)[i];
//	delete [](*pDemSet);
	for(i=0;i<tempDemSetNum;i++)
		for(int j=0;j<DemNum;j++)
			(*pDemSet)[i][j]=tempDemSet[i][j];
	iDemSetNum=tempDemSetNum;
	//递归调用
	if(!DemSet(XNum-1,DemNum+1,iDemSetNum,XCoreNum,pDemSet))
		return false;
    return true;
}
/*	
//求CoreA的Xnum阶幂集
//首先求一节的,再求2节的,慢慢地递归调用而已。
//结果放在pDemSet,iDemSetNum中。
//注意:求得的结果不是属性在原集合中的排列位置,其值是相对
//CoreA而已的。
void IndValRed::DemSet(int XNum,int DemNum,int& iDemSetNum,int XCoreNum,int*** pDemSet)
{
	if(XNum<2) 
		return;
	int tempDemSetNum=0;
	int** tempDemSet=new int*[MAX];
	for(int i=0;i<MAX;i++)
		tempDemSet[i]=new int[iConNum];
		  
	for(i=0;i<iDemSetNum;i++)
	{
		for(int j=(*pDemSet)[i][DemNum-2]+1;j<XCoreNum;j++)
		{
			for(int k=0;k<DemNum-1;k++)
				tempDemSet[tempDemSetNum][k]=(*pDemSet)[i][k];
			//	tempDemSet[tempDemSetNum]=DemSet[i];
			tempDemSet[tempDemSetNum++][DemNum-1]=j;
		}
	}
	for(i=0;i<MAX;i++)
		delete [](*pDemSet)[i];
	delete [](*pDemSet);

	(*pDemSet)=tempDemSet;
	iDemSetNum=tempDemSetNum;
	//递归调用
	DemSet(XNum-1,DemNum+1,iDemSetNum,XCoreNum,pDemSet);
}
*/
void IndValRed::FreeContent()
{
	for(int i=0;i<ipriRecNum;i++)
		delete []pIntTable[i];
	delete []pIntTable;

	for (i=0;i<iRecNum;i++)
		delete []pInfo[i];
	delete []pInfo;

	for(i=0;i<iRecNum;i++)
		delete []pUindD[i];
	delete []pUindD;

⌨️ 快捷键说明

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