📄 mibark.cpp
字号:
// MIBARK.cpp: implementation of the CMIBARK class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RSet.h"
#include "MIBARK.h"
#include"math.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAX 100
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMIBARK::CMIBARK()
{
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;
}
CMIBARK::~CMIBARK()
{
FreeContent();
}
bool CMIBARK::InitTable()//输入离散后的初始化决策表
{ //将决策表值从pIntTable复制到info中
int i,j;
rec_num = iRecordNum;//记录对象数
con_num = iAttNum;//条件属性数
if((info=new int *[rec_num])==0) //原始表,以转化为int 指针
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return false;
}
for (i=0;i<rec_num;i++)
if((info[i]=new int [con_num+1])==0)
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return false;
}
for (i=0;i<rec_num;i++)
for (j=0;j<con_num+1;j++)
info[i][j] = pIntTable[i][j];
return true;
}
void CMIBARK::GetData(char* FileName)//get the privilege pInformation from the file given.
{
FILE* fp;
if((fp = fopen(FileName,"r")) == NULL)
{
AfxMessageBox("打开文件失败!",MB_ICONSTOP|MB_OK);
return;
}
// cStyle= new char[100];
fscanf(fp,"Style:%s\n",cStyle);
fscanf(fp,"Stage:%d\n",&iStage);
//return if not the result of the discrete
//if ((stricmp(cStyle,"train")!=0)||(iStage!=2))
//{
// printf("The unfit data set!\n");
// return;
// }
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);//读入决策表
SetCutResult(fp);//读入断点
fclose(fp);
return;
}
int CMIBARK::Create_Table()//初步简化决策表,删除多余的行
{ // return :success:1 false: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)
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return 0;
}
int same_num=0;
//把重复记录编号存在same_rec中,same_num中为重复记录数目
for(i=0;i<rec_num-1;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_rec[same_num++]=j;//same_num指相同的条件属性的个数
}
find=FALSE;
sum=0;
}//浏览整个决策表
//如果有重复记录,采取的措施
if(same_num>0)
{
//为新表分配空间
if((infoset=new int * [rec_num-same_num])==0)//新的决策表代码
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return 0;
}
for(i=0;i<(rec_num-same_num);i++)
{
if((infoset[i]=new int[con_num+1])==0)
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return 0;
}
}
for(i=0;i<rec_num;i++)
{
for(j=0;j<same_num;j++)
if(i==same_rec[j])
break;
else
sum++;
//说明第i条记录不在same_rec中
if(sum==same_num)
{
for(j=0;j<con_num+1;j++)
{
infoset[new_rec_num][j]=info[i][j];
}
new_rec_num++;
}
sum=0;
}
for(i=0;i<rec_num;i++)
delete []info[i];
delete []info;
info=infoset;
rec_num-=same_num;//决策表中记录对象数减少
}
delete []same_rec;
return 1;
}
int CMIBARK:: Create_Array()//建立可辩识矩阵
{//不成功返回为0,成功返回为1
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)
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return 0;
}
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])
{ //把不相等的条件属性记录下来,放在att中。att
for(k=0;k<con_num;k++)
{
if(info[i][k]!=info[j][k])
{
att[++m]=k;
}
if(m>1)//m初始化为0 最多只记录两个不一致属性
break;
}
att[0]=m;
m=0;
for(l=0;l<element;l++)
{
if(array[l][0]==att[0])
{
for(n=1;n<=att[0];n++)
if(array[l][n]==att[n])
num++;
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 CMIBARK::Reduct_Table() //计算结果属性组合 //根据互信息选择最终的属性集
{ //success:true wrong:false
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)//全局熵的计算指针
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return false;
}
if((reductset=new int[con_num+1])&&(attreductset= new int[con_num+1])&&
(resultset= new int[con_num+1])==0)
{ //*计算核属性 con_num =7 rec_num=89 是
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return false;
}
decreductset= new int[2];
attreductsetxu=new int[2];
attreductsetxu[0]=1;//计算单个条件熵
reductset[0]=0;
attreductset[0]=0;
//找出核属性
for(i=0;i<element;i++)//element:可辩识(决策)矩阵中的元素个数
if(array[i][0]==1)
{//将核属性加入
reductset[++redu_att_num]=array[i][1];
reductset[0]=redu_att_num;
}
//找出非核属性
for(k=0;k<con_num;k++)
{
for(j=1;j<=redu_att_num;j++)
{
if(k!=reductset[j])
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;
for(i=1;i<=result_num;i++)
{
resultset[i]=reductset[i];
}
for(i=1;i<=con_num;i++)
{
attallreductset[i]=i-1;
}
////////全集条件熵的计算
H_DR_ALL=Entropy(decreductset,1, attallreductset,con_num);
if(H_DR_ALL==-1)
return false;
/////计算单属性的条件熵/////
double *H_DR;
if((H_DR=new double[con_num+1])==0)
{
AfxMessageBox("分配内存失败!",MB_ICONSTOP|MB_OK);
return false;
}
double H_D;
////////////决策属性D的墒熵值///////////
H_D=EntropyDec(decreductset,1);
if(H_D==-1)
return false;
//////定义互信息变量/////////////
//条件属性数con_num
double *Inf=new double[con_num+2];//Inf为互信息
//////////C与D的互信息
Inf[0]=H_D-H_DR_ALL;//C与D的互信息
//////核属性与D的互信息
if(result_num!=0)
{
H_DR[0]=Entropy(decreductset,1, resultset,result_num);//已经得到
if(H_DR[0]==-1)
return false;
Inf[1]=H_D-H_DR[0];//first attribute's
}
////比较互信息的大小///
while(Inf[1]<Inf[0])
//for(j=0;j<redu_num;j++)
{
if(result_num==0)//约简结果属性个数为零
{
for(i=1;i<=con_num;i++)
{
attreductsetxu[1]=attreductset[i];//取一个非核属性
H_DR[i]=Entropy(decreductset,1, attreductsetxu,1);//计算信息熵
if(H_DR[i]==-1)
return false;
Inf[i+1]=H_D-H_DR[i];//得到单个属性的互信息 from 2,3,4...
}
double t=Inf[2];
int m,temp=-1;
for(i=1;i<=con_num;i++)
{ //找出最大的互信息的元数
if(t<Inf[i+1])
{
t=Inf[i+1];
H_DR[0]=H_DR[i];//放在H_DR[0]中
}
}
for(i=1;i<=con_num;i++)
{ //将此属性加入CORE(C)
if(t==Inf[i+1])
{
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(t==Inf[i+1]
}
resultset[result_num+1]=attreductset[m];//i;
///////////换号码///////////////
if(m!=con_num-result_num)
{//con_num-result_num得到剩下的非约简的属性数目
//con_num为条件属性数,m不在最后
int k;
for(i=m;i<con_num-result_num;i++)
{
k=attreductset[i+1];
attreductset[i]=k;
}
}
result_num++;
Inf[1]=t;//核属性的互信息
//resultset[1]=i-2;//核属性的号码
}//end 核属性等于零
else
if(Inf[0]!=Inf[1])//核属性不为零
{
// temp=-1;//初始化
H_DR[0]=Entropy(decreductset,1, resultset,result_num);//H(D|R);
if(H_DR[0]==-1)
return false;
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;
Inf[i+1]=H_DR[0]-H_DR[i];//算出了互信息的大小。
}
double t=Inf[2];
int m,temp=-1;//m是最大互信息的属性顺序数
for(i=1;i<=con_num-result_num;i++)
{
if(t<Inf[i+1])//////找出最大 的互信息的元数
{
t=Inf[i+1];
H_DR[0]=H_DR[i];
}
}
for(int ii=1;ii<=con_num-result_num;ii++)
if(t==Inf[ii+1])
{
// resultset[result_num+1]=attreductset[i];//为最大的互信息的属性号码数
// m=i;
if(temp==-1)
{//first time
m=ii;
temp=ii;
}
else
{//有两个属性同时具有最大的互信息,计算得到属性值组合数最小的属性
resultset[result_num+1]=attreductset[m];
IND(resultset,result_num+1,rec_num);
int m1=IND_Order;//属性组合数m1
resultset[result_num+1]=attreductset[ii];
IND(resultset,result_num+1,rec_num);
int m2=IND_Order;//属性组合数m2
if(m1>m2)
m=ii;
}
}//end if(t=Inf(i+1)
resultset[result_num+1]=attreductset[m];//为最大的互信息的属性号码数
///////////换号码///////////////
if(m!=con_num-result_num)//如果m在非核属性的末尾,则不需要移位
{
// int k;
for(i=m;i<con_num-result_num;i++)
{//向前移一位
attreductset[i]=attreductset[i+1];
// k=attreductset[i+1];
// attreductset[i+1]=attreductset[i+2];
// attreductset[i]=k;
}
}
result_num++;
Inf[1]=t+Inf[1]; //(H(D|B)-H(D|B+{p}))+(H(D)-H(D|B))=H(D)-H(D|B+{p})=H(D|B+{p})
if(result_num==redu_num)
break;
}//end else
}//end while
//约简结果
resultset[0]=result_num;//约简得到的最终属性集合
reduct_num=1;
result=new int * [1];
// result[0]=new int[redu_att_num+1];//redu_att_num为核属性数目
result[0]=new int[result_num+1];//将上面一行修改为此行
result[0][0]=result_num;
for(i=0;i<result_num;i++)
result[0][i+1]=resultset[i+1];
SelectSort(result[0]);
//用选择法对约简后的属性重新排列,对数组att中的元素按从小到大排序
/////////////////////////////
delete []reductset; //核条件属性集
delete []attreductset; //非核条件属性集
delete []decreductset;//决策属性集
delete []resultset;//约简结果集
delete []attallreductset;
delete []attreductsetxu;
delete []Inf;//互信息数组
delete []H_DR;
return true;
}
bool CMIBARK::SetAttName(FILE* fp, int 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 CMIBARK::SetDataType(FILE *fp, int count)
{
int i;
if((pDataType = new char*[count])==0)
return false;
for(i = 0;i < count;i++)
{
if((pDataType[i]=new char[20])==0)
return false;
}//end for
for(i = 0;i < count;i++)
fscanf(fp,"%s",pDataType[i]);
return true;
}
bool CMIBARK::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -