日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Apriori算法的實現

作者:Joyce_Joe 更新時間: 2022-09-22 編程語言

Apriori使用一種稱作逐層搜索的迭代方法,k項集用于探索(k+1)項集。?首先,通過掃描數據庫,累計每個項的計數,并收集滿足最小支持度的項,找出頻繁1項集的集合。該集合記作L1。然后,L1用于找頻繁2項集的集合L2,L2用于找L3,如此下去直到不能再找到頻繁k項集。找每個Lk需要一次數據庫全掃描。

Apriori定律1 :如果某商品組合小于最小支持度,則就將它舍去,它的超集必然不是頻繁項集。
Apriori定律2 :如果一個集合是頻繁項集,即這個商品組合支持度大于最小支持度,則它的所有子集都是頻繁

數據庫有5個事務。設min_sup=60%,min_conf=80%

TID

購買的商品

T100

{M,O,N,K,E,Y}

T200

{D,O,N,K,E,Y}

T300

{M,A,K,E}

T400

{M,U,C,K,Y}

T500

{C,O,O,K,I,E}

在程序中,使用Apriori算法,找出頻繁項集

步驟:

  1. 每個項都是候選1項集的集合C1的成員。算法掃描所有的事務,獲得每個項,生成C1(見下文代碼中的create_C1函數)。然后對每個項進行計數。然后根據最小支持度從C1中刪除不滿足的項,從而獲得頻繁1項集L1。
  2. 對L1的自身連接生成的集合執行剪枝策略產生候選2項集的集合C2,然后,掃描所有事務,對C2中每個項進行計數。同樣的,根據最小支持度從C2中刪除不滿足的項,從而獲得頻繁2項集L2。
  3. 對L2的自身連接生成的集合執行剪枝策略產生候選3項集的集合C3,然后,掃描所有事務,對C3每個項進行計數。同樣的,根據最小支持度從C3中刪除不滿足的項,從而獲得頻繁3項集L3。
  4. 以此類推,對Lk-1的自身連接生成的集合執行剪枝策略產生候選k項集Ck,然后,掃描所有事務,對Ck中的每個項進行計數。然后根據最小支持度從Ck中刪除不滿足的項,從而獲得頻繁k項集。

?

 vc代碼:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#define D 5 /*D數事務的個數*/
