最初TWInClose3算法20170214

来源:互联网 发布:增值税发票模拟软件 编辑:程序博客网 时间:2024/06/08 11:19
#include "function_c.h"int AequalC(unsigned long *C, unsigned long *A);void CtoD(unsigned long *D, unsigned long *C);void CCNtoD(unsigned long *D, unsigned long *C, unsigned long *CN);long long com_num = 0;long long conceptNum = 0;void InClose(unsigned long *B, unsigned long *A, unsigned long *AN, unsigned long start_ulong, int start_bit_j, int *start_ulongFlag, unsigned long **N, unsigned long ***N_stack);clock_t start, finish;void out_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD);char choice='y',sort_choice;int BisEmpty(unsigned long *D);unsigned long concept_temp[2000000];void MyTWconcepts(unsigned long*, long);int file_out_num = 0;int ANjtoCN(unsigned long *CN, unsigned long *AN, unsigned long *cols);void out_easy_TWconcepts(unsigned long *setD);void out_test_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD);int i_temp = 0;typedef struct {double start;double stop;} stopWatch;class CStopWatch {private:stopWatch timer;double frequency;double LIToSecs(double & L);public:CStopWatch();void startTimer();void stopTimer();double getElapsedTime();};int main(int argc, char ** argv){out_file = fopen("out_file.txt", "w");/* = 456654456464;printf("%d\t",sizeof(long long));printf("%d\t", sizeof(int));printf("com_num个数:%lld, ", com_num);printf("概念个数:%lld\n", conceptNum);*/system("color F0");read_file();printf("约简否?排序否(eg:y,y):");getchar();//读取上次输入余下的换行符????。。。scanf("%c,%c", &choice, &sort_choice);//少了取地址,数组才不用取地址。。。 且不可以scanf("%c\n", &choice);加回车。。。。create_context(); free(mybuf);//背景中32位每一位都有用,可是queue_Flag那块是为何可以用属性列的最后一位???????//现在可忽略背景的创建了,,,基本同自己的context,这儿只是单指针罢了。。。。//0-31context[row * anum_longSize+0], 32-63context[row * anum_longSize+1],,,...context[row * anum_longSize+anum_LongSize-1]//这种思想自己用过。。。。initialize_output();///WWWang排序背景。。。。。。。。。。。。/*if (sort_choice == 'y')sort_context();*/initialize_algorithm();//用于给cols赋值 cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系,并初始化输出即attributes[]unsigned long *A; unsigned long *AN; unsigned long *B; unsigned long *pA; int *start_ulongFlag;B = (unsigned long *)malloc(byte_anumLongSize + 2*byte_onumLongSize);  /* 分配一个概念占用的空间,包括内涵与外延 */A = B + anum_longSize;  /* 外延的起始位置 */AN = A + onum_longSize;memset(A, 0xFF, byte_onumLongSize);////有问题。。。要再去掉对象为空的那几个1。。。。memset(AN, 0xFF, byte_onumLongSize);for (int i = objects % (ARCHBIT + 1); i <ARCHBIT + 1; i++)//重要,确保A AN C CN多余的那几位全为0{A[onum_longSize-1] -= (BIT << i);//重要AN[onum_longSize - 1] -= (BIT << i);//重要}memset(B, 0, byte_anumLongSize);//WWWang位全置0start_ulongFlag = (int *)malloc(sizeof(int) * (attributes + 1) * attributes);unsigned long **N; unsigned long ***N_stack;N = (unsigned long **)malloc(sizeof(unsigned long *) * attributes);/* 存储指向算法中的queue_Flag(即新生成且重复的内涵D)的地址。所用空间在本函数之外分配,只有一次调用所需空间,一个属性对应一个地址,共计n个单元。上层调用的地址信息保存在N_stack中,在递归返回时通过N_stack恢复 */memset(N, 0, sizeof(unsigned long *) * attributes);N_stack = (unsigned long ***)malloc(sizeof(unsigned long **) * (attributes + 1) * attributes);/* 堆栈,用于递归返回时恢复N。逻辑结构域大小同starts。共有n+...+1=n(n+1)/2组,每组2个单元;第一单元存储 当前属性对应的N单元的地址,第二单元存储其值 */start = clock();InClose(B, A,AN,0, ARCHBIT, start_ulongFlag, N, N_stack);finish = clock();FILE *out_result;out_result = fopen("wwwResults.txt", "a");if (sort_choice == 'y'){printf("排序后:");fprintf(out_result, "排序后:");}else{printf("不排序:");fprintf(out_result, "不排序:");}if (choice == 'y'){printf("约简:");fprintf(out_result, "约简:");}else{printf("全部:");fprintf(out_result, "全部:");}printf("%s:%d*%d, ", fname, objects, attributes);printf("时间:%lf秒, ", (double)(finish - start) / CLOCKS_PER_SEC);printf("com_num个数:%lld, ", com_num);printf("概念个数:%lld\n", conceptNum);fprintf(out_result, "TWInClose: %s:%d*%d, ", fname, objects, attributes);fprintf(out_result, "时间:%lf秒, ", (double)(finish - start) / CLOCKS_PER_SEC);fprintf(out_result, "com_num个数:%lld, ", com_num);fprintf(out_result, "概念个数:%lld\n", conceptNum);fclose(out_result);fclose(out_file);system("pause");return 0;}/*请输入文件名:cdat_lung-cancer.dat约简否?排序否(eg:y,y):y,ysupp:10supp:100supp:1000supp:10000supp:100000supp:200000supp:300000supp:400000supp:500000supp:600000supp:700000supp:800000supp:900000supp:1000000supp:1100000!!!:概念格式:(({0,1,2,3},{0,1,2,3}),{})排序后:约简:cdat_lung-cancer.dat:32*162, 时间:10.115000秒, com_num个数:3127560, 概念个数:1120807请按任意键继续. . .//不输出概念的话:排序后:约简:cdat_lung-cancer.dat:32*162, 时间:1.284000秒, com_num个数:3127560, 概念个数:1120807*/void MyTWconcepts(unsigned long*concept, long num){for (int k = 0; k < num; k++){int i, j, c;int first = 1;fprintf(out_file, "(({");for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (concept[j + (onum_longSize * 2 + anum_longSize)*k] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "},{");first = 1;for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (concept[j + (onum_longSize * 2 + anum_longSize)*k +onum_longSize] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "}),{");//int i, j, c;//int first = 1;//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);first = 1;for (c = j = 0; j < anum_longSize; j++){int flag_wan = 0;for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (concept[j + (onum_longSize * 2 + anum_longSize)*k +onum_longSize*2] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "})");////fprintf(out_file, "\n");////}}void InClose(unsigned long *B, unsigned long *A, unsigned long *AN, unsigned long start_ulong, int start_bit_j, int *start_ulongFlag, unsigned long **N, unsigned long ***N_stack)// start_ulong ,start_bit_j 二者组合在一起表示本次调用的起始属性,即算法中的y。 start_ulong是y所在单元(一个unsigned long),start_bit_j是y的位序号 {int i, j_numAttri;unsigned long *C,*CN, *D, *temp_D;int *start_ulongFlagtemp = start_ulongFlag;j_numAttri = start_ulong * (ARCHBIT + 1) + (ARCHBIT - start_bit_j);//WWWang,赋初值OK了。。。j_numAttri为当前属性的序号(也表示前面已经处理了j_numAttri个属性)unsigned long *D_head;D = temp_D = D_head = (unsigned long *)malloc((byte_anumLongSize + byte_onumLongSize*2) * (attributes - j_numAttri));C = D + anum_longSize; //第一个概念的外延的起始位置。。。CN = C + onum_longSize;unsigned long ***N_stack_temp = N_stack;for (; start_ulong < anum_longSize; start_ulong++)//遍历所有属性。。。{com_num++;int flag_bianliwan = 0;for (; start_bit_j >= 0; start_bit_j--, j_numAttri++)//遍历每个longSize(32个对象)中的所有对象。。。{if (j_numAttri >= attributes)  //因为最后一个longSize空间中放的属性个数很可能不满,所以特殊处理下。。。。{flag_bianliwan = 1;break;}if (!(B[start_ulong] & (BIT << start_bit_j)))  /* 算法中的j属于B */{int flag_imply = 0;if (N[j_numAttri] != NULL)//若为空,则直接计算新概念进入一般测试{if (N[j_numAttri][start_ulong] & ~(B[start_ulong]) & Yj[start_bit_j]){//若集合A的某些元素不在集合B中,则A一定不包含于B。判断Nj是否包含于B。Yj[start_bit_j]用于屏蔽start_bit_j及start_bit_j右边的bitflag_imply = 1;}if (flag_imply == 0){for (i = 0; i < start_ulong; i++){if (N[j_numAttri][i] & ~(B[i])){flag_imply = 1;break;}}}}if (flag_imply == 0){////printf("j=%d\n", j_numAttri);int result1 = AjtoC(C, A, cols[j_numAttri]);if (result1 == 2)continue;//if (result1 != 2)//表示C不空,C大小>0.。。。。{int result2 = ANjtoCN(CN, AN, cols[j_numAttri]);if (result2 == 2)continue;//if (result2 != 2)//表示CN不空,CN大小>0.。。。。{if ((result1 == 1) && (result2 == 1)){B[start_ulong] |= (BIT << start_bit_j);//将属性j加入B中。。。。}////if (AjtoC(C, A, cols[j_numAttri]) == 2)if ((result1 == 0) || (result2 == 0))//((result1 == 1) && (result2 == 1))不成立。。{//CtoD(D, C);//WWWang 为了求D。。。。。CCNtoD(D, C, CN);if (!((D[start_ulong] ^ B[start_ulong]) & Yj[start_bit_j]))//初步判断最接近j的那个longSize的B和D中属性的关系是否满足Bqueue_Flagj等于Dqueue_Flagj...,自己分步试了,没问题。。。{int flag_skiptoelse = 1;for (i = 0; i < start_ulong; i++)//为了测试剩余属性0,1...(start_ulong-1)*4中的属性是否有:Bqueue_Flagj=Dqueue_Flagj成立与否。。。WWWang*********{if (D[i] ^ B[i])//B和D不同,因为D[i]和B[i]中的属性都在Yj中,所以有Bqueue_Flagj不等于Dqueue_Flagj{flag_skiptoelse = 0;*N_stack_temp = &(N[j_numAttri]);N_stack_temp++;*N_stack_temp = (unsigned long **)N[j_numAttri];//强制类型转换N_stack_temp++;N[j_numAttri] = D;D[anum_longSize - 1] |= BIT;// //WWWang 初始化时anum_longSize多给了(1位到31位,就是为了这里queue_Flag用的最右边那个标志位。。。)break;}}if (flag_skiptoelse == 1){//**************入队。。。。。。。。。//入队对应的start_ulong,start_bit值。。。。。//当然D通过标志位queueFlag,,,初始化全0即都入队,当正则检测失败时置为1,表示不入队。。。。*start_ulongFlagtemp = start_ulong;start_ulongFlagtemp++;*start_ulongFlagtemp = start_bit_j;start_ulongFlagtemp++;}}else//正则检测失败。。。。。。。。。{*N_stack_temp = &(N[j_numAttri]);N_stack_temp++;*N_stack_temp = (unsigned long **)N[j_numAttri];//强制类型转换N_stack_temp++;N[j_numAttri] = D;D[anum_longSize - 1] |= BIT;  //WWWang 初始化时anum_longSize多给了(1位到31位,就是为了这里queue_Flag用的最右边那个标志位。。。)}D = CN + onum_longSize;//D指向新概念的起始地址。。。。C = D + anum_longSize;//C在D地址上加anum_longSize,同初始化解释。。。WWWangCN = C + onum_longSize;}}}}}/////j_numAttri++;//统计已遍历属性的个数,主要为了控制最后一个anum_longSize中的属性,因为它很可能不满,不等遍历32个就要退出。。。}if (flag_bianliwan == 1)//通过j_numAttri和attribe比对,判断属性遍历完否。。。break;elsestart_bit_j = ARCHBIT;//下一个anum_longSize中的起始位,设置为31。。。。。}if (choice=='y'){//out_easy_TWconcepts(B);out_TWconcepts(A, AN, B);conceptNum++;if (conceptNum <= 100000){if (conceptNum == 10 * countConcept){printf("supp:%lld\n", conceptNum);countConcept *= 10;}}else{i_temp++;if (i_temp == 100000){printf("supp:%lld\n", conceptNum);i_temp = 0;}}}if (choice == 'n'){//out_easy_TWconcepts(B);out_TWconcepts(A, AN, B);conceptNum++;if (conceptNum <= 100000){if (conceptNum == 10 * countConcept){printf("supp:%lld\n", conceptNum);countConcept *= 10;}}else{i_temp++;if (i_temp == 100000){printf("supp:%lld\n", conceptNum);i_temp = 0;}}}for (; temp_D != D; temp_D = CN + onum_longSize)//temp_D != D这个条件用于处理所有的计算出的概念{C = temp_D + anum_longSize;//队列中的第一个概念外延CN = C + onum_longSize;if (temp_D[anum_longSize - 1] & BIT) //WWWang 当前概念没有入队,所以不用遍历子概念。。。。是queue_Flag中的失败概念,即树中的方块节点,不递归 continue;//执行InClose的D=BUj  但是j没有入队啊。。。。当时的j如何保存,,额有了*(start_ulongFlag + 1)就是了。。。。//当时的D[Bchildren[0]]即D[*start_ulongFlag], D[Bchildren[1]]即D[*(start_ulongFlag+2)],D[Bchildren[j]]即D[*(start_ulongFlag+2*j)]当然 *start_ulongFlag,*(start_ulongFlag+2)等可能相等temp_D[*start_ulongFlag] = B[*start_ulongFlag] | (BIT << *(start_ulongFlag + 1));//刚开始两个D只有一个改为temp_D,两一个忘记改,一定程度影响com_numif (*(start_ulongFlag + 1) == 0)InClose(temp_D, C, CN, *start_ulongFlag + 1, ARCHBIT, start_ulongFlagtemp, N, N_stack_temp);//走下一anum_longSize,ARCHBIT为下一anum_longSize中的属性31,else  //还没到longSize的最后一位,start_ulong不变,start_bit_j-1即可 InClose(temp_D, C, CN, *start_ulongFlag, *(start_ulongFlag + 1) - 1, start_ulongFlagtemp, N, N_stack_temp);//看下一个属性即start_bit_j-1,即*(start_ulongFlag + 1) - 1start_ulongFlag += 2;//WWWang(指向下一个,为了和D0,D1,D2等的切换一直,切换到同一个概念。。。。}for (; N_stack != N_stack_temp; N_stack += 2){**N_stack = (unsigned long *)*(N_stack + 1);  /* 把N恢复到刚进入本次调用时的状态,注意这里必须强制转换回来 */}free(D_head);return;}int BisEmpty(unsigned long *B){for (int k = 0; k < anum_longSize; k++){if (B[k]>0)return 0;}return 1;}int AjtoC(unsigned long *C, unsigned long *A, unsigned long *cols)//cols初始值为cols[j_numAttri]{int i, j, k;int flag = 1;int flagC_empty = 0;if (cols)//cols属性外延即为j',也即程序中的cols[j_numAttri]????但有问题啊,cols[0...onumLongsize-1]才是属性1和所有对象的关系。。{for (k = 0; k < onum_longSize; k++)//为了遍历cols[j_numAttri+0],cols[j_numAttri+1],..cols[j_numAttri+onum_longSize-1]{///printf("cols[%d]:%x\n:",k,cols[k]);C[k] = A[k] & (cols[k]);//A与j'的交集,计算新的外延if ((choice == 'y') && (C[k] == 0)){flagC_empty++;}if ((flag == 1) && (C[k]!=A[k]))//如果二者不相等。。。{flag = 0;}}}if (flag == 1)//A等于Creturn 1;else //A不等于C{if (flagC_empty == onum_longSize)//C为空。。。不进行正则判断return 2;else //C不空。。进行正则判断return 0;}}int ANjtoCN(unsigned long *CN, unsigned long *AN, unsigned long *cols)//cols初始值为cols[j_numAttri]{int i, j, k;int flag = 1;int flagC_empty = 0;if (cols)//cols属性外延即为j',也即程序中的cols[j_numAttri]????但有问题啊,cols[0...onumLongsize-1]才是属性1和所有对象的关系。。{for (k = 0; k < onum_longSize; k++)//为了遍历cols[j_numAttri+0],cols[j_numAttri+1],..cols[j_numAttri+onum_longSize-1]{///printf("cols[%d]:%x\n:",k,cols[k]);CN[k] = AN[k] & (~cols[k]);//AN与jn'的交集,计算新的外延if ((choice == 'y') && (CN[k] == 0)){flagC_empty++;}if ((flag == 1) && (CN[k] != AN[k]))//如果二者不相等。。。{flag = 0;}}}if (flag == 1)//A等于Creturn 1;else //A不等于C{if (flagC_empty == onum_longSize)//C为空。。。不进行正则判断return 2;else //C不空。。进行正则判断*/return 0;}}void CCNtoD(unsigned long *D, unsigned long *C, unsigned long *CN){int i, j, k, l;memset(D, 0xFF, byte_anumLongSize);//WWWang位全置1if (D[anum_longSize - 1] % 2 == 1)//如果最后一位位1则初始为0,即默认入队的。。。。???  但考虑到作者没写,且程序几个数据的结果都没问题,暂时不加D[anum_longSize - 1]--;for (k = 0; k < onum_longSize; k++){if (C[k])//如果外延不为空,求C'即D{for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交{if (C[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环{if ((C[k] >> l) & BIT)//对外延中的对象l处理{for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++){D[i] = D[i] & (context[j]);}}}else{break;}}}if (CN[k])//如果外延不为空,求CN'即D{for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交{if (CN[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环{if ((CN[k] >> l) & BIT)//对外延中的对象l处理{for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++){D[i] = D[i] & (~context[j]);}}}else{break;}}}}}void CtoD(unsigned long *D, unsigned long *C)//cols初始值为cols[j_numAttri]{int i, j, k, l;memset(D, 0xFF, byte_anumLongSize);//WWWang位全置1if (D[anum_longSize - 1] % 2 == 1)//如果最后一位位1则初始为0  但考虑到作者没写,且程序几个数据的结果都没问题,暂时不加D[anum_longSize - 1]--;for (k = 0; k < onum_longSize; k++){if (C[k])//如果外延不为空,求C'即D{for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交{if (C[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环{if ((C[k] >> l) & BIT)//对外延中的对象l处理{for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++){D[i] = D[i] & (context[j]);}}}else{break;}}}}}

