PCbO3C算法20170214

#include "Read.h"
#include <Windows.h>
#include <process.h>//_beginthreadex
#include <sstream>
#define MAX_DECIMAL_INT_SIZE (8)
int threads = 1;
int para_level = 2;
HANDLE out_handle;

HANDLE *thread_id;
int *thr_index;
uchar **my_thr;//双指针uchar
uchar **my_thr_head;//双指针uchar
uchar **my_thr_limit;//双指针uchar

ulong **intents_thr;//ulong双指针
int common_sum_concepts = 0;
int common_num = 0;
int **starts;
ulong ***implied;//局部变量。。。。。
ulong ****implied_stack;//也是局部变量,压根没有什么全局变量。。。。
struct str_int
{
	char str[MAX_DECIMAL_INT_SIZE];
	int length;
} *table_of_ints;
void find_all_intents();
void initialize_algorithm();
struct timeb rawtime;
clock_t start, finish;
long long conceptNum[5000];
long i_temp[5000];
FILE *out_thread_file[5000];
int main(int argc, char **argv)
{
	remove("test");
	remove("test_failed");
	system("color F0");
	printf("***************PCbO3C_FCbO**************\n");

	argv[1] = "cdat_lung-cancer.dat";
	argv[2] = "8";//线程数
	argv[3] = "2";//level

	char *fname = argv[1];
	stringstream ss;
	ss << argv[2];
	ss >> threads;
	ss.clear();//clear必须有,必须先情况ss字符串流。。。
	ss << argv[3];
	ss >> para_level;

	in_file = fopen(fname, "r");
	if (in_file == NULL)
	{
		printf("打开文件 \"%s\" 失败\n\n", fname);
		ofstream test;
		test.open("test_failed");
		test.close();
		return -1;
	}
	char fname_out[200] = "out_";
	strcat(fname_out, fname);
	strcat(fname_out, "_t"); strcat(fname_out, argv[2]);
	strcat(fname_out, "_l"); strcat(fname_out, argv[3]);
	
	for (int i = 0; i < threads; i++)
	{
		char file_gen[1000] = "out_files\\out_file_";//文件输出位置
		stringstream ss_i;
		ss_i << i;
		string str_i = ss_i.str();
		const char *i_threads = str_i.c_str();
		strcat(file_gen, i_threads);
		out_thread_file[i] = fopen(file_gen, "w");
	}

	memset(conceptNum, 0, sizeof(conceptNum));
	memset(i_temp, 0, sizeof(i_temp));
	read_file(in_file);	create_context();
	initialize_output();
	sort_context();
	initialize_algorithm();
	out_handle = CreateMutex(NULL, FALSE, NULL);//主线程创建不拥有所有权的互斥量。
	
	ftime(&rawtime);ulong s_start = rawtime.time;int ms_start = rawtime.millitm;
	start = clock();
	find_all_intents();
	finish = clock();
	ftime(&rawtime);ulong s_end = rawtime.time;	int ms_end = rawtime.millitm;
	ulong out_s = s_end - s_start;	int out_ms = ms_end - ms_start;
	if (out_ms < 0){out_ms += 1000;out_s -= 1;}
		
	int sum_conceptNum=0;
	for (int i = 0; i < threads; i++)
	{
		sum_conceptNum += conceptNum[i];
		///cout << conceptNum[i] << endl;
	}
	cout << fname << ", 线程数:" << threads << ",L=" << para_level << ", 概念数量:" << sum_conceptNum << ", 用时:" << (double)(finish - start) / CLOCKS_PER_SEC <<"秒,linux计时:"<< out_s << "s," <<out_ms<<"ms"<< endl;
	ofstream out_logs("out_logs", std::ios::app);
	out_logs << fname << ", 线程数:" << threads << ",L=" << para_level << ", 概念数量:" << sum_conceptNum << ", 用时:" << (double)(finish - start) / CLOCKS_PER_SEC << "秒,linux计时:" << out_s << "s," << out_ms << "ms" << endl;
	out_logs.close();
	out_logs.open("test");
	out_logs.close();
	//system("pause");
	return 0;
}

/*
***************PCbO3C_FCbO**************
cdat_lung-cancer.dat, 线程数:8,L=2, 概念数量:1120807, 用时:1.135秒,linux计时:1s,135ms
请按任意键继续. . .
*/

void table_of_ints_init(int max)
{
	table_of_ints = (struct str_int*)malloc(sizeof(struct str_int) * max);
	for (int i = 0; i < max; i++) {
		sprintf(table_of_ints[i].str, "%i", i);
		table_of_ints[i].length = strlen(table_of_ints[i].str);
	}
}

void print_thread_attributes(const ulong *set,int id)
{
	//WaitForSingleObject(out_handle, INFINITE);//等待现有的线程释放资源
	int j;
	for (j = 0; j < int_cnt_a; j++)
	{
		fprintf(out_thread_file[id], "%x ", set[j]);
	}
	fprintf(out_thread_file[id], "\n");
	conceptNum[id]++;
	i_temp[id]++;
	if (i_temp[id] == 5000000)
	{
		printf("conceptNum[%d]=%lld\n", id,conceptNum[id]);
		i_temp[id] = 0;
	}
	//ReleaseMutex(out_handle);//释放资源。。。。
}

void print_attributes(const ulong *set)
{
	WaitForSingleObject(out_handle, INFINITE);//等待现有的线程释放资源
	int j;
	for (j = 0; j < int_cnt_a; j++)
	{
		fprintf(out_file, "%x ", set[j]);
	}
	fprintf(out_file, "\n");
	/*conceptNum[id]++;
	i_temp[id]++;
	if (i_temp == 100000)
	{
		printf("supp:%lld\n", conceptNum);
		i_temp = 0;
	}*/
	ReleaseMutex(out_handle);//释放资源。。。。
	//WaitForSingleObject(out_handle, INFINITE);//等待现有的线程释放资源
	//int j; int temp = 0;
	//char buf_out[1000];
	//int buf_index = 0;
	//for (j = 0; j < int_cnt_a; j++)//遍历属性
	//{
	//	for (int i = ARCHBIT; i >= 0; i--)
	//	{
	//		if (set[j] & (BIT << i) && temp<attributes)
	//		{
	//			//attrib_numbers[temp]因为排序了,用attrib_numbers[temp]来查找实际属性。。。
	//			strcpy(buf_out + buf_index, table_of_ints[attrib_numbers[temp]].str);//mush.dat  555s 不加互斥量
	//			buf_index += table_of_ints[attrib_numbers[temp]].length;
	//			buf_out[buf_index++] = ' ';
	//		}
	//		temp++;
	//	}
	//}
	//buf_out[buf_index++] = '\n';//先回车
	//buf_out[buf_index++] = '\0';//后标志为\0结束字符串,不然的话输出到文件时 读到'\0'就终止读了
	//							//fprintf(out_file, "\n");
	//fputs(buf_out, out_file);//输入到文件中。。。。
	//common_sum_concepts++;
	//common_num++;
	//if (common_num == 100000)
	//{
	//	printf("concepts:%d\n", common_sum_concepts);
	//	common_num = 0;
	//}
	//ReleaseMutex(out_handle);//释放资源。。。。
}

void initialize_algorithm()
{
	table_of_ints_init(attributes);//初始化结构体数组table_of_ints

	int i, j, k, x, y;
	ulong *ptr, mask, *cols_buff;
	for (i = 0; i <= ARCHBIT; i++)
	{
		upto_bit[i] = NULL_LONG;
		for (j = ARCHBIT; j > i; j--)
			upto_bit[i] |= (BIT << j);
	}
	cols_buff = (ulong *)malloc(LONG_SIZE * int_cnt_o * attributes);
	std::memset(cols_buff, 0, LONG_SIZE * int_cnt_o * attributes);
	cols = (ulong **)malloc(sizeof(ulong *) * attributes);
	ptr = cols_buff;
	for (k = j = 0; j < int_cnt_a; j++)
	{
		for (i = ARCHBIT; i >= 0; i--, k++)
		{
			if (k >= attributes)
				return;
			mask = (BIT << i);
			cols[k] = ptr;
			for (x = 0, y = j; x < objects; x++, y += int_cnt_a)
				if (context[y] & mask)
					ptr[x / (ARCHBIT + 1)] |= BIT << (x % (ARCHBIT + 1));
			ptr += int_cnt_o;
		}
	}
}

