CbO層次遍歷?

#include "fcbo_no_ny_breadth1.h"
void find_all_intents(void);
void insert_node(unsigned long * intent, unsigned long * extent, int start_int, int start_bit);
void generate_from_node(unsigned long *intent, unsigned long *extent, int start_int, int start_bit);
struct queue_node_t
{
	unsigned long *intent;
	unsigned long *extent;
	int start_int;
	int start_bit;
	queue_node_t* next;
};
struct queue_node_concept
{
	queue_node_t* front;
	queue_node_t* rear;
} concept_queue = { NULL, NULL};

int main(int argc, char **argv)
{
	//in_file = fopen("cdat_nursery.dat", "rb");
	in_file = fopen("cdat_hebingAE_cuxin.dat", "rb");
	out_file = fopen("out_file", "wb");
	if (in_file == NULL)
		return -1;
	read_file(in_file);//
	create_context();//
	free(buff);//
	fclose(in_file);//
	initialize_output();//
	sort_context();//
	initialize_algorithm();//

	clock_t start = clock();
	find_all_intents();
	clock_t finish = clock();

	fclose(out_file);
	printf("概念個數:%d, 時間%f秒\n",countNum,(finish-start)*1.0/CLOCKS_PER_SEC);
	system("pause");
	return 0;
}
/*
層次遍歷? “類”層次遍歷吧  因爲儘管是層次遍歷,但是對構成的格來說不是走的層次
空
空:01 2 3 4  
01:012 0134 014  
2:
3:34
4:
012:01234 0124 
0134:
014:
34:
01234:
0124:
概念個數:11, 時間0.008000秒
*/

void find_all_intents(void)
{
	unsigned long *extent;
	unsigned long *intent;
	intent = (unsigned long *)malloc(BYTE_COUNT_A + BYTE_COUNT_O);
	extent = intent + int_count_a;
	compute_closure(intent, extent, NULL, NULL);
	print_attributes(intent,true);
	//print_objects(extent,true);
	if (intent[int_count_a - 1] & BIT)
		return;
	//新建queue_node_t類型指針p,tmp
	queue_node_t *p, *tmp;
	p = concept_queue.front = concept_queue.rear = (queue_node_t*)malloc(sizeof(struct queue_node_t));

	p->intent = intent;	p->extent = extent;
	p->start_int = 0; p->start_bit = ARCHBIT;
	p->next = NULL;
	while (p)
	{
		generate_from_node(p->intent, p->extent, p->start_int, p->start_bit);
		
		tmp = p;//暫存當前指針p
		p = p->next;//p指向下next

		free(tmp->intent);
		free(tmp);
	}
}

// 去掉新條件Ny(即implied),只有cbo原始條件;廣度;單結點、單概念分配內存,用完釋放
void generate_from_node(unsigned long *intent, unsigned long *extent, int start_int, int start_bit)
{
	printf("\n\n當前父概念:"); print_attributes(intent,false);
	//print_objects(extent, false);
	unsigned long *new_extent, *new_intent;	int i, total;
	total = start_int * (ARCHBIT + 1) + (ARCHBIT - start_bit);//即剩餘屬性個數。。。
	for (; start_int < int_count_a; start_int++)
	{
		for (; start_bit >= 0; start_bit--)
		{
			if (total >= attributes)//遍歷完了
				goto skipout;
			if (intent[start_int] & (BIT << start_bit))
				goto skip;
			new_intent = (unsigned long *)malloc(BYTE_COUNT_A + BYTE_COUNT_O);//重新申請內存。。。
			new_extent = new_intent + int_count_a;
			compute_closure(new_intent, new_extent, extent, cols[total]);//計算閉包
			if ((new_intent[start_int] ^ intent[start_int]) & upto_bit[start_bit])//BnYj不屬於DnYj
				goto skiptoelse;
			for (i = 0; i < start_int; i++)//BnYj不屬於DnYj
				if (new_intent[i] ^ intent[i])
					goto skiptoelse;
			print_attributes(new_intent,true);//打印概念的內涵
			//print_objects(new_extent,true);
			if (start_bit == 0)
				insert_node(new_intent, new_extent, start_int + 1, ARCHBIT);//注意這不是遞歸,而是自己的方法
			else
				insert_node(new_intent, new_extent, start_int, start_bit - 1);
			goto skip;
		skiptoelse:
			free(new_intent);
		skip:
			total++;
		}
		start_bit = ARCHBIT;
	}
skipout:
	return;
}

