3阶有向完全图的所有非同构的子图(不同钩子图个数)

子图同构问题本质上就是一种匹配,VF2算法加了很多feasibilityrules,保证了算法的高效性。这里只是实现最基本的判断子图同构的算法:参考文献有(其实google一把就能出来这些):http://stackoverflow.com/questions/8176298/vf2-algorithm-steps-with-examplehttp://www.zhihu

大家好,又见面了,我是你们的朋友全栈君。

子图同构问题本质上就是一种匹配,VF2算法加了很多feasibility rules,保证了算法的高效性。这里只是实现最基本的判断子图同构的算法:

参考文献有(其实google一把就能出来这些):

http://stackoverflow.com/questions/8176298/vf2-algorithm-steps-with-example

http://www.zhihu.com/question/27071897

https://github.com/fozziethebeat/S-Space/tree/master/src/main/java/edu/ucla/sspace/graph/isomorphism

http://stackoverflow.com/questions/6743894/any-working-example-of-vf2-algorithm/6744603

Luigi P. Cordella,Pasquale Foggia,Carlo Sansone,Mario Vento: A (Sub)Graph Isomorphism Algorithm for Matching Large Graphs.IEEE Trans. Pattern Anal. Mach. Intell. 26(10): 1367-1372 (2004)

第一个链接给了一个示例:

http://stackoverflow.com/questions/8176298/vf2-algorithm-steps-with-example:

I will try to give you a quick explaination of my previous answer to this question :

Any working example of VF2 algorithm?

I will use the same example as the one in my previous answer :

enter image description here

The 2 graphs above are V and V’ .(V’ is not in the drawing but it’s the one on the right)

The VF2 algorithm is described in the graph.

Step by step

I want to know if V and V’ are isomorphic.

I will use the following notations : XV is the node X in V

In the VF2 algoritm I will try to match each node in V with a node in V’.

step 1 :

I match empty V with empty V’ : it always works

step 2 : I can match 1V with 1V’,2V’ or 3V’

I match 1V witch 1V’ : it always works

step 3 :

I can match 2V with 2V’ or 3V’

I match 2V with 2V’ : it works because {1V 2V} and {1V’ 2V} are isomorphic

step 4 :

I try to match 3V with a node in V’ : I cannot! {it would be possible if their was an edge between node 3 and 2 in V’, and no edge between 3 and 1)

So I go back to step 2

step 5:

I match 2V with 3V’

step 6:

same as step 4

I go back to step 2. there is no solution in step 2 , I go back to step 1

step 7:

I match 1V with 2V’

step 8:

I match 2V with 1V’

step 9 :

I match 3V with 3V’

it works I matched {1V 2V 3V} with { 2V’ 1V’ 3V’}

The graphs are isomorphic.

If I test all the solution and it never works the graph would not be isomorphic.

Hope this helps


About you’re question on “matching”, have a look at the wikipedia article on graph isomorphis :

http://en.wikipedia.org/wiki/Graph_isomorphism

this is a good example of a function f that matches graph G and H : enter image description here

Hope you can better understand this algorithm with this illustration.

下面给出我的算法设计(这里考虑边和点除了ID之外,还有label):

边和图结构:

struct EDGE
{
	int id2;
	int label;
	EDGE(int _id2, int _label)
	{
		id2=_id2;
		label=_label;
	}
};


//邻接链表结构,不过是用vector来实现
struct GRAPH
{
	int graphID;
	vector<int> vID;
	vector<int> vLabel;


	vector<vector<EDGE> > vAdjacencyEdge;
	//外面的大vector< >,为每一个节点保存一个邻接表,一个图中有多少个节点,vAdjacencyEdge的size就是多少
	//vector<EDGE>存放EDGE[id2,label]组元,表示每个节点对应的兄弟节点id以及这两个节点间的边的label,
	//vector<EDGE>大小由每个节点的兄弟数量决定(这里所谓的兄弟,就是指“邻接点”)
	//因为可行pair(m,n)就是从当前状态M(s)的邻接点中寻找的,所以该结构能够加快搜索速度
};

每一个match结构:

//match结构,对应论文中提到的core_1 and core_2,
//whose dimensions correspond to the number of nodes in G1 and G2
struct MATCH
{
	//int *dbMATCHqu; //存储DB中的节点id和与之match的QU中的节点id
	//int *quMATCHdb; //存储QU中的节点id和与之match的DB中的节点id
	//使用map编程更方便,查找速度更快!
	map<int, int> dbMATCHqu;
	map<int, int> quMATCHdb;
};

从文件中读取数据(主要是保证每个点的邻接边/点能够按照struct GRAPH正确存储):

vector<GRAPH *> ReadGraph(const char *filename)
{
	FILE *fp = fopen(filename, "r");
	/*
	if (!fp)
	{
		printf("fp is NULL, file [%s] doesn't exist...\n", filename);
		return;
	}
	*/

	EDGE e(-1,-1);
	vector<EDGE> v;
	v.push_back(e);

	char mark[2];
	int id,label,id2;
	vector<GRAPH *> gSet;
	GRAPH * g = NULL;
	while(true)
	{
		fscanf(fp, "%s", mark);
		if(mark[0]=='t')
		{
			
			fscanf(fp, "%s%d", mark, &id);
			if(id==-1)
			{
				gSet.push_back(g);
				break;
			}
			else //if input not ending, then
			{				
				if(g!=NULL)
				{
					gSet.push_back(g);
				}
				g = new GRAPH;
				g->graphID=id;
			}
		}
		else if(mark[0]=='v')
		{
			fscanf(fp, "%d%d", &id, &label);
			g->vID.push_back(id);
			g->vLabel.push_back(label);

			g->vAdjacencyEdge.push_back(v);//为每个节点申请一个vAdjacencyEdge,其中v只是占用位置,没有任何用处!
		}
		else if(mark[0]=='e')
		{
			fscanf(fp, "%d%d%d", &id, &id2, &label);

			e.id2=id2; e.label=label;
			g->vAdjacencyEdge[id].push_back(e);//id->id2的边
			e.id2=id; e.label=label;
			g->vAdjacencyEdge[id2].push_back(e);//id2->id的边
		}
	}

	fclose(fp);
	printf("graph number:%d\n", gSet.size());
	return gSet;

}

判断一个候选pair是否满足feasibility rules:

//其实 pair(quG->vID[i], dbG->vID[j])就是一个候选pair candidate
//判断该候选pair是否满足feasibility rules
bool FeasibilityRules(GRAPH *quG, GRAPH *dbG, MATCH match, int quG_vID, int dbG_vID)
{
	int quVid,dbVid,quGadjacencyEdgeSize,dbGadjacencyEdgeSize,i,j;
	bool flag=false;

	//首先,判断quG_vID和dbG_vID对应的label是否相同
	if(quG->vLabel[quG_vID]!=dbG->vLabel[dbG_vID]) //如果两个点的label不同,则【一定不】满足feasibility rules
	{
		return false;
	}
	
	//其次,判断是不是每次match的第一个比较pair
	if(match.quMATCHdb.size()==0) //如果是第一个比较pair
	{
		//只需要这两个点的label相同(已经判断成立了)即满足feasibility rules
		return true;
	}

	//最后(label相同,不是第一个pair【即,之前已经match了一部分节点】),那么只要下面条件成立就能满足最简单的feasibility rules:
	//1)quG_vID和dbG_vID与已经match的那些节点对中的【至少】一对(quVid,dbVid)分别相邻(quG_vID和dbG_vID分别是已经match的节点quVid和dbVid的“neighbor节点”)
	//2)如果存在多个相邻对(quVid,dbVid),则必须要求【所有的】邻接边对( edge(quG_vID,quVid), edge(dbG_vID,dbVid) )的label一样
	for(map<int, int>::iterator iter=match.quMATCHdb.begin();iter!=match.quMATCHdb.end();iter++) //遍历所有的已经match的节点对
	{
		quVid=iter->first;
		quGadjacencyEdgeSize=quG->vAdjacencyEdge[quVid].size();
		for(i=1;i<quGadjacencyEdgeSize;i++) //从1开始依次扫描quVid的邻接点,第0个存的是(-1,-1)
		{
			//quG_vID是已经match的quG中的节点quVid的“第i个neighbor节点”
			if( quG->vAdjacencyEdge[quVid][i].id2==quG_vID ) 
			{
				dbVid=iter->second;
				dbGadjacencyEdgeSize=dbG->vAdjacencyEdge[dbVid].size();
				for(j=1;j<dbGadjacencyEdgeSize;j++) //从1开始依次扫描dbVid的邻接点,第0个存的是(-1,-1)
				{
					//同时,与quVid相match的节点dbVid在dbG中的“第j个neighbor节点”正好是dbG_vID
					if( dbG->vAdjacencyEdge[dbVid][j].id2==dbG_vID )
					{
						//判断2)是否成立
						if( quG->vAdjacencyEdge[quVid][i].label != dbG->vAdjacencyEdge[dbVid][j].label )
						{
							//因为2)要求【所有的】label一样,只要有一个不一样,则返回false
							return false;
						}
						else
						{
							//标记:flag=true表示至少有一对满足1)的pair(dbVid,quVid),同时满足了2)
							//因为有可能循环结束了,在所有的已经match的节点对里,找不到一个pair(dbVid,quVid)同时满足条件1)和2)
							flag=true;
						}
					}
				}
			}
		}
	}
	return flag;
}