int compute_closure(ulong *extent, ulong *extentN, ulong *prev_extent, ulong *prev_extentN, ulong *attr_extent)
{
	int i, j, k, p;
	if (attr_extent)
	{
		//bool  flag_noequal = false;//变量已被优化掉,因而不可用。。。
		//bool empty=true;//变量已被优化掉,因而不可用。。。
		bool  flag_noequal;
		flag_noequal = false;//同样会被优化掉,在Release下
		bool empty;
		empty = true;//同样会被优化掉,在Release下
		for (k = 0; k < int_cnt_o; k++)
		{
			extent[k] = prev_extent[k] & attr_extent[k];
			if ((!flag_noequal) && (extent[k] != prev_extent[k]))//如果二者不相等。。。
			{
				flag_noequal = true;
			}
			//if (empty && extent[k] != 0)
			if (empty && extent[k])
				empty=false;
		}
		if (empty)//empty==true,则真是空了,所以return 0;
			return 0;

		empty = true;//重置为true。。。 因为上层不空,改变了empty为false...
		bool flag_noequal2 = false;
		for (k = 0; k < int_cnt_o; k++)
		{
			extentN[k] = prev_extentN[k] & (~attr_extent[k]);
			if ((!flag_noequal2) && (extentN[k] != prev_extentN[k]))//如果二者不相等。。。
			{
				flag_noequal2 = true;
			}
			//if (empty && extentN[k] != 0)
			if (empty && extentN[k])
				empty=false;
		}
		if (empty)
			return 0;
		if ((!flag_noequal) && (!flag_noequal2))
			return 1;
		else
			return 2;
	}
}
//
//int to_new_extent(unsigned long *new_extent, unsigned long *new_extentN, unsigned long *extent, unsigned long *extentN, unsigned long *cols)//cols初始值为cols[total]
//{
//	int i, j, k; 
//	if (cols)//cols属性外延即为j',也即程序中的cols[total]????但有问题啊,cols[0...onumLongsize-1]才是属性1和所有对象的关系。。
//	{
//		int flag = 1;	int flagC_empty = 0;
//		for (k = 0; k < int_cnt_o; k++)
//		{
//			new_extent[k] = extent[k] & (cols[k]);//A与j'的交集,计算新的外延
//			if ((new_extent[k] == 0))
//			{
//				flagC_empty++;
//			}
//			if ((flag == 1) && (new_extent[k] != extent[k]))//如果二者不相等。。。
//			{
//				flag = 0;
//			}
//		}
//
//		if (flagC_empty == int_cnt_o)//new_extent为空了,直接return 2;不用看后面的了
//			return 0;
//
//		//其他情况要看extentN和new_extentN的关系
//		int flag2 = 1; flagC_empty = 0;
//		for (k = 0; k < int_cnt_o; k++)//为了遍历cols[total+0],cols[total+1],..cols[total+int_cnt_o-1]
//		{
//			new_extentN[k] = extentN[k] & (~cols[k]);//extentN与jn'的交集,计算新的外延
//			if (new_extentN[k] == 0)
//			{
//				flagC_empty++;
//			}
//			if ((flag2 == 1) && (new_extentN[k] != extentN[k]))//如果二者不相等。。。
//			{
//				flag2 = 0;
//			}
//		}
//		if (flagC_empty == int_cnt_o)//new_extentN为空。。。
//			return 0;
//		if (flag&&flag2)//A等于C && AN等于CN
//			return 1;
//		return 2;
//	}
//	return 2;
//}

void to_new_intent(unsigned long *new_intent, unsigned long *new_extent, unsigned long *new_extentN)
{
	int i, j, k, p;
	memset(new_intent, 0xFF, B_CNT_A);//WWWang位全置1
	if (new_intent[int_cnt_a - 1] % 2 == 1)//如果最后一位位1则初始为0,即默认入队的。。。。???  但考虑到作者没写,且程序几个数据的结果都没问题,暂时不加
		new_intent[int_cnt_a - 1]--;
	for (k = 0; k < int_cnt_o; k++)
	{
		if (new_extent[k])//如果外延不为空,求C'即D
		{
			for (p = 0; p <= ARCHBIT; p++)//该循环实现了外延中的所有对象属性相交
			{
				if (new_extent[k] >> p)//如果移位后为0,则没有更多的对象处理,跳出for循环
				{
					if ((new_extent[k] >> p) & BIT)//对外延中的对象p处理
					{
						for (i = 0, j = int_cnt_a * (k * (ARCHBIT + 1) + p); i < int_cnt_a; i++, j++)
						{
							new_intent[i] = new_intent[i] & (context[j]);
						}
					}
				}
				else
				{
					break;
				}
			}
		}

		if (new_extentN[k])//如果外延不为空,求new_extentN'即new_intent
		{
			for (p = 0; p <= ARCHBIT; p++)//该循环实现了外延中的所有对象属性相交
			{
				if (new_extentN[k] >> p)//如果移位后为0,则没有更多的对象处理,跳出for循环
				{
					if ((new_extentN[k] >> p) & BIT)//对外延中的对象p处理
					{
						for (i = 0, j = int_cnt_a * (k * (ARCHBIT + 1) + p); i < int_cnt_a; i++, j++)
						{
							new_intent[i] = new_intent[i] & (~context[j]);
						}
					}
				}
				else
				{
					break;
				}
			}
		}
	}
}