#define MinSupCount 3 /*最小事務支持度數*/
void main()
{
char a[5][6] = {
	{ 'M','O','N','K','E','Y' },
	{ 'D','O','N','K','E','Y' },
	{ 'M','A','K','E' },
	{ 'M','U','C','K','Y'},
	{ 'C','O','O','K','I','E' }
	};
char b[20], d[100], t, b2[100][10], b21[100][10];//b用來保存數據庫中的元素
int i, j, k, x = 0, flag = 1, c[20] = { 0 }, x1 = 0, i1 = 0, j1, counter = 0, c1[100] = { 0 }, flag1 = 1, j2, u = 0, c2[100] = { 0 }, n[20], v = 1;
int count[100], temp;
for (i = 0; i<D; i++)
{
	for (j = 0; a[i][j] != '\0'; j++)
	{
/*這個循環是用來判斷之前保存的是否和a[i][j]一樣,不一樣就保存,一樣就不保存*/
		for (k = 0; k<x; k++)
		{
			if (b[k] != a[i][j]);//b[k]是已存儲的項,已存儲的項不等于現在存儲的,意味著有新元素。
			else
			{
				flag = 0; break;
			}
		}
		/*這個if是用來判斷是否相等*/
		if (flag == 1)
		{
			b[x] = a[i][j];
			x++;
		}
		else flag = 1;/*這個不保存,那就跳到下一個數*/
	}
}
//數組b用于存放元素,即x就是元素種類的個數
/*計算篩選出的元素的支持度計數*/
for (i = 0; i<D; i++)
{
	for (j = 0; a[i][j] != '\0'; j++)
	{
		for (k = 0; k<x; k++)/*這個x是上面b數組中元素個數,用b數組和a[i][j]數組中的每一行和每一列進行比較,用來記錄b數組每一個元素的支持度計數*/
		{
			if (a[i][j] == b[k])
			{
				c[k]++; break;
			}
		}
	}
}
//數組c用于存放每個元素的支持度計數
for (k = 0; k<x; k++)
	{
		if (c[k] >= MinSupCount)
		{
			d[x1] = b[k];
			count[x1] = c[k];
			x1++;//L1中元素的個數
		}
	}
//數組D即為L1
/*對選出的項集中的元素進行排序*/
for (i = 0; i<x1 - 1; i++)
{
	for (j = 0; j<x1 - i - 1; j++)
	{
		if (d[j]>d[j + 1])
		{
		t = d[j]; d[j] = d[j + 1]; d[j + 1] = t;
		temp = count[j]; count[j] = count[j + 1]; 		count[j + 1] = temp;
		}
	}
}
/*打印出L1*/
printf("L1 elements are:\n");
for (i = 0; i<x1; i++)
{
	printf("{%c} = %d  ", d[i], count[i]);
}
printf("\n");

/*計算事務的項的個數,并且保存到n[]數組中*/
for (i = 0; i<D; i++)
{
for (j = 0; a[i][j] != '\0'; j++);
n[i] = j;
}
//數組n表示各事務中的元素個數
/*對a[][]數組的每一行進行排序*///對本例沒影響,因為已經排好了序
for (i = 0; i<D; i++)
{
	for (j = 0; j<n[i] - 1; j++)
	{
		for (k = 0; k<n[i] - j - 1; k++)
		{
			if (a[i][k]>a[i][k + 1])
			{
			t = a[i][k];
			a[i][k] = a[i][k + 1];
			a[i][k + 1] = t;
			}
		}
	}
}
/*把L1中的每一個元素都放在b2[i][0]中*/
j1 = x1;//j1初始設置為L1中元素的個數。
for (i = 0; i<j1; i++)
{
b2[i][0] = d[i];
}
/*把L1中的元素進行組合,K=2開始,表示x1個元素選K個元素的組合(x1是頻繁一項集個數)*/
for (k = 2; b2[0][0] != '\0'; k++) 
{   /*u是用來計數候選集中的組合總數的*/
	u = 0; v = 1;/*v 是用來在進行輸出各種組合的標識數 v=1 說明正在進行輸出*/
	for (i = 0; i<100; i++)
	{
	c2[i] = 0;//頻繁項集Lk中元素的支持度計數
	}
	for (i = 0; i<j1; i++)//j1是Lk-1中的集合個數,初始為L1中的集合個數x1
	{
		for (i1 = i + 1; i1<j1; i1++)
		{

			for (j = 0; j<k - 2; j++)
			{
			//k-2之前只要有不同的,說明不能鏈接,標記flag1為0
				if (b2[i][j] != b2[i1][j])
				{
					flag1 = 0; break;
				}

			}
/*進行組合的部分*/
if (flag1 == 1 && b2[i][k - 2] != b2[i1][k - 2])//可以鏈接并且最后一個元素不相等
{
	for (j2 = 0; j2<k - 1; j2++)
	{
		b21[u][j2] = b2[i][j2];   //k-1個元素保持不變
	}
		b21[u][k - 1] = b2[i1][k - 2]; //第k個元素加上不同的那個
		u++;
	}
	flag1 = 1;
	}
}
//b21為候選集
counter = 0;//候選k項集中的元素在某個事務中出現的次數
for (i = 0; i<D; i++)/*找候選項集Ck中滿足支持度計數的*///掃描D
{
	for (i1 = 0; i1<u; i1++)/*U=Ck中所有組合總數*/
	{
		for (j1 = 0; j1<k; j1++)/*K 代表一個組合中的元素個數*/
		{
			for (j = 0; a[i][j] != '\0'; j++)/*逐個比較每一行的元素*/
			{
				if (b21[i1][j1] == a[i][j])
				{
				counter++;
				break;
				}
			}
		}
    	if (counter == k) 
           c2[i1]++;  
/*把候選集是事務的子集的計數記錄在c2數組中(只要滿足有k個元素在某個事務中,則計數加1)*/
counter = 0;
	}
}
j1 = 0; temp = 0;/*這里的temp 是用來分行*/
 /*對u種情況進行選擇,選出支持度計數大于2的*/
//j1對Lk中的集合個數計數,每次在輸出前重置。
for (i = 0; i<u; i++)
{
 	if (c2[i] >= MinSupCount)
	{
		if (v == 1)
	{
		printf("L%d elements are:\n", k);
		v = 0;
	}
	printf("{");
	for (j = 0; j<k; j++)/*輸出每種組合k 個元素*/
	{
		b2[j1][j] = b21[i][j];
		printf("%c,", b2[j1][j]);
	}
		j1++; //Lk計數加1
		printf("\b}");
		printf(" = %d  ", c2[i]);
		if (0 == (temp + 1) % 3) //printf("\n");
		temp++;
	}
}

b2[j1][0] = '\0';//j1是Lk中的集合個數
if (b2[0][0] != '\0') 
printf("\b \n");
}
	system("pause");
}

原文鏈接:https://blog.csdn.net/Joyce_Joe/article/details/126980496

相關推薦

欄目分類
最近更新