function_c.h

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#define BIT((unsigned long) 1)  #define zero_LONG((unsigned long) 0)#define INT_SIZE(sizeof (int))#define LONG_SIZE(sizeof (unsigned long))#define ARCHBIT((LONG_SIZE * 8) - 1)  /* 最高位序号 */#define byte_anumLongSize(LONG_SIZE * anum_longSize)  // 属性占用的字节数,一个属性一bit,对的其实就是4*(attributes/32+1) #define byte_onumLongSize(LONG_SIZE * onum_longSize)#define bufBlock10241024int attributes = 0;  //属性的总个数int objects = 0; //对象的总个数int anum_longSize = 0;  //存储属性所需要的LONG_SIZE个数int onum_longSize = 0;  //存储对象所需要的LONG_SIZE个数int table_ones = 0;//形式背景表格中1的个数int intData[1000];unsigned long *context;//用于存储形式背景的指针/*宏定义一个函数用来存储形式背景中1对应的属性,存储在mybuf开始的地址空间中*/FILE *in_file;FILE *out_file;int *mybuf = NULL;//一个一维数组,大小除了多存放行结束标志-1则该多少是多少,一点不多malloc.int mybuf_index = 0;int mybuf_size = bufBlock1024;void create_context();void read_file();void allocate_mybufer(int **mybufer, int size);int getNextInt(FILE *file, int *value);void initialize_algorithm();unsigned long **cols;//属性列,双指针。。。unsigned long Yj[ARCHBIT + 1];  /* 第i个元素的右边i位全是0,从第i+1位向左全为1。用于屏蔽右边i位 。为了实现和集合Yj的相交*/int AjtoC(unsigned long *C, unsigned long *A, unsigned long *cols);int *attrib_numbers,*object_numbers;long long countConcept = 1;#define PushNewInterger(__value) \  { \if (mybuf_index >= mybuf_size) { \      mybuf_size += bufBlock1024; \      allocate_mybufer (&mybuf, mybuf_size); \} \mybuf[mybuf_index] = (__value); \mybuf_index ++; \  }void print_concepts(unsigned long *setC, unsigned long *setD);void print_A(unsigned long *setA);void print_B(unsigned long *setB);void out_concepts(unsigned long *setC, unsigned long *setD);char fname[100];void sort_context();int min_support = 0;int *supps;int rows_compar(const void *a, const void *b);int cols_compar(const void *a, const void *b);void initialize_output();void initialize_output(){//初始化输出。。。。int q;attrib_numbers = (int *)malloc(sizeof(int) * attributes);for (q = 0; q < attributes; q++)attrib_numbers[q] = q;int p;object_numbers = (int *)malloc(sizeof(int) * objects);for (p = 0; p < objects; p++)object_numbers[p] = p;}void initialize_algorithm(){//用于给cols赋值。。。。////cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系int i, j, k, x, y;unsigned long *temp_colmybuf, mask, *cols_mybuf;for (i = 0; i <= ARCHBIT; i++)//下面两个for循环对Yj[i]初始化{Yj[i] = zero_LONG;//zero_LONG是unsigned long型的0for (j = ARCHBIT; j > i; j--){Yj[i] |= (BIT << j);  //通过for循环、或的作用。。。 第i个元素的右边i位全是0,从第i+1位向左全为1,因为Bit是unsigned long型1。。。。 }}//Yj[i]现在第i个元素的右边i位全是0,从第i+1位向左全为1。用于屏蔽右边i位 。为了实现和集合Yj的相交*/cols_mybuf = (unsigned long *)malloc(LONG_SIZE * onum_longSize * attributes);//单指针。。。。存储背景,这时换成。。。以列为单位memset(cols_mybuf, 0, LONG_SIZE * onum_longSize * attributes);//初始化为0cols = (unsigned long **)malloc(sizeof(unsigned long *) * attributes);//双指针。。。。 存储列地址temp_colmybuf = cols_mybuf;for (k = j = 0; j < anum_longSize; j++)//anum_longSize属性用的long的个数。。。{for (i = ARCHBIT; i >= 0; i--, k++){if (k >= attributes)//如果所有属性处理完毕,则退出return;mask = (BIT << i);//mask=1左移i位。。。即1*2^icols[k] = temp_colmybuf;for (x = 0, y = j; x < objects; x++, y += anum_longSize){if (context[y] & mask)//判断x对象是否具有属性i????{temp_colmybuf[x / (ARCHBIT + 1)] |= BIT << (x % (ARCHBIT + 1));//对象x是否具有属性i....}}temp_colmybuf += onum_longSize;//cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系//与context不同,cols[0][0]中的存放12345678,1放对象28-31,2放对象24-27,3放对象20-23,4放。。。7放4-7位,8放对象0-3 但是也是32位全用来存放有效的属性。。。 为何queue_Flag中要用属性列的最后一位作标志位判断重复失败与否。。。//printf("cols[%d][0]:%x\n", k, cols[k][0]);//printf("cols[%d][1]:%x\n", k, cols[k][1]);}}}void read_file()//读取形式背景文件{printf("请输入文件名:");scanf("%s", fname);FILE *file = fopen(fname, "r");int last_value = -1, value = 0, last_attribute = -1, last_object = -1;allocate_mybufer(&mybuf, mybuf_size);//为mybuf重新申请更大的空间。。。while (getNextInt(file, &value))//依次获得文件中的属性值 每次仅读取一个数字。。。{if ((value < 0) && (last_value < 0))//某一行为空,不作处理,不影响。。。continue;if (value < 0)//行末情况发生,last_object计数加1,用-1来分割地址中不同对象的属性{last_object++;//统计非空行的行数,即对象的个数。。。。PushNewInterger(-1);}else{if (value > last_attribute){last_attribute = value;//为了找到最大的属性值,即属性的个数。。。。}PushNewInterger(value);}last_value = value;}if (last_value >= 0){last_object++;PushNewInterger(-1);//地址中最后一个元素赋值为-1}objects = last_object + 1;//attributes = last_attribute + 1;//所有属性从0开始。。。。 背景从0开始//attributes = last_attribute;fclose(file);}int getNextInt(FILE *file, int *value){//通过value传值,return仅仅返回真假,是否读取到了数值。。。。int ch = ' ';*value = -1;//初始化为-1,若ch到行末但不是文件尾,那么value为默认值-1while ((ch != EOF) && ((ch < '0') || (ch > '9')))//文件没到末尾且ch不为数字,即空格时{ch = fgetc(file);if (ch == '\n')return 1;//走到行尾了。。。。}if (ch == EOF)return 0;//走到文件尾了。。。。*value = 0;while ((ch >= '0') && (ch <= '9'))//ch为数字的情况,计算value的值{*value *= 10;*value += ch - '0';ch = fgetc(file);}//能走到这说明正好走到一个数字又读取了一个字符,该ch应放回文件流中,待下次判断。。。ungetc(ch, file);//相当于撤销上一次的fgetc调用return 1;}///********************************************************************************************************int cols_compar(const void *a, const void *b){int x, y;x = supps[*(int const *)a];y = supps[*(int const *)b];if (x >= min_support){if (y >= min_support)return (x < y) ? -1 : ((x > y) ? 1 : 0);elsereturn -1;}else{if (y >= min_support)return 1;elsereturn (x < y) ? -1 : ((x > y) ? 1 : 0);}}int rows_compar(const void *a,const void *b){int i;for (i = 0; i < anum_longSize; i++)if (((unsigned long *)a)[i] < ((unsigned long *)b)[i])return -1;else if (((unsigned long *)a)[i] > ((unsigned long *)b)[i])return 1;return 0;}void sort_context(){int i, j, k, x, y, z, ii, jj, a, aa;unsigned long *new_context;for (a = i = 0; i < attributes; i++)if (supps[i] >= min_support)a++;qsort(attrib_numbers, attributes, sizeof(int), cols_compar);aa = attributes;attributes = a;a = anum_longSize;anum_longSize = (attributes / (ARCHBIT + 1)) + 1;new_context = (unsigned long *)malloc(LONG_SIZE * anum_longSize * objects);memset(new_context, 0, LONG_SIZE * anum_longSize * objects);for (k = jj = 0, ii = ARCHBIT; k < aa; k++){if (supps[attrib_numbers[k]] < min_support)continue;j = attrib_numbers[k] / (ARCHBIT + 1);i = ARCHBIT - (attrib_numbers[k] % (ARCHBIT + 1));for (x = 0, y = j, z = jj; x < objects; x++, y += a, z += anum_longSize)if (context[y] & (BIT << i))new_context[z] |= (BIT << ii);if (ii > 0)ii--;else{ii = ARCHBIT;jj++;}}free(context);context = new_context;qsort(context, objects, byte_anumLongSize, rows_compar);}void create_context()//用位数组存储背景{int i = 0, row = 0;//31个属性的话就用1个longSize.queue_Flag标志位(用1位),多给了(32-31)=1位,用于queue_Flag,最佳空间利用的很好//32个属性的话就用2个longSize.本来一个就Ok了,为了queue_Flag标志位(用1位),多给了(32)=32位,用于queue_Flag//33个属性的话就用2个longSize.queue_Flag标志位(用1位),多给了(32-1)=31位,用于queue_Flaganum_longSize = (attributes / (ARCHBIT + 1)) + 1;//WWWang 这里多给了(1位到32位,就是为了queue_Flag用的最右边那个标志位。。。)计算存储属性需要的LONG_SIZE个数//onum_longSize = (objects / (ARCHBIT + 2))+1;//WWWang计算存储对象需要的LONG_SIZE个数,1位也不多给。。。onum_longSize = (objects / (ARCHBIT + 1)) + 1;//这个也多给了(1-32位。。。目前没作用,但是先不动它。。)context = (unsigned long *)malloc(LONG_SIZE * anum_longSize * objects);//context是一维数组哈。。。。例如context[0]=??supps = (int *)malloc(sizeof(int) * attributes);memset(supps, 0, sizeof(int) * attributes);if (!context){fprintf(stderr, "不能给背景申请空间.\n");exit(5);}memset(context, 0, LONG_SIZE * anum_longSize * objects);//先初始化为0//memset(contextN, 0xFF, LONG_SIZE * anum_longSize * objects);for (i = 0; i < mybuf_index; i++)//对mybuf数组中的每个元素处理{if (mybuf[i] < 0)//-1的情况说明一个对象的属性处理完毕,也就是文件中的一行属性处理完毕{row++;continue;}//0-31context[row * anum_longSize+0], 32-63context[row * anum_longSize+1],,,...context[row * anum_longSize+anum_LongSize-1]//这种思想自己用过。。。。context[row * anum_longSize + (mybuf[i] / (ARCHBIT + 1))] |= (BIT << (ARCHBIT - (mybuf[i] % (ARCHBIT + 1)))); //(ARCHBIT - (mybuf[i] % (ARCHBIT + 1)))属性0对应31-0 30对应31-30 31对应31-31。。。supps[mybuf[i]]++;table_ones++;//背景是属性0代表31位,属性1代表30位。。。。属性31代表0位。。    属性32代表31位(因为32%32=0)。。。。//printf("context[%d]:%x\n", row * anum_longSize + (mybuf[i] / (ARCHBIT + 1)),context[row * anum_longSize + (mybuf[i] / (ARCHBIT + 1))]);}}void allocate_mybufer(int **mybufer, int size)//该函数为*mybufer开始的地址分配空间{if (*mybufer){*mybufer = (int *)realloc(*mybufer, INT_SIZE * size);}else{*mybufer = (int *)malloc(INT_SIZE * size);}if (!*mybufer){fprintf(stderr, "不能重新分配内存\n");exit(3);}}void print_A(unsigned long *setA)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;for (c = j = 0; j < onum_longSize; j++){for (i = 0; i <= ARCHBIT; i++){if (setA[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(" ");}printf("%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{break;}}}}void print_B(unsigned long *setB)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{printf("%x,", setB[0]);int i, j, c;int first = 1;for (c = j = 0; j < anum_longSize; j++){for (i = ARCHBIT; i >= 0; i--){if (setB[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(" ");}printf("%d", attrib_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{break;}}}printf("\n");}void out_concepts(unsigned long *setC, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{out_file = fopen("out_file.txt", "a");int i, j, c;int first = 1;for (c = j = 0; j < onum_longSize; j++){for (i = 0; i <= ARCHBIT; i++){if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{fprintf(out_file, " , ");////break;}}}//int i, j, c;//int first = 1;first = 1;for (c = j = 0; j < anum_longSize; j++){for (i = ARCHBIT; i >= 0; i--){if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");}fprintf(out_file, "%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{fprintf(out_file, "\n");////fclose(out_file);}}}}void print_concepts(unsigned long *setC, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(" ");}printf("%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;printf(" , ");////break;}}if (flag_wan == 1)break;}//int i, j, c;//int first = 1;//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);first = 1;for (c = j = 0; j < anum_longSize; j++){for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(" ");}printf("%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{printf("\n");////break;}}}}void print_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;printf("(({");for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(",");}printf("%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}printf("},{");first = 1;for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(",");}printf("%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}printf("}),{");//int i, j, c;//int first = 1;//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);first = 1;for (c = j = 0; j < anum_longSize; j++){int flag_wan = 0;for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{printf(",");}printf("%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}printf("})");////printf("\n");////}void out_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;fprintf(out_file, "(({");for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "},{");first = 1;for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "}),{");//int i, j, c;//int first = 1;//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);first = 1;for (c = j = 0; j < anum_longSize; j++){int flag_wan = 0;for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, ",");}fprintf(out_file, "%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "})");////fprintf(out_file, "\n");////}void out_TWconcepts_C_CN_D(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;fprintf(out_file, "");for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, ",");first = 1;for (c = j = 0; j < onum_longSize; j++){int flag_wan = 0;for (i = 0; i <= ARCHBIT; i++){if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");}fprintf(out_file, "%d", object_numbers[c]);first = 0;}c++;//每处理一个对象c要加一if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "|");//int i, j, c;//int first = 1;//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);first = 1;for (c = j = 0; j < anum_longSize; j++){int flag_wan = 0;for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");}fprintf(out_file, "%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "\n");////}void out_TWconcepts_D(unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int i, j, c;int first = 1;fprintf(out_file, "|");//printf("|");first = 1;for (c = j = 0; j < anum_longSize; j++){int flag_wan = 0;for (i = ARCHBIT; i >= 0; i--){//printf("BIT<<i:%x, ",BIT<<i);if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性{if (!first)//标志位,输出空格{fprintf(out_file, " ");//printf(" ");}fprintf(out_file, "%d", attrib_numbers[c]);//printf("%d", attrib_numbers[c]);first = 0;}c++;//每处理一个属性c要加一if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕{flag_wan = 1;break;}}if (flag_wan == 1)break;}fprintf(out_file, "\n");//////printf("\n");////}void out_easy_TWconcepts(unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性{int j, num_str = 0;for (j = 0; j < anum_longSize; j++){fprintf(out_file, "%x ", setD[j]);}fprintf(out_file, "\n");/*int j,num_str = 0;for (j = 0; j < anum_longSize; j++){intData[num_str++] = setD[j];}for (int i = 0; i < num_str; i++)fprintf(out_file, "%x ", intData[i]);fprintf(out_file, "\n");*/}


0 0
原创粉丝点击