?? aprioriset.cpp
字號:
#include "stdAfx.h"
#include ".\aprioriset.h"
using namespace win32::gui;
CAprioriSet::CAprioriSet(int _itemCount, double _itemSupp)
{
itemCount = _itemCount;
freq = _itemSupp * itemCount;
//initialization database access
con.connect ( DB_NAME, HOST, USER, PASSWD );
Query query = con.query();
query<<"select * from AprioriDB";
res = query.store();
}
CAprioriSet::~CAprioriSet(void)
{
con.close();
}
//************************************************************
//*
//* 功能: 查找1-頻繁項集
//*
//************************************************************
void CAprioriSet::FindlargeItem(void)
{
int count = 0;
string strInit;
string strValue;
// 初始化候選項目集——從I1到I9
for( int initCount = 0; initCount < itemCount ; initCount++ )
{
strInit = "I" + boost::lexical_cast<std::string>( initCount+1 );
candlargeItem[0][initCount] = strInit;
}
// 遍歷訪問數(shù)據(jù),獲取項集
Result::iterator it;
for ( it = res.begin() ; it != res.end(); ++it )
{
// 獲取當前列的值
Row row(*it);
strValue = row[1];
//strValue = it->lookup_by_name( res.field_name(i).c_str() ); //效率較低,似乎無法獲得正確的值
// 統(tǒng)計1-頻繁項集的值
for(int j = 0; j < itemCount; j++)
if ( npos != strValue.find( candlargeItem[0][j]) )
candFreqCount[0][j]++;
}
// 生成1-頻繁項集
for ( int i = 0; i < itemCount; i++)
{
if ( candFreqCount[0][i] > freq )
{
freqGroup.push_back( make_tuple( 0, candlargeItem[0][i], candFreqCount[0][i] ) );
largeItem[0][count] = candlargeItem[0][i];
freqCount[0][count] = candFreqCount[0][i];
count++;
}
}
candlargeItemCount.push_back(count);
largeItemCount.push_back(count);
}
//************************************************************
//*
//* 功能: 生成k(k>1)-頻繁項集
//*
//************************************************************
void CAprioriSet::GenfreqItem(int level)
{
string strValue;
int count = 0;
// 以下為求頻繁項目集
int k = level;
for(int i = 0; i < candlargeItemCount[k]; i++)
{
if ( candFreqCount[k][i] > freq )
{
freqGroup.push_back ( make_tuple( k, candlargeItem[k][i], candFreqCount[k][i] ) );
largeItem[k][count] = candlargeItem[k][i];
freqCount[k][count] = candFreqCount[k][i];
count++;
}
}
// 復制頻繁項目個數(shù)
largeItemCount.push_back(count);
}
//********************************************************************
//*
//* 功能: 剪枝函數(shù), 對已生成的候選項集檢測其所有k-1組合是否存在
//*
//********************************************************************
bool CAprioriSet::Prune( int level, string& strCandFreqItem, vector<bool> itemFlag )
{
int pos;
vector<string> strFreqItem;
string strSubTemp;
// 以,為間隔符取得字符串中的各項
tokenItem ( strFreqItem, strCandFreqItem );
pos = strFreqItem.size() - 2;
while( pos-- >= 0 )
{
strSubTemp.clear();
strSubTemp = next_combination( strFreqItem, pos );
// 如果下一個k-1組合存在于C(k-1)中,則返回true
for( int i = 0; i < largeItemCount[level-1]; i++ )
{
if ( npos == largeItem[level-1][i].find( strSubTemp ) )
{
return false;
}
else {
itemFlag[i] = true;
}
}
}
return true;
}
//************************************************************
//*
//* 功能: 由L(k-1)生成C(k)
//*
//************************************************************
void CAprioriSet::AprioriGen( int level )
{
string strTemp;
int levelCount = 0;
vector<bool> candLargeItemFlag( largeItemCount[level-1], false );
// 如果兩個L(k-1)項,前k-2都相同,只是最后一項不同,且前一項小于后一項
// 則生成C(k),并剪枝
for(int i = 0; i < largeItemCount[level-1]; i++)
{
string strTemp1 = largeItem[ level-1 ][i];
for(int j = i + 1; j < largeItemCount[level-1]; j++)
{
// 如果此項為前面某k項組合中的k-1子項,則必不符合下述條件
if( candLargeItemFlag[j] ){
candLargeItemFlag[j] = false;
continue;
}
string strTemp2 = largeItem[ level-1 ][j];
// 檢查兩個L(k-1)項,是否只有最后一項不同,且符合條件
pair<string::iterator, string::iterator> result =
mismatch( strTemp1.begin(), strTemp1.end(), strTemp2.begin());
if ( result.first == strTemp1.end()-1 && *(result.first) < *(result.second) )
{
strTemp = strTemp1 + ",I" + *(result.second);
if( level == 1 || Prune( level, strTemp, candLargeItemFlag ) )
{
candlargeItem[level][levelCount++] = strTemp;
}
}
}
}
candlargeItemCount.push_back(levelCount);
}
//************************************************************
//*
//* 功能: 獲取頻繁項集,返回給view
//*
//************************************************************
vector<ItemType> CAprioriSet::getFreqItem()
{
Result::iterator it;
string strValue;
vector<string> strVec;
FindlargeItem();
for( int k = 1; largeItemCount[k-1] > k-1; k++ )
{
AprioriGen(k);
// 統(tǒng)計各項集頻繁度
for ( it = res.begin(); it != res.end(); it++ )
{
Row row(*it);
strValue = row[1];
for ( int i = 0; i < candlargeItemCount[k]; i++)
{
tokenItem( strVec, candlargeItem[k][i] );
if ( search( strVec, strValue) )
{
candFreqCount[k][i]++;
}
}
}
// 生成頻繁項集
GenfreqItem(k);
}
return freqGroup;
}
//************************************************************
//*
//* 功能: 以','為間隔符抽取字符串中的單項目,返回矢量
//*
//************************************************************
vector<string>& CAprioriSet::tokenItem(vector<string>& strVec, string& text)
{
strVec.clear();
string::const_iterator begin = text.begin(), end = text.end();
boost::regex re("\\s*,\\s*", regex::optimize);
boost::sregex_token_iterator token( begin, end, re, -1 );
boost::sregex_token_iterator seeker;
while ( token != seeker )
strVec.push_back( *token++ );
return strVec;
}
//************************************************************
//*
//* 功能: 生成L(k-1)的下一個組合
//*
//************************************************************
string& CAprioriSet::next_combination( vector<string>& kItem, int vecPos )
{
vector<string> next = kItem;
string str;
// 用排除法求k-1組合
vector<string>::iterator it;
vector<string>::iterator new_end = remove( next.begin(), next.end(), kItem[ vecPos - 1 ] );
next.erase( new_end, next.end() );
for( it = kItem.begin(); it != kItem.end()-1; it++ )
str += *it + ",";
str += *it;
return str;
}
//************************************************************
//*
//* 功能: 查找候選項集在在數(shù)據(jù)集中的匹配
//*
//************************************************************
bool CAprioriSet::search(vector<string>& src, string& text)
{
vector<string>::iterator it;
for( it = src.begin(); it != src.end(); it++ )
{
if ( npos == text.find(*it) )
return false;
}
return true;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -