批量处理PCbO3C算法20170214

批量处理PCbO3C.cpp:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<sstream>
#include<Windows.h>
using namespace std;
vector<string> vec_string;
int main()
{
	system("color F0");
	//printf("***************批量处理20161107**************\n");
	string bat_fname = "bat.txt";
	ifstream readfile(bat_fname);
	string str;
	while (getline(readfile, str))
	{
		vec_string.push_back(str);
	}
	if (!readfile.is_open())
	{
		cout << "打开批处理文件" << bat_fname << "失败\n";
	}
	else
	{
		readfile.close();//关闭
		
		for (int i = 0; i < vec_string.size(); i++)
		{	//char *ss_fname = const_cast<char *>(vec_string[i].c_str());
			const char *ss_fname = vec_string[i].c_str();
			for (int j = 1; j <= 16; j++)
			{
				//char ss_cmd[5000] = "整理概念格算法20161107.exe ";//错误,为何不能打开,名字改下就行,就是不能用从工程.exe?
				char ss_cmd[5000] = "PCbO3C_bat.exe ";
				strcat(ss_cmd, ss_fname); strcat(ss_cmd, " ");
				stringstream ss;
				ss << j;
				string stri = ss.str();
				const char *ss_threads = stri.c_str();
				strcat(ss_cmd, ss_threads); strcat(ss_cmd, " ");
				char *ss_para_level = "2";
				strcat(ss_cmd, ss_para_level);
				remove("test");
				WinExec(LPCSTR(ss_cmd), SW_SHOWMAXIMIZED);
				readfile.open("test");
				
				while (!readfile.is_open())//等待FCbO20160420.exe结束
				{
					Sleep(1000);
					readfile.open("test");
				}
				readfile.close();
				Sleep(1000);
				cout << "\n\n";
			}
		}
	}
	system("pause");
	return 0;
}

bat.txt:

cuxin.dat
cdat_lung-cancer.dat
cdat_nursery.dat
mush.dat
...

PCbO3C_bat.cpp:

#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";*/

	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;
}

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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值