www.pudn.com > apriori的vc源代码.zip > association.cpp


// CAssociationRule.cpp: implementation of the CAssociationRule class. 
// 
////////////////////////////////////////////////////////////////////// 
#include "stdafx.h" 
#include  
#include  
#include  
 
#include "Association.h" 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CAssociationRule::CAssociationRule() 
{ 
    m_minConfidence = 0.90; 
    m_numRules = 0; 
	 
    m_LargeItemSets = (List *)NULL; 
	 
    m_Rules = (ARRuleSetNode *)NULL; 
}; 
 
CAssociationRule::~CAssociationRule() 
{ 
    ARRuleSetNode *rn, *temp; 
 
    rn = m_Rules; 
    while(rn != (ARRuleSetNode *)NULL) 
    { 
        temp = rn->next; 
        if(rn->m_premise != NULL) 
            delete rn->m_premise; 
 
        if(rn->m_consequence != NULL) 
            delete rn->m_consequence; 
 
        delete rn; 
        rn = temp; 
    } 
 
}; 
 
 
 
void CAssociationRule::genrules() 
{ 
    itemSet *current; 
     
    for(int i = 0; i < m_LargeItemSets->size(); i++) 
    { 
        current = (itemSet *)m_LargeItemSets->get(i); 
        if(current->size() > 1) 
            ruler(current, current); 
 
//        delete current; 
    } 
     
    return; 
} 
 
void CAssociationRule::ruler(itemSet *Lk, itemSet *Am) 
{ 
    itemSet *current; 
    itemSet *Aminusone; 
    int pos; 
    double conf; 
    long necConfidence; 
 
 
    for(int i = 0; i < Am->size(); i++) 
    { 
        current = (itemSet *)Am->clone(); 
        current->remove(i); 
 
        pos = m_LargeItemSets->indexOf(current); 
        if(pos >= 0) 
        { 
            Aminusone = (itemSet *)m_LargeItemSets->get(pos); 
 
            conf = ((double)(Lk->support()))/(double)(Aminusone->support()); 
            necConfidence = (long)(m_minConfidence*(double)(Aminusone->support()) + 0.5); 
 
            if(necConfidence <= Lk->support()) 
            { 
                add(Lk, Aminusone, conf); 
 
                if(Aminusone->size() > 1) 
                    ruler(Lk, Aminusone); 
            } 
 
//            delete Aminusone; 
        } 
 
        delete current; 
    } 
 
    return; 
} 
 
 
void CAssociationRule::add(itemSet *Lk, itemSet *Aminusone, double confidence) 
{ 
    itemSet *rightitems; 
    ARRuleSetNode *newRule; 
    ARRuleSetNode *browser; 
 
    rightitems = Lk->substract(Aminusone); 
 
    browser = m_Rules; 
    while(browser != (ARRuleSetNode *)NULL) 
    { 
        if((browser->m_premise->compare(Aminusone) == TOTALEQUAL) && (browser->m_consequence->compare(rightitems) == TOTALEQUAL)) 
        { 
            delete rightitems; 
            return; 
        } 
 
        browser = browser->next; 
    } 
 
    newRule = (ARRuleSetNode *) new ARRuleSetNode(); 
 
    newRule->m_premise = (itemSet *)Aminusone->clone(); 
    newRule->m_consequence = (itemSet *)rightitems->clone(); 
 
    newRule->m_confidence = confidence; 
    newRule->m_support = Lk->support(); 
 
    newRule->next = m_Rules; 
    m_Rules = newRule; 
 
    m_numRules++; 
 
    return; 
} 
 
 
void CAssociationRule::save(const char *filename) 
{ 
    ARRuleSetNode *currentRule; 
    FILE *fp; 
	int i; 
	itemSet *pitem; 
 
    fp = fopen(filename,"wt"); 
 
    /* 
	fprintf(fp, "Large Item Sets ...\n\n\n"); 
	for(i = 0; i < m_LargeItemSets->size(); i++) 
	{ 
		pitem = (itemSet *)m_LargeItemSets->get(i); 
		for(int j = 0; j < pitem->size(); j++) 
			fprintf(fp, "%d ", pitem->get(j)); 
		fprintf(fp, "\n"); 
	} 
	fprintf(fp, "\n\n\n"); 
    */ 
 
    currentRule = m_Rules; 
    while(currentRule != (ARRuleSetNode *)NULL) 
    { 
        /* 
        fprintf(fp, "%f %f\n", currentRule->m_confidence, currentRule->m_support); 
		fprintf(fp, "%d", currentRule->m_premise->size()); 
        */ 
                 
        for(i = 0; i < currentRule->m_premise->size(); i++) 
            fprintf(fp, " %d", currentRule->m_premise->get(i)); 
        fprintf(fp, "  ---> "); 
 
        /* 
		fprintf(fp, "%d", currentRule->m_consequence->size()); 
        */ 
                 
        for(i = 0; i < currentRule->m_consequence->size(); i++) 
            fprintf(fp, " %d", currentRule->m_consequence->get(i)); 
        fprintf(fp, "\n"); 
		 
        currentRule = currentRule->next; 
    } 
 
	fflush(fp); 
	fclose(fp); 
 
    return; 
} 
 
 
void CAssociationRule::load(const char *filename) 
{ 
    ARRuleSetNode *currentRule; 
	double support, confidence; 
	int count, pageno; 
    FILE *fp; 
	int i; 
 
	printf("Loading Association Rules from %s ... ", filename); 
	fflush(stdout); 
	 
    fp = fopen(filename,"rt"); 
	while( !feof(fp) ) 
	{ 
	    currentRule = (ARRuleSetNode *)new ARRuleSetNode(); 
		 
        fscanf(fp, "%f %f\n", &confidence, &support); 
		 
        currentRule->m_confidence = confidence; 
        currentRule->m_support = support; 
		 
		fscanf(fp, "%d", &count); 
		currentRule->m_premise = (itemSet *)new itemSet(); 
        for(i = 0; i < count; i++) 
		{ 
            fscanf(fp, " %d", &pageno); 
			currentRule->m_premise->add(pageno); 
		} 
        fscanf(fp, "\n"); 
 
 
		fscanf(fp, "%d", &count); 
		currentRule->m_consequence = (itemSet *)new itemSet(); 
        for(i = 0; i < count; i++) 
		{ 
            fscanf(fp, " %d", &pageno); 
			currentRule->m_consequence->add(pageno); 
		} 
        fscanf(fp, "\n"); 
		 
		currentRule->next = m_Rules; 
		m_Rules = currentRule; 
    } 
 
	printf(" Finish!"); 
	fflush(stdout); 
	 
    return; 
} 
 