最后给出该算法的伪代码:

3阶有向完全图的所有非同构的子图(不同钩子图个数)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127834.html原文链接:https://javaforall.net

(1)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • html给网页添加背景音乐_网页怎么在属性里加入音乐

    html给网页添加背景音乐_网页怎么在属性里加入音乐方式一:<videocontrols=””autoplay=””name=”media”><sourcesrc=”音乐”type=”audio/mpeg”></video><videocontrols=”true”autoplay=”true”name=”media”loop=”true”hidden=”true”…

    2022年9月24日
    4
  • Adobe dreamweaver CS6小白入门教程「建议收藏」

    Adobe dreamweaver CS6小白入门教程「建议收藏」1.界面认识2.创建站点:(针对复杂网站使用)站点是一系列文档的组合,这些文档通过各种链接建立逻辑关联。是管理网页文档场所。DWCS6是一个站点创建和管理工具,使用它不仅可以创建单独文档,还可以创建完整的站点。创建网页:新建。3.管理站点的操作:打开站点、编辑站点、删除站点、复制站点、导入导出站点4.管理站点中的文件1.创建文件夹和文件…

    2022年6月12日
    56
  • 杂项-黑苹果安装教程「建议收藏」

    杂项-黑苹果安装教程「建议收藏」说明黑苹果安装步骤笔记准备工作:一台电脑(预装Win10),一个8g及以上的U盘(10.15+版本的系统需要更大的U盘),一块硬盘或一个30g以上的分区,一双手,一个大脑。测试用例主要硬件机器:台式组装机主板:技嘉h110m-SCPU:3.19GHzIntelCorei5显卡:IntelHDGraphics530+NVIDIAGeForceGT730硬盘:GALAXTA1D0120A+西数机械盘500G网卡:RealtekRTL8168G/81

    2022年5月6日
    329
  • SSH+activity工作流集成开发「建议收藏」

    SSH+activity工作流集成开发「建议收藏」一直没有更新最近,把以前的资料整理下。SSH的集成配置清查看上一篇struts-2.3.24+spring-framework-4.1.6.RELEASE+hibernate-release-4.3.10.Final集成开发导入activity工作流需要的jaractiviti-bpmn-converter-5.16.4.jaractiviti-bpmn-layout-5

    2022年5月18日
    42
  • R-L模型算法的优缺点_模型解题

    R-L模型算法的优缺点_模型解题@[TOC]LR模型相关知识点#1.LR归一化问题,什么情况可以不归一化,什么情况必须归一化,#2.为什么提到LR损失函数要能知道交叉熵,为什么是它,以它为损失函数在优化的是一个什么东西,知道它和KL散度以及相对熵的关系#3.提到LR的求解方法,比如SGD,知道SGD和BGD的区别,知道不同的GD方法有什么区别和联系,二阶优化算法知道什么,对比offlinelearning和onlinelearning的区别#4.提到调参,知道模型不同超参数的含义,以及给定一个特定情况,大概要调整哪些参数,怎么

    2022年10月10日
    5
  • beanutils.copyproperties原理_beanutils工具类

    beanutils.copyproperties原理_beanutils工具类常用的BeanUtils.copyProperties方法,你知道它的实现原理吗?

    2022年10月3日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号