//自己的insert_node方法,僅僅更新概念指針concept_queue
void insert_node(unsigned long * intent, unsigned long * extent, int start_int, int start_bit)
{
	queue_node_t* current= (queue_node_t*)malloc(sizeof(struct queue_node_t));//新建queue_node_t類型指針,並申請相應大小的內存
	current->intent = intent;current->extent = extent;
	current->start_int = start_int;	current->start_bit = start_bit;
	current->next = NULL;

	concept_queue.rear->next = current;	
	concept_queue.rear = current;
	return;
}


fcbo_no_ny_breadth1.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 BYTE_COUNT_A	(LONG_SIZE * int_count_a)
#define BYTE_COUNT_O	(LONG_SIZE * int_count_o)
#define BUFFER_BLOCK	1024
struct stats_t
{
	int total; int closures; int fail_canon; int fail_fcbo; int fail_support;
} stats = { 0, 0, 0, 0, 0 };
int *buff = NULL;
int buff_index = 0;
size_t buff_size = BUFFER_BLOCK;
int attributes = 0;
int objects = 0;
int int_count_a = 0;
int int_count_o = 0;
int table_entries = 0;
int min_support = 0;
unsigned long *context;
unsigned long **cols;
int *supps;
int *attrib_numbers;
unsigned long upto_bit[ARCHBIT + 1];
int attr_offset = 0;
FILE *in_file;
FILE *out_file;

int verbosity_level = 1;
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);
	*value -= attr_offset;
	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_count_a = (attributes / (ARCHBIT + 1)) + 1;
	int_count_o = (objects / (ARCHBIT + 1)) + 1;
	context = (unsigned long *)malloc(LONG_SIZE * int_count_a * objects);
	if (!context)
	{
		fprintf(stderr, "Cannot allocate bitcontext, quitting.");
		exit(5);
	}
	memset(context, 0, LONG_SIZE * int_count_a * objects);
	supps = (int *)malloc(sizeof(int) * attributes);
	memset(supps, 0, sizeof(int) * attributes);
	for (i = 0; i < buff_index; i++)
	{
		if (buff[i] < 0)
		{
			row++;
			continue;
		}
		context[row * int_count_a + (buff[i] / (ARCHBIT + 1))] |= (BIT << (ARCHBIT - (buff[i] % (ARCHBIT + 1))));
		supps[buff[i]]++;
		table_entries++;
	}
	if (verbosity_level >= 2)
		fprintf(stderr, "objects: %6i\nattributes: %4i\nentries: %8i\n", objects, attributes, table_entries);
}

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

void print_attributes(unsigned long *set, size_t supp)
{
	int i, j, c;
	int first = 1;
	if (verbosity_level <= 0)
		return;
	for (c = j = 0; j < int_count_a; j++)
	{
		for (i = ARCHBIT; i >= 0; i--)
		{
			if (set[j] & (BIT << i))
			{
				if (!first)
					fprintf(out_file, " ");
				fprintf(out_file, "%i", attrib_numbers[c]);
				first = 0;
			}
			c++;
			if (c >= attributes)
				goto out;
		}
	}
out:
	fprintf(out_file, "\n");
}

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

void initialize_algorithm(void)
{
	int i, j, k, x, y;
	unsigned long *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 = (unsigned long *)malloc(LONG_SIZE * int_count_o * attributes);
	memset(cols_buff, 0, LONG_SIZE * int_count_o * attributes);
	cols = (unsigned long **)malloc(sizeof(unsigned long *) * attributes);
	ptr = cols_buff;
	for (k = j = 0; j < int_count_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_count_a)
				if (context[y] & mask)
					ptr[x / (ARCHBIT + 1)] |= BIT << (x % (ARCHBIT + 1));
			ptr += int_count_o;
		}
}


void compute_closure(unsigned long *intent, unsigned long * extent, unsigned long * prev_extent, unsigned long * attr_extent, int * supp)
{
	int i, j, k, l;
	stats.closures++;
	memset(intent, 0xFF, BYTE_COUNT_A);
	if (attr_extent)
	{
		*supp = 0;
		for (k = 0; k < int_count_o; k++)
		{
			extent[k] = prev_extent[k] & attr_extent[k];
			if (extent[k])
				for (l = 0; l <= ARCHBIT; l++)
				{
					if (extent[k] >> l)
					{
						if ((extent[k] >> l) & BIT)
						{
							(*supp)++;
							for (i = 0, j = int_count_a * (k * (ARCHBIT + 1) + l); i < int_count_a; i++, j++)
								intent[i] &= context[j];
						}
					}
					else
						break;
				}
		}
	}
	else
	{
		memset(extent, 0xFF, BYTE_COUNT_O);
		for (j = 0; j < objects; j++)
		{
			for (i = 0; i < int_count_a; i++)
				intent[i] &= context[int_count_a * j + i];
		}
	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章