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

📄 disfour.cpp

📁 某个实验事编写粗糙集智能信息处理的程序
💻 CPP
字号:
// DisFour.cpp: implementation of the CDisFour class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DisFour.h"
#include "../RSet.h"
#include "fstream.h"
#include "String.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//我的改进贪心算法,名为改进贪心算法4
CDisFour::CDisFour()
{

}

CDisFour::~CDisFour()
{

}

BOOL CDisFour::OnDisFour()
{
	int matrix_row;                       //矩阵的行数
	int matrix_col;                       //矩阵的列数
    double duration;//计算约简时间的大小
    CString str;
    clock_t  finish	,start;
    start = clock();

	if(iNonStrAttNum!=0)
	{
		if(get_att_val()==-2)
			return FALSE;
		matrix_row=logic();
		matrix_col=init_matrix(matrix_row);
		findcuts(matrix_row,matrix_col);
	}
	make_new_table();
	if(iStrAttNum!=0) 
      doString();

    finish = clock();
    duration = (double)(finish - start) / CLOCKS_PER_SEC;
    str.Format (" 约简运行时间:%f 秒",duration);
    AfxMessageBox(str);  
	return TRUE;
}

void CDisFour::findcuts(int rows, int cols)
{//在新信息表中选取断点,记录在表中的列号,存入cuts数组中  
	int i,j;                    //循环变量
    int * cuts=NULL;
	if((cuts=new int[cols+1])==0)//定义断点
	{ 
		AfxMessageBox("分配内存失败!",MB_OK|MB_ICONSTOP);                     
		return;
	}
	cuts[0]=0;   //设置断点的初始个数
	if((rows==0)||(cols==0))
	{
	 	get_cut(cuts);//得到最终的断点集   
		return;
	}
	int num;
	int remains; //未处理的矩阵元素个数
	int maxvalue;//含1最多的列
	int maxnum; //含1最多的列中1的个数
	int maxcol=0;
    int **maxcols=NULL;
	int minvalue; //在含1最多的列相等的情况下,求对应行断点的最小值
	if((maxcols=new int*[cols])==0)
	{  
		 AfxMessageBox("分配内存失败!",MB_OK|MB_ICONSTOP);                     
	  	 return;
	} 
	for(i=0;i<cols;i++)
		maxcols[i]=new int[2];
	int * countcols=NULL;
	if((countcols=new int[cols])==0) //各列中含1的个数
	{  
		  AfxMessageBox("分配内存失败!",MB_OK|MB_ICONSTOP);                     
		  return;
	}                
	int * countrows=NULL;
	if((countrows=new int[rows])==0)//各行中含1的个数
	{ 
		AfxMessageBox("分配内存失败!",MB_OK|MB_ICONSTOP);                     
		return;
	}
	//初始化各列1的总和以及各行1的总和为0
    for(i=0;i<cols;i++)
	{
       countcols[i]=0;
	   for(j=0;j<2;j++)
	    	maxcols[i][j]=0;
	}
    for(i=0;i<rows;i++)
		countrows[i]=0;

	for(i=0;i<cols;i++)//列
		  for(j=0;j<rows;j++)//行
			  if(matrix[j][i]==1)//统计i列1的数目和
			     countcols[i]++;
    bool tt=false;
	for(i=0;i<rows;i++)//行
	{
		if(i==11)
			int a=0;
		for(j=0;j<cols;j++)//列
			if(matrix[i][j]==1)//统计i行1的数目和
				countrows[i]++;
		if(countrows[i]==1)
		{
			tt=true;
		}
	}
	if(!tt)
	{
		remains=0;
	    for(i=0;i<rows;i++)
	      if(countrows[i]!=0)
		     remains+=countrows[i];
	}
	if(tt)
	{//对断点核的处理
		for(int i1=0;i1<rows;i1++)//行
         if(countrows[i1]==1)//存在行的1的个数为1,存在断点核,所在的行
		 { //为i1
		   for(j=0;j<cols;j++)//列
			   if(matrix[i1][j]==1)
			   {// 找到断点核为第j列,删除此列此行,以及此列上为一的行
				   maxcol=j;
	               for(i=0;i<rows;i++)
		              if(matrix[i][maxcol]==1)
					   {	 
						   countrows[i]=0;//行标志为0,该行删除了
						   for(j=0;j<cols;j++)
							   matrix[i][j]=-1;// 该行每个元素设为-1
					   } 
					for(i=0;i<rows;i++)
						matrix[i][maxcol]=-1;//该列每个元素设为-1
					countcols[maxcol]=0;//列标志标为0
					cuts[0]++;//断点数目加一
					cuts[cuts[0]]=maxcol;//记录此时断点对应的列
					break;
			   }//end for
		 } //end if(countrows[i1]==1)
	     for(i=0;i<cols;i++)
	        if(countcols[i]!=0)//改列还没有删除
			{//统计剩下各列1的数目
			  countcols[i]=0;
			  for(j=0;j<rows;j++)
			    if(matrix[j][i]==1)
			    	 countcols[i]++;
	//统计此时该列中'1'的个数,如大于1,说明还有为一的元素,否则说明该列为全零
				   //元素,下次计算断点的样列对数目时可以不考虑
			} 
	//	 tt=false;
	     for(i=0;i<rows;i++)//对新信息表的每一行
	   	    if(countrows[i]!=0)//改行还没有删除
			{//统计剩下的行
	        	countrows[i]=0;//行标设为0,重新统计
			    for(j=0;j<cols;j++)//列
				   if(matrix[i][j]==1)
					countrows[i]++;//重新统计该行'1'的个数
			//    if(countrows[i]==1)
			  //  	tt=true;
			}
		remains=0;
		for(i=0;i<rows;i++)
		  if(countrows[i]!=0)
			  remains+=countrows[i];
	}

   while(remains>0)//do
	{//对剩下的信息表的处理
		maxnum=0;
		maxvalue=0;
		remains=0;
	//先选列值为1总和最多的断点,
	//当有两列以上都为最多时,看行的总数
    //选取行总数最少的断点
		for(i=0;i<cols;i++)
			if(maxvalue<countcols[i] && countcols[i]>0 )
				maxvalue=countcols[i];//找出列值最大的数设为maxvalue
        for(i=0;i<cols;i++)
          if(countcols[i]==maxvalue)
		     maxnum++;//统计有几列都取得最大值
      if(maxnum==1)
		  {//只有一列1的总数最多
			for(i=0;i<cols;i++)
               if(countcols[i]==maxvalue)
			   {
				   maxcol=i;//列号
				   break;
			   }
		  } 
		else if(maxnum>1)//1的总数最多的列不止一个
		{ 
		   num=0;
		   maxcols[num][0]=maxnum;//个数
           for(i=0;i<cols;i++)
		     if(countcols[i]==maxvalue)
			 {
				  num++;
				  maxcols[num][0]=i;//将列号存入maxcols数组中  num从1开始
			 }
          //判断单行数最少的列
            num=1;//第一个列值最大的单元
		    int num1=0;
		    for(i=0;i<maxnum;i++)
		    {//计算得到每个列对应的行的1个数最小的的数
				 for(j=0;j<rows;j++)
		           if(matrix[j][maxcols[num][0]]==1)
				   {
					   if(num1==0)
						   num1=countrows[j];
					   else
						   if(num1>countrows[j])
							   //比较得到列maxcols[num][0]中1的行的1的个数最小的数
							   num1=countrows[j];
               //行为1的数放在maxcols[num][1]中
						maxcols[num][1]=num1;//赋予列对应的行之和
				   }
				   num++;
			       num1=0;
			}//end  for 
		    num=1;
		    minvalue=maxcols[1][1];
		    for(i=0;i<maxnum;i++)
			{  //z找出行中1的最小值
		       if(minvalue>maxcols[num][1])
		     	 	minvalue=maxcols[num][1];
               num++;
			} 
	    	 num=1;
		     for(i=0;i<maxnum;i++)
			 { 
		       if(minvalue==maxcols[num][1])
			   { 
			      maxcol=maxcols[num][0];//得到此时的列号
			      break;
			   } 
		       num++;
			 } 
		}  //end else  if(maxnum>1)
		// 删除maxcol所在的列和列值为1的行
		for(i=0;i<rows;i++)
		    if(matrix[i][maxcol]==1)
			{		
                countrows[i]=0;//行标志为0,该行删除了
				for(j=0;j<cols;j++)
					matrix[i][j]=-1;// 该行每个元素设为-1
			}
		for(i=0;i<rows;i++)
		   matrix[i][maxcol]=-1;//该列每个元素设为-1       
	   countcols[maxcol]=0;//列标志标为0
 	   cuts[0]++;//断点数目加一
	   cuts[cuts[0]]=maxcol;//记录此时断点对应的列
	   for(i=0;i<cols;i++)
		 if(countcols[i]!=0)//改列还没有删除
			 {//统计剩下各列1的数目
				 countcols[i]=0;
				 for(j=0;j<rows;j++)
				   if(matrix[j][i]==1)
					 countcols[i]++;
	//统计此时该列中'1'的个数,如大于1,说明还有为一的元素,否则说明该列为全零
				   //元素,下次计算断点的样列对数目时可以不考虑
			 }
		for(i=0;i<rows;i++)//对每一行
			if(countrows[i]!=0)//改行还没有删除
			{//统计剩下的行
				countrows[i]=0;//行标设为0,重新统计
				for(j=0;j<cols;j++)//列
					if(matrix[i][j]==1)
						countrows[i]++;//重新统计该行'1'的个数
			}
		remains=0;
		for(i=0;i<rows;i++)
		  if(countrows[i]!=0)
			  remains+=countrows[i];
		  //统计未处理的矩阵元素个数'1'的个数,如果大于1则说明矩阵不为空
	}//while(remains>0);//当矩阵为0矩阵时退出
	if(countrows!=NULL)
		delete[] countrows;
	if(countcols!=NULL)
		delete[] countcols;	
	for(i=0;i<rows;i++)
		delete[] matrix[i];
	delete[] matrix;	
	for(i=0;i<cols;i++)
		delete[] maxcols[i];
	if(maxcols!=NULL)
		delete[] maxcols;
	get_cut(cuts);//得到最终的断点集
}

void CDisFour::OnDisFourSave(LPCTSTR lpszPathName)
{//保存离散化后的结果
	int i,j;
	fstream fpw;
	fpw.open(lpszPathName,ios::out);
	if(!fpw)
	{
		::MessageBeep(MB_ICONHAND);
		AfxMessageBox("some error happen, file can't be opend!",
		MB_OK|MB_ICONSTOP);
        exit(0);
	}
	fpw<<"Style:"<<"train"<<endl;
	fpw<<"Stage:2"<<endl;
    fpw<<"Condition attributes number:"<<iAttNum<<endl;
    fpw<<"Records number:"<<iRecordNum<<endl;
	for(i = 0;i < iAttNum+1;i++)
		fpw<<pAttName[i]<<" ";
	fpw<<endl;
	for(i = 0;i < iAttNum+1;i++)
		fpw<<pDataType[i]<<" ";
	fpw<<endl;

    int strIndex=0,nonStrIndex=0;
    for(i=0;i<iRecordNum;i++)
	{ 
        for(j=0;j< iAttNum;j++)
		{ 
            if(!strcmp(pDataType[j],"String"))
			     fpw<<pStringTableResult[i][strIndex++]<<"   "; 
            else
                fpw<<NewTable[i][nonStrIndex++]<<"  "; 
		} 
        fpw<<NewTable[i][nonStrIndex];//决策属性 
        strIndex=0,nonStrIndex=0; 
        fpw<<endl; 
    } 
  fpw<<"[Cuts]"<<endl;//写断点	
    strIndex=0,nonStrIndex=0; 
    for(i=0;i<iAttNum;i++){ 
        fpw<<i<<endl; 
        if(!strcmp(pDataType[i],"String")){ 
            fpw<<strCuts[strIndex]<<endl;   //断点个数 
            for(j=0;j<strCuts[strIndex];j++){ 
                fpw<<pStrResult[j][strIndex]<<" "<<j<<endl; 
				//断点与离散值对应关系 
            } 
            strIndex++; 
        } 
        else{ 
            fpw<<cut[nonStrIndex][0]+1<<endl;   //断点个数 
            fpw<<"["<<"*"<<","; 
            for(j=0;j<(int)cut[nonStrIndex][0];j++){ 
                fpw<<cut[nonStrIndex][j+1]<<")"<<"  "<<j<<endl; 
                fpw<<"["<<cut[nonStrIndex][j+1]<<","; 
            } 
            fpw<<"*"<<"]"<<" "<<j; 
            fpw<<endl; 
            nonStrIndex++; 
        } 
    } 
    fpw.close();
}

⌨️ 快捷键说明

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