📄 skowron.cpp
字号:
{
if(pHead->iColumn == j)
break;//找到i样例j属性值对应的断点信息
pHead = pHead->p;
}//end while
if(pHead != NULL)//拷贝断点信息
strcpy(pStringTable[i][j],pHead->cpCut[pIntTable[i][j]]);
}//end for
}//end for
}
BOOL CSkowron::SkowronArithmetic()
{//算法主程序
int i,j;
/*
struct Object
{
int m_iSerial; //序号
int* m_pRec; //记录表(包括决策值)
int count; //重复个数
Object* p; //指向结构Object的指针
};
*/
Object* pHead=NULL;
Object* pHead1=NULL;
float precision = 0;
float rule_precision = 0;
int total = 0;
int max = 0;
float sum = 0;
int* tempobject=NULL;
int* tempclass=NULL;
int conflict_num = 0;//冲突数目
float min =0;
if(!InitTable())
return FALSE;
if(!FindConflict())
return FALSE;
tempobject = new int[iClassNum];
tempclass = new int[iClassNum];
i = 0;
pHead = pSheet;
while(pHead != NULL)
{
tempobject[i] = pHead->count;//当前样例的重复个数
pHead = pHead->p;//下一个样例
i++;//说明到了哪个样例
}
for(i = 0;i < iClassNum;i++)
tempclass[i] = 0;
for(i = 0;i < iClassNum;i++)
{
max = 0;
total = 0;
if(tempclass[i] == 1)//样例未分析
continue;
if(piConflict[i] == -1)
{//样本i无冲突
sum += tempobject[i];//统计无冲突样例个数
tempclass[i] = 1;//样例已经分析过
}
else
{
total = total + tempobject[i];//统计和i样例冲突样例个数
conflict_num += tempobject[i];//统计总共的冲突数
if(tempobject[i] > max)
max = tempobject[i];//记录冲突样例的最大重复数
tempclass[i] = 1;//已分析
j = i;
while(piConflict[j] > j)//piConflict[j]为和j冲突的样例序号
{//冲突样例 冲突样例都按照递增方式增长,最后一条指向开头
j = piConflict[j];//下一条样例
total = total + tempobject[j];
conflict_num += tempobject[j];
if(tempobject[j] > max)
max = tempobject[j];
tempclass[j] = 1;
}
sum += max;//只记录一致样本和冲突样本中最大重复数
if(min == 0)
min = (float)max/total;//设为冲突样本最大重复数和总数之比
if(min > (float)max/total)
min = (float)max/total;//求取最小值
}//end else
}//end for(i)
precision = sum / iRecordNum;//得到精度
delete[] tempobject;
delete[] tempclass;
pHead = pSheet;
if(!CreateMatrix())
return FALSE;
m_pDefaultrules = NULL;
m_pTempDefault = m_pDefaultrules;
m_pBlockrules = NULL;
m_pTempBlock = m_pBlockrules;
serial = 0;
block = 0;
m_Cuttree = NULL;
///设置阀值
CAlpha dlg;
dlg.m_iAlpha=0.5;
if(T)
{
if(dlg.DoModal()==IDOK)
fAlpha=dlg.m_iAlpha;
else
return false;
}
Projection(pMatrix,piConflict,0,NULL);
while(m_Cuttree != NULL)
{
m_Cuttree1 = m_Cuttree->p;
delete[] m_Cuttree->cut;
delete m_Cuttree;
m_Cuttree = m_Cuttree1;
}
while(pHead != NULL)
{//析构pSheet
pHead1 = pHead->p;
delete[] pHead->m_pRec;
delete pHead;
pHead = pHead1;
}
return TRUE;
}
void CSkowron::DefaultRule(CSkowron::Cell* m_pRecord,CSkowron::Point* m_pPoint,bool T)
{//cell:矩阵中的每一格 Point:表示属性组合 m_pRecord为可辨识矩阵中的一行
int j;
int same = 0;
Point* temp_point=NULL;
Defaultline* temphead = NULL;
Defaultline* tempend=NULL;
Cell* m_pTemp = NULL;
Rules* m_pRulestemp = NULL;
Rules* m_pRulestemp1 = NULL;
//如果递归的层数大于以前的规则的个数,则不再递归
if(callnum > rulenum)//callnum初始为0;rulenum为iclassnum
{ //析构所有
//temp_point = m_pPoint;
//m_pPoint = m_pPoint->p;
delete m_pPoint;
if(m_pRecord!=NULL)
{
for(int i= 0;i < iMatrixLine;i++)
delete[] m_pRecord[i].m_p ;
delete[] m_pRecord;
m_pRecord=NULL;
}
return;
}
for(int i = 0;i < iMatrixLine;i++)
{//目的在于判断是否存在差异属性
if(m_pRecord[i].nattribute != 0)//nattribute:不同的属性值个数
break;//退出时得到第一个有差异属性的列i
}
if(i == iMatrixLine)
{//说明m_pRecord所代表的矩阵行没有差异属性,此时产生默认规则,返回
if(m_pPoint==NULL)
return;
int* ruletemp = new int[iAttNum];
for(j = 0;j < iAttNum;j++)
ruletemp[j] = 0;
temp_point = m_pPoint;//temp_point指向该属性单元
while(m_pPoint != NULL)
{
ruletemp[m_pPoint->attribute-1] = 1;//给规则中m_pPoint->attribute-1对应属性赋值为一
m_pPoint = m_pPoint->p;
}
delete temp_point;
m_pRulestemp = m_pRules;
while(m_pRulestemp != NULL)
{
for(j = 0;j < iAttNum;j++)
if(m_pRulestemp->rule[j]==ruletemp[j] ||
m_pRulestemp->rule[j]==0&&ruletemp[j]==1)
continue;
else
break;
if(j == iAttNum)
{//说明规则相等或者是m_pRules中包含ruletemp
same=1;
break;//end while
}
m_pRulestemp1 = m_pRulestemp;
m_pRulestemp = m_pRulestemp->p;
}
if(same == 0)
{//不相等,为新规则分配空间,产生规则
m_pRulestemp = new Rules;
m_pRulestemp->rule = new int[iAttNum];
m_pRulestemp->p = NULL;
for(j = 0;j < iAttNum;j++)
m_pRulestemp->rule[j] = ruletemp[j];
if(m_pRules==NULL)
m_pRules=m_pRulestemp;
else m_pRules->p = m_pRulestemp;//m_pRulestemp指向下一条规则,此时为空
}
if(T)
rulenum = callnum;//规则数目等于callnum
delete[] ruletemp;
if(m_pRecord!=NULL)
{
for(int i= 0;i < iMatrixLine;i++)
delete[] m_pRecord[i].m_p ;
delete[] m_pRecord;
m_pRecord=NULL;
}
//delete m_pPoint;
return;//返回
}
callnum++;//递归的层数加一
//初始化temp数组
//Attnum* temp = NULL;
/*
struct Defaultline//缺省(值)行
{
Attnum* line;
Defaultline* p;
}tempend;
struct Attnum
{
int attribute;
int num;
};
*/
tempend = NULL;//插入节点在头部
tempend = new Defaultline;
tempend->line = new Attnum[iAttNum];
tempend->p = temphead;//加到头部,初始时temphead为空
temphead = tempend;
//计算m_pRecord中各属性的个数,并且从大到小排序
int n1;
int n2 = 0;
for(i = 0;i < iAttNum;i++)
{//统计各个属性区别样例的作用
n1 = 0;
for(j = 0;j < iMatrixLine;j++)
{
if(m_pRecord[j].nattribute == 0)
continue;
if(m_pRecord[j].m_p[i] == 1)
n1++;//标记i属性区别在区别样例中出现的次数
}
temphead->line[i].attribute = i+1;//加入属性 比实际多一
temphead->line[i].num = n1;//属性i总共出现的次数
}
Attnum temp1;
for(i = 0;i < iAttNum-1;i++)
{//对属性出现次数从大到小排序
//if(temp[i].num == 0)
// break;
for(j = i+1;j < iAttNum;j++)
{
//if(temp[j].num == 0)
// break;
if(temphead->line[j].num > temphead->line[i].num)
{//j大于i,交换i,j 从大到小排列
temp1 = temphead->line[i];
temphead->line[i] = temphead->line[j];
temphead->line[j] = temp1;
}
}
}
int num=0;//统计一下不为空的属性集合的个数
bool T1=false;//true:存在唯一区分属性集合的单一属性;false:不存在
for(i=0;i<iMatrixLine;i++)
if(m_pRecord[i].nattribute!=0)
num++;
for(i=0;i<iAttNum;i++)
if(temphead->line[i].num==num)//出现次数为非空集合个数
for(j=0;j<iMatrixLine;j++)//扫描该行,看是否为核属性,即为单元素集合
{
if(m_pRecord[j].nattribute == 0)//该列属性集合为空,继续,到下一个属性集合
continue;
if(m_pRecord[j].m_p[temphead->line[0].attribute-1] == 1
&& m_pRecord[j].nattribute==1)//j列出现该属性且差异属性集合中的属性个数为1
{
T1=true;//存在此单一属性
break;
}
}
//依次从m_ptemp中取出属性,然后将它放入m_pRules中,
//将包含此属性的属性组合从m_pTemp中除去,递归调用
//DefaultRule函数
if(T1)
{//存在此单一属性
m_pTemp = new Cell[iMatrixLine];//cell:矩阵中的一格
for(j = 0;j < iMatrixLine;j++)
{//得到m_pRecord的拷贝m_pTemp
m_pTemp[j].nattribute = m_pRecord[j].nattribute ;
m_pTemp[j].serial = m_pRecord[j].serial ;
m_pTemp[j].m_p=new int[iAttNum];
for(int k=0;k<iAttNum;k++)
m_pTemp[j].m_p[k] = m_pRecord[j].m_p[k] ;
}
Point* temp_point = NULL;//表示属性组合
temp_point = new Point;//temp_point为当前i属性节点
temp_point->p = m_pPoint;
temp_point->attribute = temphead->line[0].attribute;//属性
for(j = 0;j < iMatrixLine;j++)
{
if(m_pTemp[j].nattribute == 0)//该列属性集合为空,继续,到下一个属性集合
continue;
if(m_pTemp[j].m_p[temphead->line[0].attribute-1] == 1)//j的第i个属性出现次数为一
{
m_pTemp[j].nattribute = 0;//相当于出去一个属性后,包含该属性的属性集合就设为0
}
}
DefaultRule(m_pTemp,temp_point,T1);//递归调用自身
}
else
for(i = 0;i < iAttNum;i++)
{
if(temphead->line[i].num == 0)
break;//结束.后面的不用比较了
// if(temphead->line[i].num != temphead->line[0].num)
// break;
m_pTemp = new Cell[iMatrixLine];//cell:矩阵中的一格
for(j = 0;j < iMatrixLine;j++)
{//得到m_pRecord的拷贝m_pTemp
m_pTemp[j].nattribute = m_pRecord[j].nattribute ;
m_pTemp[j].serial = m_pRecord[j].serial ;
m_pTemp[j].m_p=new int[iAttNum];
for(int k=0;k<iAttNum;k++)
m_pTemp[j].m_p[k] = m_pRecord[j].m_p[k] ;
}
Point* temp_point = NULL;//表示属性组合
temp_point = new Point;//temp_point为当前i属性节点
temp_point->p = m_pPoint;
temp_point->attribute = temphead->line[i].attribute;//当前属性
for(j = 0;j < iMatrixLine;j++)//列j
{
if(m_pTemp[j].nattribute == 0)//该列属性集合为空,继续,到下一个属性集合
continue;
if(m_pTemp[j].m_p[temphead->line[i].attribute-1] == 1)//j的第i个属性出现
{
m_pTemp[j].nattribute = 0;//相当于出去一个属性后,包含该属性的属性集合就设为0
//对j中其他属性,对应的在其他属性集合中去掉
} //end if
}//end for(j)
DefaultRule(m_pTemp,temp_point,T1);//递归调用自身 m_pTemp为属性集合中去掉temphead->line[i].attribute后得到的一行差异属性集合
}
if(m_pPoint != NULL)//析构
delete m_pPoint;
tempend = temphead;
temphead = temphead->p;//temphead移到下一个规则位置
delete[] tempend->line;
delete tempend;
callnum--;//递归的层数减一 ?
if(m_pRecord!=NULL)
{
for(int i= 0;i < iMatrixLine;i++)
delete[] m_pRecord[i].m_p ;
delete[] m_pRecord;
m_pRecord=NULL;
}
return;
}
void CSkowron::RulesJudge(int n,int cut,int* m_pCut,int* m_Conflict)
{//得到最后的规则,看当前规则的有效性,构造封锁事实 n:规则的序号 >0
//cut为零时不产生封锁事实. n为规则行号
m_pd1 = NULL;//都为Defaultrules类型
m_pd2 = NULL;
m_pd3 = NULL;
m_pb1 = NULL;
m_pb2 = NULL;
m_pb3 = NULL;
if(n<1 || m_pRules==NULL)
return;
Defaultrules* m_pd4=NULL;
/*struct Defaultrules //最终的规则
{
int serial; //规则的序号
int* rule; //规则的属性值和决策值
float reliability; //可信度
int totalnum; //总样本数
int coveragenum; //覆盖的样本数
Defaultrules* p;
}; */
int i;
int serial1;
Object* m_TempObject = NULL;
/* struct Object
{
int m_iSerial; //序号
int* m_pRec; //记录表(包括决策值)
int count; //重复个数
Object* p; //指向结构Object的指针
}; */
m_TempObject = pSheet;//决策表pSheet
Rules* m_pr1 = m_pRules;//m_pr1指向此次决策表第n行产生的规则集合
if(m_Conflict[n-1] == 0)//记录n-1不冲突
{
while(m_TempObject != NULL)
{
if(m_TempObject->m_iSerial == n)
{//再记录表中找到序号为n的产生规则.此时m_TempObject指向该记录
while(m_pr1 != NULL)//初始时为空,
{
m_pd2 = new Defaultrules;
m_pd2->serial = ++serial;
m_pd2->rule = new int[iAttNum+1];
for(i = 0;i < iAttNum;i++)
{
if(m_pr1->rule[i] == 1)
{
m_pd2->rule[i] = m_TempObject->m_pRec[i];
}
else
m_pd2->rule[i] = -1;
}
m_pd2->rule[iAttNum] = m_TempObject->m_pRec[iAttNum];//决策
compute_totalnum_coveragenum(m_pr1,n,m_pd2);//计算m_pd2的总样本数和覆盖的样本数
// m_pd2->totalnum = m_TempObject->count;//总样本数
// m_pd2->coveragenum = m_TempObject->count;//覆盖的样本数
m_pd2->reliability = m_pd2->coveragenum/m_pd2->totalnum;//可信度
m_pd2->p = NULL;
int j = 0;
if(m_pd2->reliability <fAlpha)
j=1;
m_pd4 = m_pDefaultrules;//指向规则指针头
while(m_pd4 != NULL && j==0)
{
for(i=0;i<iAttNum+1;i++)
{//比较规则的属性值和决策值 找到第一个不同的属性
if(m_pd2->rule[i] != m_pd4->rule[i])
break;
}
if(i == iAttNum+1)//没有不一样的属性
j = 1;
m_pd4 = m_pd4->p;//下一条规则
}
if(j == 1)
{//m_pd2重复,删除
delete[] m_pd2->rule;
delete m_pd2;
serial--;
}
else
{//指向下一条规则 修改m_pd1,m_pd2,m_pd3
if(m_pd1 == NULL)
m_pd1 = m_pd2;
else
m_pd3->p = m_pd2;
m_pd3 = m_pd2;
m_pd2 = m_pd2->p;
}
m_pr1 = m_pr1->p;
}//end while(m_pr1!=NULL)
break;
}//end if(m_TempObject->m_iserial==n)
m_TempObject = m_TempObject->p;
}//end while(m_TempObject!=NULL)
while(m_pRules != NULL)
{//释放m_pRules空间
m_pr1 = m_pRules->p;
delete[] m_pRules->rule;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -