无连接算法(join-less)原理及其实现

首先,介绍一些概念:

  • 星形邻居物化模型:分为相交的和不相交的,不相交的用处更大,更实用
  • 首先人为规定临近距离,黑色实现就表示具有星型临近关系。

    从A的每个实例开始计算,他的邻居实例包括自己已经在内的所有实例,同时邻居实例要比中心实例的字母序大。例如A.3的邻居实例里就不会出现A.4,因为A的字母序没有大于A。

  • 为什么是无连接算法:应用星型划分模型,使用实例查找机制代替实例连接机制。
  • 星型实例:空间实例子集中,所有的实例都是第一个实例的邻居,且这些实例的特征类型是不同的,就称为星型实例。
  • 属性级过滤:如果一个co-location模式的任意子集不是频繁的,那么这个候选就可以被剪枝掉。
  • 粗糙过滤:产生了所有的星型实例后进行,如果参与度不满足所给阈值,这一候选模式就可以剪掉了。
  • 精细过滤:在检验团后获得真实的参与度,之后与阈值比较进行过滤。 

过程太麻烦,不写了,附上代码:

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
double min_prev = 0.3;
char max_trait = 'A';
set<string> trait_set;       //存放所有可能的空间特征
map< char, int> characNum;              //每个空间特征的实例个数
set<string> allSet;             // 每个空间特征的总计数
struct table{
	string name;      
	vector<vector<string> > instance;
	int jie;
	set<string> instance_set;      //  每个候选模式中某个空间特征的实例的集合
	map<char, int> charac_count;   // 候选模式中空间特征的计数
};
map<string,table> table_instance;  //总体结构
map<char, vector< vector<string> > > star_niber;//存放所有的星型邻居
map<string, vector<string> > graph; //存放图结构


void outPut(){  //输出函数
	for (auto it = table_instance.begin(); it != table_instance.end(); it ++) {
		cout << it->first << endl;
		vector<vector<string>> temp = it->second.instance;
		for (int i = 0; i < temp.size(); i++) {
			for (int j = 0; j < temp[i].size(); j++) {
				cout << temp[i][j] << " ";
			}
			cout << endl;
		}
		cout << endl;
	}
}

void check(table t){     //检查参与度,并对三阶及其以上的进行精细过滤
	bool flag = false;
	for (int i = 0; i < t.jie; i ++) {
		double prev = double(t.charac_count[t.name[i]]) / double(characNum[t.name[i]]);  //检查参与度
		if (prev < min_prev) {
			flag = true;
			break;
		}
	}
	if (flag == true) {        //减枝
		for (auto it = trait_set.begin(); it != trait_set.end();) {
			string str = *it;
			if (str.find(t.name) != str.npos) {
				trait_set.erase(it++);
			}else {
				it ++;
			}
		}
	}
	if ( t.jie >= 3) {              //三阶以上精细过滤
		for (int i = 0; i < t.instance.size(); i++) {
			bool newFlag = true;
			vector<string> temp;
			for (int j = 1; j < t.instance[i].size(); j++) {
				temp.push_back(t.instance[i][j]);
			}
			for (auto it = table_instance.begin(); it != table_instance.end(); it ++) {
				if (it->second.name == t.name.substr(1)) {
					vector <vector<string> > comp = it->second.instance;
					for (int k = 0; k < comp.size(); k++) {
						if (comp[k] == temp) {
							newFlag = false;
						}
					}
				}
			}
			if (newFlag == true) {
				t.instance.erase(t.instance.begin() + i);
			}
		}
		t.instance_set.clear();
		t.charac_count.clear();
		for (int i = 0; i < t.instance.size(); i ++) {                //更新新的参与度
			for (int j = 0; j < t.instance[i].size(); j ++) {
				t.instance_set.insert(t.instance[i][j]);
			}
		}
		for (auto it = t.instance_set.begin(); it != t.instance_set.end(); it ++) {
			string str = *it;
			t.charac_count[str[0]] ++;
		}
		for (int i = 0; i < t.jie; i ++) {
			double prev = double(t.charac_count[t.name[i]]) / double(characNum[t.name[i]]);
			if (prev < min_prev) {
				flag = true;
				break;
			}
		}
	}
	if (flag == false) {       //加入可以输出的map中
		table_instance[t.name] = t;
	}
}

