📄 disfour.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 + -