void gen_concepts(ulong *intent, ulong *extent, ulong *extentN, int start_int, int start_bit, int *starts, ulong **implied_recur, ulong ***implied_stack, int id)
{
	int i, total;
	ulong *new_extent, *new_extentN, *new_intent;
	ulong *new_intent_i, *new_intents_head;
	ulong ***implied_stack_i = implied_stack;

	int *start_i = starts;//用来存放start_int start_bit
	total = start_int * (ARCHBIT + 1) + (ARCHBIT - start_bit);
	new_intent = new_intent_i = new_intents_head = (ulong *)malloc((B_CNT_A + 2 * B_CNT_O) * (attributes - total));
	new_extent = new_intent + int_cnt_a;
	new_extentN = new_extent + int_cnt_o;

	for (; start_int < int_cnt_a; start_int++)
	{
		for (; start_bit >= 0; start_bit--)
		{
			if (total >= attributes)
				goto skipout;
			if (intent[start_int] & (BIT << start_bit))
				goto skip;
			if (implied_recur[total] != NULL)//失效的属性子集implied[total]
			{
				if (implied_recur[total][start_int] & ~(intent[start_int]) & upto_bit[start_bit])
					goto skip;
				for (i = 0; i < start_int; i++)
					if (implied_recur[total][i] & ~(intent[i]))
						goto skip;
			}

			int result = compute_closure(new_extent, new_extentN, extent, extentN, cols[total]);
			if (result == 0)
				goto skip;
			if (result == 1)
			{
				intent[start_int] |= (BIT << start_bit);//将属性j加入B中。。。。
				goto skip;
			}
			if (result == 2)
				to_new_intent(new_intent, new_extent, new_extentN);

			if ((new_intent[start_int] ^ intent[start_int]) & upto_bit[start_bit])
				goto skiptoelse;
			for (i = 0; i < start_int; i++)
				if (new_intent[i] ^ intent[i])
					goto skiptoelse;
			*start_i = start_int;	start_i++;
			*start_i = start_bit;	start_i++;
			//print_attributes(new_intent);
			print_thread_attributes(new_intent, id);
			goto skipoverelse;
		skiptoelse:

			*implied_stack_i = &(implied_recur[total]);//首先让implied_stack_i指向 (implied[total])的地址,即 &(implied[total])
			implied_stack_i++;//然后,局部指针变量implied_stack_i++
			*implied_stack_i = (ulong **)(implied_recur[total]);//这是啥意思??ulong* => ulong**
			implied_stack_i++;//然后,局部指针变量implied_stack_i++
			implied_recur[total] = new_intent;//implied[total]仍是个指针,地址指向new_intent的地址。。。
			new_intent[int_cnt_a - 1] |= BIT;//这样是失效的都赋值为1。。。。
		skipoverelse:
			new_intent = new_extentN + int_cnt_o;//地址移动到下一个概念的地址处。。。
			new_extent = new_intent + int_cnt_a;
			new_extentN = new_extent + int_cnt_o;
		skip:
			total++;
		}
		start_bit = ARCHBIT;
	}

skipout:
	for (; new_intent_i != new_intent; new_intent_i = new_extentN + int_cnt_o)
	{
		//std::cout << "栈中概念个数" << (new_intent - new_intent_i) / (int_cnt_a + int_cnt_o * 2) << endl;
		new_extent = new_intent_i + int_cnt_a;
		new_extentN = new_extent + int_cnt_o;
		if (new_intent_i[int_cnt_a - 1] & BIT)//这个最后一个long_size的最低位是标志位,1则代表访问过的失效的概念??? 没有控制好啊。。。。
			continue;

		new_intent_i[*starts] = intent[*starts] | (BIT << *(starts + 1));

		if (*(starts + 1) == 0)
			gen_concepts(new_intent_i, new_extent, new_extentN, *starts + 1, ARCHBIT, start_i, implied_recur, implied_stack_i, id);
		else
			gen_concepts(new_intent_i, new_extent, new_extentN, *starts, *(starts + 1) - 1, start_i, implied_recur, implied_stack_i, id);
		starts += 2;
	}

	for (; implied_stack != implied_stack_i; implied_stack += 2)//若没到implied_stack_i,则implie_stack+=2,地址往下指一步
	{
		**implied_stack = (ulong *)(*(implied_stack + 1));//????
	}
	free(new_intents_head);//在这释放申请的空间。。。
	return;
}