void create_star_niber(){             //创建星型邻居的表格
	for (auto it1 = graph.begin(); it1 != graph.end(); it1 ++) {
		char trait = it1->first[0];
		if (trait > max_trait) {
			max_trait = trait;
		}
		vector<string>temp;
		temp.push_back(it1->first);
		for (auto it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
			string str = *it2;
			if (str[0] > trait) {
				temp.push_back(str);
			}
		}
		sort(temp.begin(), temp.end());
		for (int i = 1; i < temp.size(); i++) {
			if (temp[i][0] == temp[i-1][0]) {    //行实例移项,便于处理
				vector<string>newTemp;
				newTemp.push_back(temp[0]);
				newTemp.push_back(temp[i]);
				star_niber[trait].push_back(newTemp);
				temp.erase(temp.begin()+i);
			}
		}
		star_niber[trait].push_back(temp);
	}
}

map<char,bool> m;
void dfs(string result)
{
	bool flag;
	if (result.size() > 1) {
		for (int i = 0; i < result.size()-1; i++) {
			if (result[i] > result[i+1] ) {
				flag = true;
			}
		}
	}
	if (flag == false || result.size() == 1) {
		trait_set.insert(result);
	}
	for(char c = 'A';c <= max_trait;c++)
		{
			if(m[c] == false)
				{
					string s = result + c;
					m[c] = true;
					dfs(s);
					m[c] = false;
				}
		}
}

void get_trait_set(){   //所有可能的特征
	string result = "";
	m.clear();
	dfs(result);
}

void createTable(string str){                 //生成频繁模式
	int count = 0;
	char center = str[0];
	vector< vector<string> > instance;
	set<string> instance_set;
	vector< vector<string> > niberTable = star_niber[center];
	for (auto it1 = niberTable.begin(); it1 != niberTable.end(); it1 ++) {
		vector<string> temp = *it1;
		vector<string> k;
		for (auto it2 = temp.begin(); it2 != temp.end(); it2 ++) {
			string t = *it2;
			if (t[0] == str[count]) {
				count ++;
				k.push_back(t);
//				instance_set.insert(t);
				if (count == str.size()) {
					break;
				}
			}
		}
		if (k.size() == str.size()) {  //避免混入单个
			for (int i = 0; i < k.size(); i ++) {
				instance_set.insert(k[i]);
			}
			instance.push_back(k);
		}
		count = 0;
	}
	table t;                
	t.instance = instance;
	t.name = str;
	t.jie = str.size();
	t.instance_set = instance_set;
	for (auto it = instance_set.begin(); it != instance_set.end(); it ++) {
		string str = *it;
		t.charac_count[str[0]] ++;
	}
	check(t);
}


int main(int argc, char *argv[]) {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		string str1, str2;
		cin >> str1 >> str2;
		allSet.insert(str1);
		graph[str1].push_back(str2);
//		graph[str2].push_back(str1);
	}
	for (auto it = allSet.begin(); it != allSet.end(); it++) {
		string str = *it;
		characNum[str[0]] ++;
	}
	create_star_niber();
	get_trait_set();
	int k = 1;
//	for (auto it = star_niber.begin(); it != star_niber.end(); it ++) {
//		vector<vector <string> > temp = it->second;
//		cout << it->first << endl;
//		for (int i = 0; i < temp.size(); i++) {
//			for (int j = 0; j < temp[i].size(); j++) {
//				cout << temp[i][j] << " ";
//			}
//			cout << endl;
//		}
//	}
	bool flag = true;
	while (flag) {
		flag = false;
		for (auto it = trait_set.begin(); it != trait_set.end(); it ++) {
			string str = *it;
			if (str.size() == k) {
				createTable(str);
				flag = true;
			}
		}
		k++;
	}
	outPut();
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值