// Generate recommendations based on observed session 
itemSet * CAssociationRule::genRecommendations(itemSet *observed_session, int NumberofTopPages) 
{ 
    ARRuleSetNode *browser; 
    TopRule *topRules; 
    int i, j, pos, pagenum; 
	double pweight; 
    itemSet *result; 
 
	pagenum = NumberofTopPages; 
	 
    topRules = (TopRule *)new TopRule[pagenum]; 
    for(i = 0; i < pagenum; i++) 
    { 
        topRules[i].prule = NULL; 
        topRules[i].m_similarity = 0.0; 
    } 
 
    browser = m_Rules; 
    while(browser != (ARRuleSetNode *)NULL) 
    { 
		pweight = calSimilarity(browser->m_premise, observed_session); 
		 
		for(pos = 0; pos < pagenum; pos++) 
		{ 
			if(pweight > topRules[pos].m_similarity) 
				break; 
		} 
		if(pos < pagenum) 
		{ 
			for(j = pagenum-2; j >= pos; j--) 
			{ 
				topRules[j+1].prule = topRules[j].prule; 
				topRules[j+1].m_similarity = topRules[j].m_similarity; 
			} 
			topRules[pos].prule = browser; 
			topRules[pos].m_similarity = pweight; 
		} 
		 
        browser = browser->next; 
    } 
 
	result = (itemSet *)new itemSet(); 
	result->keeporder(false); 
    for(i = 0; i < pagenum; i++) 
    { 
		if(topRules[i].prule != NULL) 
			for(j = 0; j < topRules[i].prule->m_consequence->size(); j++) 
				result->add(topRules[i].prule->m_consequence->get(j)); 
    } 
 
	delete topRules; 
	if(result->size() == 0) 
	{ 
		delete result; 
		result = (itemSet *)NULL; 
	} 
	 
	return result;	 
} 
 
 
// Calculate the contribution of trace to observed_session 
double CAssociationRule::calSimilarity(itemSet *trace, itemSet *observed_session) 
{ 
    int i, observed_page, numIntersection; 
	itemSet *itrace, *isession, *iunion; 
	double score; 
	 
	itrace = (itemSet *)new itemSet(); 
	itrace->keeporder(false); 
	for(i = 0; i < trace->size(); i++) 
		itrace->add(trace->get(i)); 
	 
	isession = (itemSet *)new itemSet(); 
	isession->keeporder(false); 
	for(i = 0; i < observed_session->size(); i++) 
		isession->add(observed_session->get(i)); 
	 
	iunion = (itemSet *)new itemSet(); 
	iunion->keeporder(false); 
	for(i = 0; i < trace->size(); i++) 
		iunion->add(trace->get(i)); 
	for(i = 0; i < observed_session->size(); i++) 
		iunion->add(observed_session->get(i)); 
	 
    numIntersection = 0; 
	for(i = 0; i < isession->size(); i++) 
	{ 
		observed_page = observed_session->get(i); 
		if(itrace->indexOf(observed_page) != -1) 
			numIntersection++; 
	} 
 
	if(numIntersection == trace->size()) 
		score = 1.0; 
	else 
		score = (double)numIntersection / (double)iunion->size(); 
	 
	delete itrace; 
	delete isession; 
	delete iunion; 
	 
	return(score); 
}