unsigned _stdcall thread_func(void *params)//params是_beginthreadex中第四个参数【thr_index】。。。
{
	int id = *(int *)params;//(int*)强制类型转换。。。
	for (; my_thr_head[id] < my_thr[id];)
	{
		memcpy(intents_thr[id], my_thr_head[id], B_CNT_AOON);
		my_thr_head[id] += B_CNT_AOON;
		gen_concepts(intents_thr[id], intents_thr[id] + int_cnt_a, intents_thr[id] + int_cnt_a + int_cnt_o,
			*(int *)my_thr_head[id], *(int *)(my_thr_head[id] + INT_SIZE), starts[id], implied[id], implied_stack[id], id);//????
		my_thr_head[id] += INT_SIZE * 2;//
	}
	return 0;
}

void parallel_gen_concepts(ulong *intent, ulong *extent, ulong *extentN, int start_int, int start_bit, int *starts, ulong **implied_recur, ulong ***implied_stack_recur, int rec_level,int id)
{
	int i, total; static int num = 0;//静态变量,统计放入队列中的概念的总数量
	ulong *new_extent, *new_extentN, *new_intent;
	ulong *new_intent_i, *new_intents_head;
	ulong ***implied_stack_i = implied_stack_recur;

	if (rec_level == para_level) //这块完全是普通代码自己实现,放入自己的创建的线程my_thr队中。。。。
	{
		/*
			用到的变量:unsigned char **my_thr, **my_thr_head, **my_thr_limit
			均和线程无关,这里只是建立线程
		*/
		i = num % threads; //void *memcpy(void *dest, const void *src, size_t n);//copy操作。。。
		memcpy((unsigned long *)my_thr[i], intent, B_CNT_AOON);//存数据,先存intent,extent,extentN到my_thr
		my_thr[i] += B_CNT_AOON; //入栈(intent,extent,extentN)

		//再存数据,存start_int start_bit到my_thr
		*(int *)my_thr[i] = start_int; my_thr[i] += INT_SIZE; //my_thr[i]由(char *)转换为(int *) 存放start_int
		*(int *)my_thr[i] = start_bit; my_thr[i] += INT_SIZE;//my_thr[i]由(char *)转换为(int *)存放start_bit
		if (my_thr[i] == my_thr_limit[i])
		{
			int temp_limit = my_thr_limit[i] - my_thr_head[i];
			my_thr_head[i] = (unsigned char *)realloc(my_thr_head[i], temp_limit * 2);//空间多申请一倍???
			my_thr[i] = my_thr_head[i] + temp_limit;
			my_thr_limit[i] = my_thr_head[i] + (temp_limit * 2);//更新限制域
		}
		num++;
		return;
	}

	int *start_i = starts;//用来存放start_int start_bit
	total = start_int * (ARCHBIT + 1) + (ARCHBIT - start_bit);
	new_intent = new_intent_i = new_intents_head =(ulong *)malloc((B_CNT_A + 2 * B_CNT_O) * (attributes - total));
	new_extent = new_intent + int_cnt_a;
	new_extentN = new_extent + int_cnt_o;

	for (; start_int < int_cnt_a; start_int++)
	{
		for (; start_bit >= 0; start_bit--)
		{
			if (total >= attributes)
				goto skipout;
			if (intent[start_int] & (BIT << start_bit))
				goto skip;
			if (implied_recur[total] != NULL)//失效的属性子集implied[total]
			{
				if (implied_recur[total][start_int] & ~(intent[start_int]) & upto_bit[start_bit])
					goto skip;
				for (i = 0; i < start_int; i++)
					if (implied_recur[total][i] & ~(intent[i]))
						goto skip;
			}
			int result = compute_closure(new_extent, new_extentN, extent, extentN, cols[total]);
			if (result == 0)
				goto skip;
			if (result == 1)
			{
				intent[start_int] |= (BIT << start_bit);//将属性j加入B中。。。。
				goto skip;
			}
			if (result == 2)
				to_new_intent(new_intent, new_extent, new_extentN);

			if ((new_intent[start_int] ^ intent[start_int]) & upto_bit[start_bit])
				goto skiptoelse;
			for (i = 0; i < start_int; i++)
				if (new_intent[i] ^ intent[i])
					goto skiptoelse;
			*start_i = start_int;	start_i++;
			*start_i = start_bit;	start_i++;

			print_thread_attributes(new_intent, id);

			//print_attributes(new_intent);
			goto skipoverelse;
		skiptoelse:

			*implied_stack_i = &(implied_recur[total]);//首先让implied_stack_i指向 (implied[total])的地址,即 &(implied[total])
			implied_stack_i++;//然后,局部指针变量implied_stack_i++
			*implied_stack_i = (ulong **)(implied_recur[total]);//这是啥意思??ulong* => ulong**
			implied_stack_i++;//然后,局部指针变量implied_stack_i++
			implied_recur[total] = new_intent;//implied[total]仍是个指针,地址指向new_intent的地址。。。
			new_intent[int_cnt_a - 1] |= BIT;//这样是失效的都赋值为1。。。。
		skipoverelse:
			new_intent = new_extentN + int_cnt_o;//地址移动到下一个概念的地址处。。。
			new_extent = new_intent + int_cnt_a;
			new_extentN = new_extent + int_cnt_o;
		skip:
			total++;
		}
		start_bit = ARCHBIT;
	}

skipout:
	for (; new_intent_i != new_intent; new_intent_i = new_extentN + int_cnt_o)
	{
		//std::cout << "栈中概念个数" << (new_intent - new_intent_i)/(int_cnt_a+int_cnt_o*2) << endl;
		new_extent = new_intent_i + int_cnt_a;
		new_extentN = new_extent + int_cnt_o;
		if (new_intent_i[int_cnt_a - 1] & BIT)//这个最后一个long_size的最低位是标志位,1则代表访问过的失效的概念??? 没有控制好啊。。。。
			continue;

		new_intent_i[*starts] = intent[*starts] | (BIT << *(starts + 1));

		if (*(starts + 1) == 0)
			parallel_gen_concepts(new_intent_i, new_extent, new_extentN, *starts + 1, ARCHBIT, start_i, implied_recur, implied_stack_i, rec_level + 1,id);
		else
			parallel_gen_concepts(new_intent_i, new_extent, new_extentN, *starts, *(starts + 1) - 1, start_i, implied_recur, implied_stack_i, rec_level + 1,id);
		starts += 2;
	}

	for (; implied_stack_recur != implied_stack_i; implied_stack_recur += 2)//若没到implied_stack_i,则implie_stack+=2,地址往下指一步
	{
		**implied_stack_recur = (ulong *)(*(implied_stack_recur + 1));//????
	}

	if (rec_level == 0)
	{
		for (i = 1; i < threads; i++)//从队列my_thr[1*(B_CNT_AOON+INT_SIZE*2)...threads-1*(B_CNT_AOON+INT_SIZE*2)]中取数据。。。
		{
			if (my_thr_head[i] != my_thr[i])//这块用了线程的东西。。。
				thread_id[i] = (HANDLE)_beginthreadex(NULL, 0, thread_func, &thr_index[i], 0, NULL);
		}
		for (; my_thr_head[id] < my_thr[id];)
		{
			memcpy(intents_thr[id], my_thr_head[id], B_CNT_AOON);//从队列my_thr[0**(B_CNT_AOON+INT_SIZE*2)]中取数据。。。
			my_thr_head[id] += B_CNT_AOON;
			gen_concepts(intents_thr[id], intents_thr[id] + int_cnt_a, intents_thr[id] + int_cnt_a + int_cnt_o, *(int *)my_thr_head[id], *(int *)(my_thr_head[id] + INT_SIZE), start_i, implied[id], implied_stack[id], id);
			my_thr_head[id] += INT_SIZE * 2;
		}
	}
	free(new_intents_head);//在这释放申请的空间。。。
	return;
}

void find_all_intents()
{
	starts = (int**)malloc(sizeof(int*)*threads);
	implied = (ulong ***)malloc(sizeof(ulong**)*threads);
	implied_stack = (ulong****)malloc(sizeof(ulong***)*threads);
	///************************************************************
	//申请地址空间():thread_id、thread_i、my_thr my_thr_head、my_thr_limit、intents_thr
	//地址空间就各是各的。。。。
	thread_id = (HANDLE *)malloc(sizeof(HANDLE) * threads);
	std::memset(thread_id, 0, sizeof(HANDLE) * threads);
	thr_index = (int *)malloc(sizeof(int) * threads);
	my_thr = (uchar **)malloc(sizeof(uchar *) * threads);
	my_thr_head = (uchar **)malloc(sizeof(uchar *) * threads);
	my_thr_limit = (uchar **)malloc(sizeof(uchar *) * threads);
	intents_thr = (ulong**)malloc(sizeof(ulong *) * threads);
	//为my_thr[i]、my_thr_head[i]、my_thr_limit[i]申请同一块内存空间
	int queue_size = attributes / threads + 1, last_attrs = attributes - para_level + 1;
	for (int i = 0; i < threads; i++)
	{
		thr_index[i] = i;//这个的作用是??=>指定线程吧,_beginthreadex中用了
		my_thr_limit[i] = my_thr_head[i] = my_thr[i] =(uchar*)malloc((B_CNT_AOON + INT_SIZE * 2)*queue_size);
		my_thr_limit[i] += (B_CNT_AOON + INT_SIZE * 2)*queue_size;
		intents_thr[i] = (ulong*)malloc(B_CNT_AOON);
		//*************************
		starts[i] = (int *)malloc(sizeof(int) * (attributes + 1) * attributes);//内涵多一个标志位,所以要attributes+1???
		implied[i] = (ulong **)malloc(sizeof(ulong *) * attributes);//for for最多存的属性个数的属性子集
		std::memset(implied[i], 0, sizeof(ulong *) * attributes);
		implied_stack[i] = (ulong ***)malloc(sizeof(ulong **) *(attributes + 1)*attributes);//栈中放的属性子集的个数:(attributes+1)*attributes??

	}

	memset(intents_thr[0]+int_cnt_a, 0xFF, B_CNT_O);有问题。。。要再去掉对象为空的那几个1。。。。
	memset(intents_thr[0] + int_cnt_a+int_cnt_o, 0xFF, B_CNT_O);
	for (int i = objects % (ARCHBIT + 1); i <ARCHBIT + 1; i++)//重要,确保A AN C CN多余的那几位全为0
	{
		(intents_thr[0] + int_cnt_a)[int_cnt_o - 1] -= (BIT << i);//重要
		(intents_thr[0] + int_cnt_a+int_cnt_o)[int_cnt_o - 1] -= (BIT << i);//重要
	}
	memset(intents_thr[0], 0, B_CNT_A);//WWWang位全置0

	//print_attributes(intents_thr[0]);
	print_thread_attributes(intents_thr[0], 0);
	if (intents_thr[0][int_cnt_a - 1] & BIT)
		return;

	//gen_concepts主函数。。。。
	//gen_concepts(intents_thr[0], intents_thr[0] + int_cnt_a, intents_thr[0] + int_cnt_a + int_cnt_o, 0, ARCHBIT, starts[0], implied[0], implied_stack[0], 0);
	parallel_gen_concepts(intents_thr[0], intents_thr[0] + int_cnt_a, intents_thr[0] + int_cnt_a + int_cnt_o, 0, ARCHBIT, starts[0], implied[0], implied_stack[0], 0, 0);

	for (int i = 1; i < threads; i++)
	{
		if (thread_id[i])
		{
			WaitForSingleObject(thread_id[i], INFINITE);//等待线程释放
			CloseHandle(thread_id[i]);//关闭线程句柄
		}
	}
	free(intents_thr);//这个貌似很耗时间,难道free用的有问题????
	CloseHandle(out_handle);//关闭输出handle
	for (int i = 0; i < threads; i++)
		fclose(out_thread_file[i]);
}


