📄 reduct1.cpp
字号:
// Reduct1.cpp: implementation of the CReduct1 class.
//
//////////////////////////////////////////////////////////////////////
/*======================================================
filename :reduct1.cpp
一般属性约简实现文件
作者: 李鄂
创建时间: 2000/12
------------------------------------------------------*/
#include "stdafx.h"
#include "Reduct1.h"
#include "fstream.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CReduct1::CReduct1()
{
}
CReduct1::~CReduct1()
{
}
bool CReduct1::InitTable(CString infotable)
{
TRACE(" Kylin CReduct1::InitTable;\n");
if(!CTable::InitTable(infotable))
{
TRACE("initialize error!\n");
return false;
}
deleteDup();
return true ;
}
void CReduct1::ComputeOriPF()
{ //计算初始的正域
ClassifyDev();//根据决策表中的信息得到决策类集合class_dev
CSet<CSet<int> > tempset;
ClassifyAttr(tempset);//根据决策表中的信息得到条件类集合,保存在tempset中
PosField=computePF(tempset,class_dev);
//根据条件类class_attr和决策类class_dev计算并返回正域
#ifdef _DEBUG
CSet<int>::outset(PosField);
#endif //_DEBUG
}
bool CReduct1::ClassifyDev(void)
{//根据决策表中的信息得到决策类集合class_dev
int& n=m_nConAttrNum; //devision attribute column
int *cls;//clk[k]表示了决策分类号,即该记录属于哪个决策类
try
{
cls=new int[m_nCount];
}
catch(CMemoryException * e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return 0;
}
int count=0;
bool flag=true;
for (int i=0;i<m_nCount;i++)
{//对每个样例
if(!m_bObj[i])
{//记录已经被删掉,不需要分类了
cls[i]=-1;
continue;
}
for(int k=0;k<i;k++)
{//看i样例是否属于其前面的样例的决策分类集合
if(m_Record[i][n]==m_Record[k][n])//决策相同
{//加入决策分类
cls[i]=cls[k];
flag=false;
break;
}
}
if(flag) { cls[i]=count++;}//开辟新的决策类,count标记类号
flag=true;
}
//k表示了记录的编号,cls[k]表示它属
//于第几个决策类,class_dev表示决策类的集合
for(int k=0;k<m_nCount;k++)
{//加入决策类
// TRACE("%d,",cls[k]);
CSet<int>::AddEleToSubSet(class_dev,k,cls[k]);
}
// TRACE("\n");
// TRACE("devision classification:\n");
#ifdef _DEBUG
CSet<int>::outset(class_dev);
TRACE("\n");
#endif
delete[] cls;
return true;
}
bool CReduct1::ClassifyAttr(CSet<CSet<int> >& tempset)
{ //根据决策表中的信息得到条件类集合,保存在tempset中
int& n=m_nConAttrNum; //devision attribute column
int *cls;
try
{
cls=new int[m_nCount];
}
catch(CMemoryException * e)
{
TRACE("classify attr :memory error!\n");
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return false;
}
int count=0;
bool flag=true;
for (int i=0;i<m_nCount;i++)
{
if(!m_bObj[i])//被删除
{
cls[i]=-1;
continue;
}
for(int k=0;k<i;k++)
{
if(CompObj(i,k))
{//比较条件属性,全部相等返回为true,否则为false
cls[i]=cls[k];
flag=false;
break;
}
}
if(flag) { cls[i]=count++;}//count为等价类的序号
flag=true;
}
for(int k=0;k<m_nCount;k++)
{
if(m_bObj[k])
CSet<int>::AddEleToSubSet(tempset,k,cls[k]);
}
// TRACE("\n");
// TRACE("attribute classification:\n");
// outputset(tempset);
// TRACE("\n");
delete []cls;
return true;
}
CSet<int> CReduct1::computePF(CSet<CSet<int> >& class_attr,CSet<CSet<int> >& class_dev)
{//计算条件集合划分class_attr的正域
CSet<int> posfield;
setNode<CSet<int> > * p=class_attr.getHead();//条件分类集合头部
setNode<CSet<int> > * temp;
while(p)
{
temp=class_dev.getHead();
while(temp)
{//对决策分类中的每个集合
if(p->element.BelongTo(temp->element))
{//某个条件分类包含于决策分类中
posfield+=p->element;//条件分类加入正域中
break;
}
temp=class_dev.getNext(temp);//下一个决策分类集合
}
p=class_attr.getNext(p);//下一个条件分类集合
}
return posfield;//正域
}
bool CReduct1::reduct()
{//约简主算法
TRACE(" Kylin CReduct1::reduct;\n");
// double duration;
// CString str;
// clock_t finish ,start;
//start = clock();
ComputeOriPF();//计算初始正域
int i_leftAttNum=0;//记录剩下的条件属性数目
for(int i=0;i<m_nConAttrNum;i++)
{//对每个属性尝试删除 m_bObj[i]为false表示删除了的重复样例
m_bAttr[i]=FALSE;//表示删除了i属性
CSet<CSet<int> > tempset;
ClassifyAttr(tempset);//计算条件分类集合
if(computePF(tempset,class_dev)==PosField)
{
i_leftAttNum++;
if(i_leftAttNum==m_nConAttrNum)
m_bAttr[i]=TRUE;
// deleteDup();//合并重复的行,因为PosField没有重新计算,所以如果这里合并重复行的话势必
//造成条件属性划分的减小,从而带来正域的增大,使能约简的属性数目减小。
// TRACE("%d can be reduced\n",i);
// continue;
}
else m_bAttr[i]=TRUE;
}
TRACE("recudt finished ,it's ");
for(i=0;i<m_nConAttrNum;i++)
if(m_bAttr[i])
TRACE("%d,",i);
// finish = clock();
// duration = (double)(finish - start) / CLOCKS_PER_SEC;
// str.Format (" 约简运行时间:%f 秒",
//duration);
// AfxMessageBox(str);
return true;
}
bool CReduct1::WriteFile(CString name)
{
// TRACE(" Kylin CReduct1::WriteFile;\n");
deleteDup();
return CTable::WriteFile(name);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -