AprioriView.cpp
上传用户:zscyanite
上传日期:2022-07-25
资源大小:4947k
文件大小:12k
开发平台:

Visual C++

  1. // AprioriView.cpp : implementation of the CAprioriView class
  2. //
  3. #include "stdafx.h"
  4. #include "Apriori.h"
  5. #include "AprioriSet.h"
  6. #include "AprioriDoc.h"
  7. #include "AprioriView.h"
  8. #include "GetData.h"
  9. #include "time.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CAprioriView
  17. IMPLEMENT_DYNCREATE(CAprioriView, CRecordView)
  18. BEGIN_MESSAGE_MAP(CAprioriView, CRecordView)
  19. //{{AFX_MSG_MAP(CAprioriView)
  20. ON_BN_CLICKED(IDC_FREQBN, OnFreqBn)
  21. ON_COMMAND(ID_GETDATA, OnGetData)
  22. ON_BN_CLICKED(IDC_RULEBN, OnRuleBn)
  23. //}}AFX_MSG_MAP
  24. // Standard printing commands
  25. ON_COMMAND(ID_FILE_PRINT, CRecordView::OnFilePrint)
  26. ON_COMMAND(ID_FILE_PRINT_DIRECT, CRecordView::OnFilePrint)
  27. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRecordView::OnFilePrintPreview)
  28. END_MESSAGE_MAP()
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CAprioriView construction/destruction
  31. CAprioriView::CAprioriView()
  32. : CRecordView(CAprioriView::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAprioriView)
  35. // NOTE: the ClassWizard will add member initialization here
  36. m_pSet = NULL;
  37. //}}AFX_DATA_INIT
  38. // TODO: add construction code here
  39. }
  40. CAprioriView::~CAprioriView()
  41. {
  42. }
  43. void CAprioriView::DoDataExchange(CDataExchange* pDX)
  44. {
  45. CRecordView::DoDataExchange(pDX);
  46. //{{AFX_DATA_MAP(CAprioriView)
  47. DDX_Control(pDX, IDC_RULELIST, m_rlist);
  48. DDX_Control(pDX, IDC_LIST1, m_list);
  49. //}}AFX_DATA_MAP
  50. }
  51. BOOL CAprioriView::PreCreateWindow(CREATESTRUCT& cs)
  52. {
  53. // TODO: Modify the Window class or styles here by modifying
  54. //  the CREATESTRUCT cs
  55. return CRecordView::PreCreateWindow(cs);
  56. }
  57. void CAprioriView::OnInitialUpdate()
  58. {
  59. m_pSet = &GetDocument()->m_aprioriSet;
  60. CRecordView::OnInitialUpdate();
  61. GetParentFrame()->RecalcLayout();
  62. ResizeParentToFit();
  63. }
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CAprioriView printing
  66. BOOL CAprioriView::OnPreparePrinting(CPrintInfo* pInfo)
  67. {
  68. // default preparation
  69. return DoPreparePrinting(pInfo);
  70. }
  71. void CAprioriView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  72. {
  73. // TODO: add extra initialization before printing
  74. }
  75. void CAprioriView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  76. {
  77. // TODO: add cleanup after printing
  78. }
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CAprioriView diagnostics
  81. #ifdef _DEBUG
  82. void CAprioriView::AssertValid() const
  83. {
  84. CRecordView::AssertValid();
  85. }
  86. void CAprioriView::Dump(CDumpContext& dc) const
  87. {
  88. CRecordView::Dump(dc);
  89. }
  90. CAprioriDoc* CAprioriView::GetDocument() // non-debug version is inline
  91. {
  92. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAprioriDoc)));
  93. return (CAprioriDoc*)m_pDocument;
  94. }
  95. #endif //_DEBUG
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CAprioriView database support
  98. CRecordset* CAprioriView::OnGetRecordset()
  99. {
  100. return m_pSet;
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. // CAprioriView message handlers
  104. void CAprioriView::OnFreqBn() 
  105. {
  106. // TODO: Add your control notification handler code here
  107. CString strValue[MaxSize];
  108. clock_t start,stop;
  109. double timeused;
  110. int flag=0;
  111. if (ItemCount<=0)
  112. {
  113. MessageBox("请先进行参数设置",NULL,MB_OK);
  114.     return;
  115. }
  116.     start=clock();
  117. FindLargeItem();
  118. for(int k=1;LargeItemCount[k-1]!=0;k++)
  119. {    
  120.      
  121.      AprioriGen(k);
  122. for(int mm=0;mm<CandLargeItemCount[k];mm++)
  123. {
  124. nCountCand[mm]=0;
  125. }
  126.         
  127. //统计计数
  128. for(int j=0;j<CandLargeItemCount[k];j++)
  129. {
  130. for(int j1=0;j1<nDbItemCount;j1++)
  131. {   
  132. for(int j2=0;j2<DbItemCount[j1];j2++)
  133. {
  134. if(CandLargeItem[k][j].Find(DbItem[j1][j2])!=-1) 
  135. {  flag++; }
  136. }
  137. if(flag==k+1)
  138. {
  139.      nCountCand[j]++;
  140.      flag=0;
  141. }
  142. flag=0;
  143. }
  144. }
  145.      ShowFreqItem(k);
  146.  
  147. }
  148. ncount=k-1;
  149. //CString msg1;
  150. //msg1.Format("%d",ncount);
  151. //AfxMessageBox(msg1);
  152. m_list.InsertString(0,"频繁项目集:n");
  153. stop=clock();
  154. timeused=(double)(stop-start)/CLK_TCK;
  155. CString msg;
  156. msg.Format("运行程序所用时间为:%5.7f秒",timeused);
  157. AfxMessageBox(msg);
  158. }
  159. void CAprioriView::FindLargeItem()
  160. {
  161. int nFieldCount=m_pSet->GetODBCFieldCount();
  162. int nCount=0;
  163. int nFreqItem[100];
  164.     int nDbCount=0;
  165. CString str;
  166. CString strValue;
  167. CString strIntToString;
  168.   // 初始化候选项目集
  169.     for(int i=0;i<ItemCount;i++)
  170. {   
  171. str="";
  172. str.Format("%s%d",str,i+1); 
  173. CandLargeItem[0][i]='I'+str;
  174. }
  175. //初始化数组
  176. for(int ii=0;ii<ItemCount;ii++)
  177. nFreqItem[ii]=0;
  178. m_pSet->MoveFirst ();
  179. while(!m_pSet->IsEOF())
  180. {
  181. for(int j=1;j<nFieldCount;j++){
  182. m_pSet->GetFieldValue(j,strValue);
  183.            SubItemGen(nDbCount++ ,strValue);
  184. for(int i=0;i<ItemCount;i++)
  185. if(strValue.Find(CandLargeItem[0][i])!=-1)
  186. nFreqItem[i]++;
  187. }
  188. m_pSet->MoveNext();
  189. }
  190. nDbItemCount=nDbCount;
  191.     for(int i1=0;i1<ItemCount;i1++)
  192.    if(double(nFreqItem[i1])/double(nDbItemCount)>=ItemSupp)
  193. {  
  194.    CString str; 
  195.    LargeItem[0][nCount]=CandLargeItem[0][i1];
  196.    str.Format("%s%20d",LargeItem[0][nCount],nFreqItem[i1]);
  197.    m_list.InsertString(nCount,str);
  198.    NLargeItemCount[0][nCount]=nFreqItem[i1];
  199.    nCount++;
  200. }
  201. }
  202. LargeItemCount[0]=nCount;
  203. }
  204. void CAprioriView::OnGetData() 
  205. {
  206. // TODO: Add your command handler code here
  207. CGetData dlg;
  208. dlg.m_itemcount=10;
  209. dlg.m_itemsupp=0.2;
  210. dlg.m_itemconf=0.7;
  211. int ren=dlg.DoModal();
  212. ItemCount=dlg.m_itemcount;
  213. ItemSupp=dlg.m_itemsupp;
  214. ItemConf=dlg.m_itemconf;
  215. }
  216. void CAprioriView::SubItemGen(int strSubItemCount/*表示第几个事物*/,CString strSubItem
  217.   /*表示第几个事物的具体内容如:I1,I2*/)
  218. {//对每个事务分解成单个项目,并存储到数组 DbItem[][]中去
  219. CString strTemp;
  220. int nSubItemCount;
  221. int nstrTemp;
  222. strTemp=strSubItem;
  223. nSubItemCount=0;//用于统计所有的单个项目的个数
  224. while((nstrTemp=strTemp.Find(','))!=-1)
  225. {
  226. DbItem[strSubItemCount][nSubItemCount++]=strTemp.Left(nstrTemp);
  227. strTemp=strTemp.Mid(nstrTemp+1);
  228. }
  229.     DbItem[strSubItemCount][nSubItemCount++]=strTemp;
  230. DbItemCount[strSubItemCount]=nSubItemCount;
  231.     
  232. }
  233. bool CAprioriView::Prune( int level, CString strCandFreqItem)
  234. {
  235. CString strTemp,str;
  236. int flag=0,nstrTemp;
  237. int nSubItemCount=0,nFreqCount=0;//存放单个项目的个数
  238.     strTemp=strCandFreqItem;
  239. CString strSubTemp[MaxSize];//存放分解出来的单个项目
  240. CString strFreqItem[MaxSize];//存放k阶的子集
  241.     while((nstrTemp=strTemp.Find(','))!=-1)
  242. {
  243. strSubTemp[nSubItemCount++]=strTemp.Left(nstrTemp);
  244. strTemp=strTemp.Mid(nstrTemp+1);
  245. }
  246.     strSubTemp[nSubItemCount++]=strTemp;
  247.     for(int i=0;i<nSubItemCount;i++)
  248. {   str="";
  249.     if(nSubItemCount<=2)
  250. {
  251. strFreqItem[nFreqCount++]=strSubTemp[i];
  252. }
  253. else{
  254. for(int j=i+1;j<nSubItemCount;j++)
  255. {   str=strSubTemp[i]+",";
  256.      if(level>1){
  257.      for(int k=j;k<j+level-1&&k<nSubItemCount;k++)
  258.     str=str+strSubTemp[k]+",";}
  259.      for(int m=j+level-1;m<nSubItemCount;m++)
  260. {
  261.      str=str+strSubTemp[m]+",";
  262. }
  263.      strFreqItem[nFreqCount++]=str.Left(str.GetLength()-1);
  264. }
  265. }
  266.     
  267.     for(int j=0;j<nFreqCount;j++)
  268. {
  269. for( int i = 0; i < LargeItemCount[level-1]; i++ )
  270. if (LargeItem[level-1][i].Find(strFreqItem[nFreqCount])!=-1 ) 
  271. flag++;
  272. }
  273. if(flag>0)return true;
  274. else return false;
  275. }
  276. void CAprioriView::AprioriGen( int level )
  277. {
  278. CString strTemp,strTemp1,strTemp2,strTemp11,strTemp22;
  279. int levelCount = 0;
  280. int n;
  281. // 如果两个L(k-1)项,前k-2都相同,只是最后一项不同,且前一项小于后一项
  282. // 则生成C(k),并剪枝
  283. if(level==1)
  284. {
  285. for(int i = 0; i < LargeItemCount[level-1]; i++)
  286. {
  287.        strTemp1 = LargeItem[ level-1 ][i];
  288. for(int j = i + 1; j < LargeItemCount[level-1]; j++)
  289. {
  290.  strTemp2 = LargeItem[ level-1 ][j];
  291. if ( strTemp1 < strTemp2)
  292. {
  293. strTemp = strTemp1 + "," + strTemp2;
  294. for(n=0;n<j;n++)
  295. if(strTemp==CandLargeItem[level][n]) continue;
  296.                 if(Prune(level,strTemp))
  297. CandLargeItem[level][levelCount++] = strTemp;
  298. }
  299. }
  300. }
  301. }
  302. else{
  303. for(int i = 0; i < LargeItemCount[level-1]; i++)
  304. {
  305. strTemp1 = LargeItem[ level-1 ][i];
  306. strTemp11=strTemp1.Left(strTemp1.GetLength()-3);
  307. for(int j = i + 1; j < LargeItemCount[level-1]; j++)
  308. {
  309.  strTemp2 = LargeItem[ level-1 ][j];
  310.              strTemp22=strTemp2.Left(strTemp2.GetLength()-3);
  311. if ( strTemp11 == strTemp22 &&strTemp1.Mid(strTemp1.GetLength()-2)
  312. < strTemp2.Mid(strTemp2.GetLength()-2))
  313. {
  314. strTemp = strTemp1 + "," + strTemp2.Mid(strTemp2.GetLength()-2);
  315. for(n=0;n<j;n++)
  316. if(strTemp==CandLargeItem[level][n]) continue;
  317.                 if(Prune(level,strTemp))
  318. CandLargeItem[level][levelCount++] = strTemp;
  319. }
  320. }
  321. }
  322. }
  323. CandLargeItemCount[level]=levelCount++;
  324. }
  325. void CAprioriView::ShowFreqItem(int nScanCount)
  326. {
  327. CString strIntToString="";
  328.     CString strValue;
  329. CString strjj3[2];
  330. CString str;
  331. int nLargeCount=-1;
  332. int nLargeItemCount=0;
  333. //以下为求频繁项目集
  334. int k;
  335. k=nScanCount;  
  336. m_list.InsertString(0,"-----------------------");
  337. for(int jj2=0;jj2<CandLargeItemCount[k];jj2++)
  338. {
  339. if(double(nCountCand[jj2])/double(nDbItemCount)>=ItemSupp)
  340. {
  341. LargeItem[k][nLargeItemCount++]=CandLargeItem[k][jj2];
  342. nLargeCount++;
  343. //nLargeItemCount[0][0]=4;
  344. NLargeItemCount[k][nLargeItemCount-1]=nCountCand[jj2];
  345. str.Format("%s%20d",LargeItem[k][nLargeItemCount-1],nCountCand[jj2]);
  346.     m_list.InsertString(nLargeCount,str);
  347. }
  348. }
  349.         //复制频繁项目个数
  350.   LargeItemCount[k]=nLargeItemCount;
  351. }
  352. void CAprioriView::OnRuleBn()
  353. // TODO: Add your control notification handler code here
  354. CString strSubTemp[MaxSize][MaxSize],strTemp,Rule[MaxSize][MaxSize]/*用于存放规则的左边部分*/;
  355. CString str,msg;
  356. int nstrTemp,nSubCount=0,count=-1,rcount=0,rrcount;
  357. clock_t start,stop;
  358. double timeused;
  359. start=clock();
  360. for(int i=0;i<LargeItemCount[ncount-1];i++)
  361. {     strTemp=LargeItem[ncount-1][i];  
  362.      while((nstrTemp=strTemp.Find(','))!=-1)
  363.  {
  364.      strSubTemp[i][nSubCount++]=strTemp.Left(nstrTemp);
  365.      strTemp=strTemp.Mid(nstrTemp+1);
  366. //AfxMessageBox(strSubTemp[i][nSubCount-1]);
  367.  }
  368.          strSubTemp[i][nSubCount++]=strTemp;
  369. // AfxMessageBox(strSubTemp[i][nSubCount-1]);
  370.  nSubCount=0;
  371.    }
  372. strTemp="";
  373. for(int n=0;n<LargeItemCount[ncount-1];n++)
  374. {
  375.      for(int k=1;k<ncount;k++)
  376.  {
  377. for(int ii=0;ii<ncount;ii++)
  378. {
  379. if(k==1){Rule[n][rcount++]=strSubTemp[n][ii];}
  380. else 
  381. {
  382. strTemp=strSubTemp[n][ii];
  383. if(k>2){
  384.              for(int kk=ii+1;kk<ii+k-1&&kk<ncount;kk++)
  385. {strTemp=strTemp+","+strSubTemp[n][kk]+",";
  386. //AfxMessageBox(strSubTemp[n][kk]);
  387. }
  388.                       for(int jj=kk;jj<ncount;jj++)
  389.   Rule[n][rcount++]=strTemp+","+strSubTemp[n][jj];
  390.  }
  391. else{
  392.     for(int jj=ii+1;jj<ncount;jj++)
  393. Rule[n][rcount++]=strTemp+","+strSubTemp[n][jj];}
  394. }
  395. }
  396. }
  397. rrcount=rcount;
  398. rcount=0;
  399. }
  400. for(int i1=0;i1<LargeItemCount[ncount-1];i1++)
  401. {
  402. for(int j1=0;j1<rrcount;j1++)
  403. {
  404.           for(int i2=0;i2<ncount;i2++)
  405.   for(int j2=0;j2<LargeItemCount[i2];j2++)
  406.   if(Rule[i1][j1]==LargeItem[i2][j2])
  407.   {    
  408.   if(double(NLargeItemCount[ncount-1][i1])/double(NLargeItemCount[i2][j2])>ItemConf)
  409.   {   str="";
  410.   for(int i3=0;i3<ncount;i3++)
  411.   { 
  412.    if(Rule[i1][j1].Find(strSubTemp[i1][i3])==-1)
  413.    {
  414.  str=str+strSubTemp[i1][i3]+",";
  415.    }
  416.   }
  417.   count++;
  418.   msg.Format("%s→%s",Rule[i1][j1],str.Left(str.GetLength()-1));
  419.                    m_rlist.InsertString(count,msg);
  420.   }
  421.   }
  422. }
  423. }
  424. stop=clock();
  425. timeused=(double)(stop-start)/CLK_TCK;
  426. msg.Format("生成关联规则所用时间为:%5.7f秒",timeused);
  427. AfxMessageBox(msg);
  428. }