/*
	五一回家 新问题发现:
	还是闭包那块求错了。。。
	应该分开处理。。。
	先判断new_extent, new_extentN空否,相等否 =》做处理退出否
	再求new_intent,不要早求new_intent,太耗时了。。。。
	这才是真正的部分闭包,
	之前自己写的那种new_extent, new_extentN, new_intent都出来了,不好使,没有严格按照自己伪代码处理。。。
	哎,太挫了。。。

	正常修改
	唯一错误,忘记修改时
	intent最后一位是标志位,要初始为0
	当失效正则检测失败时才手动赋值为1...

	std::memset(intent, 0xFF, B_CNT_A);
	intent[int_cnt_a - 1]--;//初始最低位设置为0,当失效检测失败时,设置为1
	【
		昨天晚上20160421,打印属性放错地了,放在了闭包后
		应该是放在判断BnYj=DnYj等后才看打印
	】

*/

Read.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <string.h>
#include <time.h>
#include <sys/timeb.h>
//#pragma comment(lib,"pthreadVC2.lib") 
using namespace std;
#define BIT		((unsigned long) 1)
#define NULL_LONG	((unsigned long) 0)
#define INT_SIZE	(sizeof (int))
#define LONG_SIZE	(sizeof (unsigned long))
#define ARCHBIT		((LONG_SIZE * 8) - 1)
#define B_CNT_A	(LONG_SIZE * int_cnt_a)
#define B_CNT_O	(LONG_SIZE * int_cnt_o)
#define B_CNT_AOON (B_CNT_A+B_CNT_O*2)
#define BUFFER_BLOCK	1024
#define ulong unsigned long
#define uchar unsigned char
int attributes = 0;
int objects = 0;
int int_cnt_a = 0;
int int_cnt_o = 0;
int table_entries = 0;
int min_support = 0;
unsigned long *context;
unsigned long **cols;
int *attrib_numbers;
int * object_numbers;
unsigned long upto_bit[ARCHBIT + 1];
FILE *in_file;
FILE *out_file;
clock_t t1, t2;
int *buff = NULL;
int buff_index = 0;
size_t buff_size = BUFFER_BLOCK;
int *supps;
int common_s = 0;
int common_ms = 0;


int get_next_integer(FILE *file, int *value)
{
	int ch = ' ';
	*value = -1;
	while ((ch != EOF) && ((ch < '0') || (ch > '9')))
	{
		ch = fgetc(file);
		if (ch == '\n')
			return 1;
	}
	if (ch == EOF)
		return 0;
	*value = 0;
	while ((ch >= '0') && (ch <= '9'))
	{
		*value *= 10;
		*value += ch - '0';
		ch = fgetc(file);
	}
	ungetc(ch, file);
	return 1;
}

void
allocate_buffer(int **buffer, int size)

{
	if (*buffer)
		*buffer = (int *)realloc(*buffer, INT_SIZE * size);
	else
		*buffer = (int *)malloc(INT_SIZE * size);
	if (!*buffer)
	{
		fprintf(stderr, "Cannot reallocate buffer, quitting.");
		exit(3);
	}
}

#define PUSH_NEW_INTEGER(__value) \
  { \
	if (buff_index >= buff_size) { \
      buff_size += BUFFER_BLOCK; \
      allocate_buffer (&buff, buff_size); \
	} \
	buff [buff_index] = (__value); \
	buff_index ++; \
  }

void
read_file(FILE *file)
{
	int last_value = -1, value = 0, last_attribute = -1, last_object = -1;
	allocate_buffer(&buff, buff_size);
	while (get_next_integer(file, &value))
	{
		if ((value < 0) && (last_value < 0))
			continue;
		if (value < 0)
		{
			last_object++;
			PUSH_NEW_INTEGER(-1);
		}
		else
		{
			if (value > last_attribute)
				last_attribute = value;
			PUSH_NEW_INTEGER(value);
		}
		last_value = value;
	}
	if (last_value >= 0)
	{
		last_object++;
		PUSH_NEW_INTEGER(-1);
	}
	objects = last_object + 1;
	attributes = last_attribute + 1;
}

void
create_context(void)
{
	int i = 0, row = 0;
	int_cnt_a = (attributes / (ARCHBIT + 1)) + 1;
	int_cnt_o = (objects / (ARCHBIT + 1)) + 1;
	context = (unsigned long *)malloc(LONG_SIZE * int_cnt_a * objects);
	supps = (int *)malloc(sizeof(int) * attributes);
	memset(supps, 0, sizeof(int) * attributes);
	if (!context)
	{
		fprintf(stderr, "Cannot allocate bitcontext, quitting.");
		exit(5);
	}
	memset(context, 0, LONG_SIZE * int_cnt_a * objects);
	for (i = 0; i < buff_index; i++)
	{
		if (buff[i] < 0)
		{
			row++;
			continue;
		}
		context[row * int_cnt_a + (buff[i] / (ARCHBIT + 1))] |= (BIT << (ARCHBIT - (buff[i] % (ARCHBIT + 1))));
		supps[buff[i]]++;
		table_entries++;
	}
	free(buff);
	fclose(in_file);
}

void initialize_output(void)
{
	int i;
	attrib_numbers = (int *)malloc(sizeof(int) * attributes);
	for (i = 0; i < attributes; i++)
		attrib_numbers[i] = i;
}

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);
		else
			return -1;
	}
	else
	{
		if (y >= min_support)
			return 1;
		else
			return (x < y) ? -1 : ((x > y) ? 1 : 0);
	}
}

int rows_compar(const void *a, const void *b)
{
	int i;
	for (i = 0; i < int_cnt_a; 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 = int_cnt_a;
	int_cnt_a = (attributes / (ARCHBIT + 1)) + 1;
	new_context = (unsigned long *)malloc(LONG_SIZE * int_cnt_a * objects);
	memset(new_context, 0, LONG_SIZE * int_cnt_a * 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 += int_cnt_a)
			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, B_CNT_A, rows_compar);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值