精华内容
下载资源
问答
  • 求一个 至少包含m条边的同构子图 且是二分图 输出二分图的 X点集 和 Y点集   思路: 非正解 我们可以先随机出一组解,再判断这组解是否可行(估测可行解空间较大) #include #include #include #include

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2141

    题意:

    给定n个点 m条无向边的无向图

    求一个 至少包含m条边的同构子图 且是二分图

    输出二分图的 X点集 和 Y点集

     

    思路:

    非正解

    我们可以先随机出一组解,再判断这组解是否可行(估测可行解空间较大)


    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    using namespace std;
    #define N 105
    
    bool s[N];
    int n, m;
    int Stack[N], top, nowlen;
    struct node{
    	int u,v;
    }edge[10096];
    int edgenum;
    void put(bool hehe){
    	top = 0;
    	for(int i=1;i<=n;i++)if(s[i] == hehe)Stack[top++] = i;  
    	printf("%d",top);       
    	if(top)sort(Stack, Stack+top);
    	while(top--)printf(" %d",Stack[top]);   printf("\n");  
    }
    
    int main(){
    	int T, i;scanf("%d",&T);
    	while(T--){		
    		edgenum = nowlen = 0;
    		scanf("%d %d",&n,&m);
    
    		for(i = 0; i < m; i++)
    		{
    			scanf("%d %d",&edge[edgenum].u,&edge[edgenum].v);
    			edgenum++;
    		}
    		while(nowlen<m/2)
    		{
    			nowlen = 0;
    			for(i=1;i<=n;i++)	s[i] = (rand())&1;
    			for(i=0;i<edgenum;i++)	nowlen+=s[ edge[i].u ] ^ s[edge[i].v ];
    		}
    		put(true);
    		put(false);
    	}
    	return 0;
    }
    

    展开全文
  • 我在做一个查询子图同构的程序的时候(已实现),遇到了一个错误AttributeError: 'Graph' object has no attribute 'pred' 后来检查代码发现是因为代码 # 创建网络有向图g_network g_network = nx.DiGraph() g_...

    仅供参考

    我在做一个查询子图同构的程序的时候(已实现),遇到了一个错误AttributeError: 'Graph' object has no attribute 'pred'

    后来检查代码发现是因为代码

    # 创建网络有向图g_network
    g_network = nx.DiGraph()
    g_network.add_edges_from(data_network)
    
    # 创建model有向图g_model
    g_model = nx.Graph()
    g_model.add_edges_from(mo_model)

    中,我明明知道要建的是一个有向图,但是我却使用了

    g_model = nx.Graph()

    这行代码创建了一个图。试想,我们怎么能随随便便的比较两个不同种类的东西呢?

    改正之后

    # 创建网络有向图g_network
    g_network = nx.DiGraph()
    g_network.add_edges_from(data_network)
    
    # 创建model有向图g_model
    g_model = nx.DiGraph()
    g_model.add_edges_from(mo_model)

    运行

    问题解决了!

     

    在此,我想说的是,我出现的问题不一定是你们的问题,如果不是请多多包容。

    但是,我想说的是,自己写的代码出现问题,首先要仔细检查自己的代码 。说实话计算机、程序“犯错”的概率,如果程序在某些已经被多人认同和验证的情况下,他们很少犯错的。大多数情况都是自己的原因,仔细、耐心的从各方面寻找解决问题的方法并解决问题,也是一种能力。多多训练这种能力,对我们大有脾益!

     

    展开全文
  • 1.子图同构问题描述​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。​ 精确点:一个图由集合和集合组成,是节点(node)集合,...

    1.子图同构问题描述

    ​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。

    ​ 精确点:一个图

    equation?tex=G%3D%28V%2CE%29由集合
    equation?tex=V和集合
    equation?tex=E组成,
    equation?tex=V是节点(node)集合,
    equation?tex=E是边(edge)集合,且
    equation?tex=E%5Csubset+V%5Ctimes+V ,用
    equation?tex=L_v表示节点上的标签集合,
    equation?tex=L_e表示边上的标签集合,那么每个节点对应的标签由函数(或者说映射)
    equation?tex=%5Clambda_v%3AV%5Crightarrow+L_v 确定,每条边对应的标签由函数
    equation?tex=%5Clambda_e%3AE%5Crightarrow+L_e 确定。

    ​ 现在给定两个图

    equation?tex=G_1%3D%28V_1%2CE_1%29,
    equation?tex=G_2%3D%28V_2%2CE_2%29 ,其中
    equation?tex=G_1是比较小的图(我们把它叫做pattern graph),
    equation?tex=G_2是比较大的图(我们把它叫做target graph),用集合
    equation?tex=M%5Csubset+V_1%5Ctimes+V_2 表示两个图中节点的对应关系。如果节点
    equation?tex=u%5Cin+V_1,则
    equation?tex=%5Cmu%28u%29%5Cin+V_2表示与节点
    equation?tex=u对应的
    equation?tex=G_2中的节点;如果节点
    equation?tex=v%5Cin+V_2,则
    equation?tex=%5Cnu%28v%29%5Cin+V_1表示与节点
    equation?tex=v对应的
    equation?tex=G_1中的节点。

    equation?tex=%5Cbegin%7Barray%7D%5Bb%5D+%7B%7Cc%7Cc%7C%7D++%5Chline++%26+G_1+%26+G_2+%5C%5C++%5Chline+%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB++%26+u+%26+%5Cmu%28u%29++%5C%5C++%5Chline+%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB++%26+%5Cmu%5E%7B-1%7D+%28v%29+%26+v++%5C%5C+%5Chline+%5Cend%7Barray%7D%5C%5C

    ​ 如果以下6个条件成立,则这两个图是子图同构的。

    1. equation?tex=%5Cforall+u%5Cin+V_1++%5Cquad++%5Cexists+%5Cmu%28u%29%5Cin+V_2%3A%28u%2C%5Cmu%28u%29%29%5Cin+M+%5C%5C
    2. equation?tex=%5Cforall+u%2Cu%5E%7B%27%7D%5Cin+V_1++%5Cquad++u%5Cneq+u%5E%7B%27%7D%5CRightarrow+%5Cmu%28u%29%5Cneq+%5Cmu%28u%5E%7B%27%7D%29++%5C%5C
    3. equation?tex=%5Cforall+%28u%2Cu%5E%7B%27%7D%29%5Cin+E_1++%5Cquad+%5Cexists+%28%5Cmu%28u%29%2C%5Cmu%28u%5E%7B%27%7D%29%29%5Cin+E_2%29+%5C%5C
    4. equation?tex=%5Cforall+u%2Cu%5E%7B%27%7D+%5Cin+V_1++%5Cquad++%28%5Cmu%28u%29%2C%5Cmu%28u%5E%7B%27%7D%29%29+%5Cin+E_2+%5CRightarrow+%28u%2Cu%5E%7B%27%7D%29+%5Cin+E_1+%5C%5C
    5. equation?tex=%5Cforall+u+%5Cin+V_1++%5Cquad++%5Clambda_%7BV_1%7D%28u%29%3D%5Clambda_%7BV_2%7D%28%5Cmu%28u%29%29+%5C%5C
    6. equation?tex=%5Cforall+%28u%2Cu%5E%7B%27%7D%29+%5Cin+E_1++%5Cquad++%5Clambda_%7Be_1%7D%28u%2Cu%5E%7B%27%7D%29%3D%5Clambda_%7Be_2%7D%28%5Cmu%28u%29%2C%5Cmu%28u%5E%7B%27%7D%29%29+%5C%5C

    用人话来解释一下:

    1. 对于小图中每个节点,大图中都要有一个对应的节点与之对应,并且这样一对一对的节点构成了集合
      equation?tex=M
    2. 小图中任意两个不一样的节点,他们对应的大图中的节点不能是同一个;
    3. 小图中每条边,大图中都有一条边与之对应,并且他们两端的节点一一对应;
    4. 小图中任意两个节点,如果他们对应的大图中的节点之间有一条边,那么小图中这两个节点之间也得有条边;
    5. 每对对应节点的label要相同,也就是这俩节点类型或属性相同;
    6. 每对对应边的label要相同,也就是说这俩边的类型或属性相同。

    ​ 综上所述,子图同构简单来说就是,大图中有一个子结构,长得跟小图一模一样,而且这个子结构的节点之间不能多出小图中不存在的边来,如果要去掉最后这个而且,就把上面第4个条件去掉~

    2.VF3算法

    ​ VF3算法的目标是,给定一个小图和一个大图,找出大图中所有与小图同构的子图,这是一个NP-hard问题。整体上,VF3算法是一个树搜索算法,并且想办法去尽可能剪枝。搜索树上的每个节点都是一个状态(state),记为

    equation?tex=s,每个
    equation?tex=s中包含一系列节点的映射关系,可以想象成一系列key-value对,key都是小图中的节点,value都是大图中的节点。搜索最开始的时候(也就是树的根节点)
    equation?tex=s中什么都没有,随着搜索的进行(树高度的增加),
    equation?tex=s中的key-value对会一对对增加,假如这个状态中所有的节点对都满足第一节中的6条约束,我们称这个状态为一致状态(consistent state);如果一个一致状态包含的小图中所有的节点,那意味着我们找到了一个大图的子结构与小图同构,称之为目标状态(goal state);如果一个状态是不可能再派生出一致状态的,我们称之为死亡状态(dead state)。

    ​ 那么现在最大的问题就是两个:

    1. 这棵搜索树怎么组织?
    2. 怎么设计剪枝规则?

    下面逐个展开~

    A. 总体流程介绍

    先来介绍一些符号:

    equation?tex=%5Ctilde%7BM%7D%28s%29表示状态
    equation?tex=s中的节点映射集合,则
    equation?tex=%5Ctilde%7BM%7D%28s%29+%5Csubseteq+M

    equation?tex=%5Ctilde%7BM_1%7D%28s%29表示
    equation?tex=%5Ctilde%7BM%7D%28s%29中属于
    equation?tex=G_1的节点,也就是所有的key,严格点:
    equation?tex=%5Ctilde%7BM_1%7D%28s%29%3D%5C%7Bu%5Cin+V_1%3A%5Cexists+%28u%2Cv%29%5Cin+%5Ctilde%7BM%7D%28s%29%2Cv%5Cin+V_2%5C%7D

    equation?tex=%5Ctilde%7BM_2%7D%28s%29表示
    equation?tex=%5Ctilde%7BM%7D%28s%29中属于
    equation?tex=G_2的节点,也就是所有的value,严格点:
    equation?tex=%5Ctilde%7BM_2%7D%28s%29%3D%5C%7Bv%5Cin+V_2%3A%5Cexists+%28u%2Cv%29%5Cin+%5Ctilde%7BM%7D%28s%29%2Cu%5Cin+V_1%5C%7D

    equation?tex=%5Ctilde%7BG%7D_1%28s%29表示仅包含节点在
    equation?tex=%5Ctilde%7BM_1%7D%28s%29中的
    equation?tex=G_1的子图,也就是比
    equation?tex=%5Ctilde%7BM_1%7D%28s%29加上了边;

    equation?tex=%5Ctilde%7BG%7D_2%28s%29表示仅包含节点在
    equation?tex=%5Ctilde%7BM_2%7D%28s%29中的
    equation?tex=G_2的子图,也就是比
    equation?tex=%5Ctilde%7BM_2%7D%28s%29加上了边;

    equation?tex=%5Ctilde%7B%5Cmu%7D%28s%2Cu%29表示
    equation?tex=%5Ctilde%7BM%7D%28s%29中与
    equation?tex=u对应的节点,其中
    equation?tex=u%5Cin+V_1,
    equation?tex=%5Ctilde%7B%5Cmu%7D%28s%2Cu%29%5Cin+V_2

    equation?tex=%5Ctilde%7B%5Cmu%7D%5E%7B-1%7D%28s%2Cv%29表示
    equation?tex=%5Ctilde%7BM%7D%28s%29中与
    equation?tex=v对应的节点,其中
    equation?tex=%5Ctilde%7B%5Cmu%7D%5E%7B-1%7D%28s%2Cv%29%5Cin+V_1,
    equation?tex=v%5Cin+V_2

    equation?tex=%5Cbegin%7Barray%7D%5Bb%5D+%7B%7Cc%7Cc%7C%7D++%5Chline++%26+V_1+%26+V_2+%5C%5C++%5Chline+%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB++%26+u+%26+%5Cmu%28s%2Cu%29++%5C%5C++%5Chline+%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB++%26+%5Cmu%5E%7B-1%7D+%28s%2Cv%29+%26+v++%5C%5C+%5Chline+%5Cend%7Barray%7D%5C%5C

    大致看一下整个流程,上伪代码~

    VF3总流程

    1:

    equation?tex=function+%5C+%5C+VF3%28G_1%2CG_2%29

    2:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+Solutions%3D%5Cphi

    3:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+P_f%3DComputeProbabilitys%28G_1%2CG_2%29

    4:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+N_%7BG_1%7D%3DGenerateNodeSequence%28G_1%2CP_%7Bfeas%7D%29

    5:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+ClassifyNodes%28G_1%2CG_2%29

    6:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%28s_0%2CParent%29%3DPreProcessPatternGraph%28G_1%2CN_%7BG_1%7D%29

    7:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+Match%28s_0%2CG_2%2CG_1%2CN_%7BG_1%7D%2CParent%2CSolutions%29

    8:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+return+%5C+%5C+Solutions

    匹配函数

    1:

    equation?tex=function+%5C+%5C+Match%28s_0%2CG_2%2CG_1%2CN_%7BG_1%7D%2CParent%2CSolutions%29

    2:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+if+%5C+%5C++IsGoal%28s_c%29+%5C+%5C+then

    3:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Append%28M%28s_c%29%2CSolutions%29

    4:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return+%5C+%5C+True

    5:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+if+%5C+%5C+IsDead%28s_c%29+%5C+%5C+then

    6:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return+%5C+%5C+False

    7:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+Set%28u_c%2Cv_c%29%3D%28%5Cepsilon%2C%5Cepsilon%29

    8:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%28u_n%2Cv_n%29+%3D+GetNextCandidate%28s%2C%28u_c%2Cv_c%29%2CN_%7BG_1%7D%2CParent%2CG_1%2CG_2%29

    9:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+Result%3DFalse

    10:

    equation?tex=%5C+%5C+%5C+%5C+%5C++while+%5C+%5C+%28u_c%2Cv_c%29+%5Cne+%28%5Cepsilon%2C%5Cepsilon%29+%5C+%5C+do

    11:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if+%5C+%5C+IsFeasible%28s_c%2Cu_n%2Cv_n%29%5C+%5C+then

    12:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++s_n%3Ds_c%5Ccup+%28u_n%2Cv_n%29

    13:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++if%5C+%5C+Match%28s_n%2CG_1%2CG_2%2CN_%7BG_1%7D%2CParent%29+%5C+%5C+is%5C+%5C+True%5C+%5C+then

    14:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Result%3DTrue

    15:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++%28u_n%2Cv_n%29%3DGetNextCandidate%28s%2C%28u_n%2Cv_n%29%2CN_%7BG_1%7D%2CParent%2CG_1%2CG_2%29

    16:

    equation?tex=%5C+%5C+%5C+%5C+%5C+return%5C++%5C+Result

    ​ 总流程中出现了一些函数,

    equation?tex=ComputeProbabilitys%28G_1%2CG_2%29
    equation?tex=GenerateNodeSequence%28G_1%2CP_%7Bfeas%7D%29是为了组织搜索树,也就是搜索顺序,其中
    equation?tex=ComputeProbabilitys%28G_1%2CG_2%29的计算结果又是为
    equation?tex=GenerateNodeSequence%28G_1%2CP_%7Bfeas%7D%29服务的,最终算出的
    equation?tex=N_%7BG_1%7D是小图的节点进入
    equation?tex=s的顺序优先级,而大图中的节点进入顺序是由
    equation?tex=Match流程中的
    equation?tex=GetCandidate函数决定的。
    equation?tex=ClassifyNodes%28G_1%2CG_2%29函数是对节点进行分类,是为了更好地剪枝同时也为后面的预处理做了一些准备。
    equation?tex=PreProcessPatternGraph%28G_1%2CN_%7BG_1%7D%29为每个小图中的节点提供一个父节点,为
    equation?tex=Match做好准备,细节后面一一展开。

    ​ 搜索过程从

    equation?tex=s_0开始,这时
    equation?tex=%5Ctilde%7BM%7D%28s_0%29%3D%5Cphi,把一对对的
    equation?tex=%28u_n%2Cv_n%29往里面加,
    equation?tex=%28u_n%2Cv_n%29
    equation?tex=GetCandidate函数决定,每加一对都会判断加了这对节点后一步(1-lookahead)和两步(2-lookahead)是否可行,如果不可行就剪枝,不再从这个状态往下搜。为什么没有3-lookahead,n-lookahead?因为往后考虑n步本身就需要计算量,这是判断一枝的效率和剪枝质量之间的博弈。

    B 可行集合

    ​ 这一节主要是介绍一些集合的概念,为理解后面的算法做铺垫。

    ​ 首先集合粗略地分为

    equation?tex=%5Ctilde+P_1,
    equation?tex=%5Ctilde+S_1,
    equation?tex=%5Ctilde+V_1
    equation?tex=%5Ctilde+P_2,
    equation?tex=%5Ctilde+S_2,
    equation?tex=%5Ctilde+V_2 ,其中下标1代表是属于小图
    equation?tex=G_1的节点子集,下标2代表是属于大图
    equation?tex=G_2的节点子集,
    equation?tex=P是predecessor,意思是前驱节点,具体讲是至少有一条边连接到已经匹配的
    equation?tex=%5Ctilde+M%28s%29集合中节点的所有节点构成的集合,好拗口...重来:一个predecessor节点就是有边指向
    equation?tex=%5Ctilde+M%28s%29里面的节点;
    equation?tex=S
    equation?tex=P相对,是successor,即后继节点,是从
    equation?tex=%5Ctilde+M%28s%29中出来被指向的节点构成的集合;最后
    equation?tex=V是这个图中既不在
    equation?tex=M中,又不在
    equation?tex=P
    equation?tex=S中的节点构成的集合。综上,
    equation?tex=M是已经匹配的节点集合,
    equation?tex=P
    equation?tex=S是直接和已经匹配的节点相连的节点集合,即1-lookahead要用到的集合,V是更外圈的节点集合,至少得是2-lookahead才够得到~下面严格定义一下~
    1. equation?tex=%5Ctilde+P_1%28s%29%3D%5C%7Bu%5Cin+V_1-%5Ctilde+M_1%28s%29%3A%5Cexists+u%5E%7B%27%7D%5Cin+%5Ctilde+M_1%28s%29%3A%28u%2Cu%5E%7B%27%7D%29%5Cin+E_1+%5C%7D
    2. equation?tex=%5Ctilde+S_1%28s%29%3D%5C%7Bu%5Cin+V_1-%5Ctilde+M_1%28s%29%3A%5Cexists+u%5E%7B%27%7D%5Cin+%5Ctilde+M_1%28s%29%3A%28u%5E%7B%27%7D%2Cu%29%5Cin+E_1+%5C%7D
    3. equation?tex=%5Ctilde+V_1%28s%29%3DV_1-%5Ctilde+M_1%28s%29-%5Ctilde+P_1%28s%29-%5Ctilde+S_1%28s%29
    4. equation?tex=%5Ctilde+P_2%28s%29%3D%5C%7Bv%5Cin+V_2-%5Ctilde+M_2%28s%29%3A%5Cexists+v%5E%7B%27%7D%5Cin+%5Ctilde+M_2%28s%29%3A%28v%2Cv%5E%7B%27%7D%29%5Cin+E_2+%5C%7D
    5. equation?tex=%5Ctilde+S_2%28s%29%3D%5C%7Bv%5Cin+V_2-%5Ctilde+M_2%28s%29%3A%5Cexists+v%5E%7B%27%7D%5Cin+%5Ctilde+M_2%28s%29%3A%28v%5E%7B%27%7D%2Cv%29%5Cin+E_2+%5C%7D
    6. equation?tex=%5Ctilde+V_2%28s%29%3DV_2-%5Ctilde+M_2%28s%29-%5Ctilde+P_2%28s%29-%5Ctilde+S_2%28s%29

    几个集合的关系如下图所示~~~

    7163a75179ff799cc7a1d98070649418.png

    ​ 这样还不够,在这基础上,我们还要为节点分组,最常见的就是按节点的类型或属性分组,如果分别属于小图和大图的两个节点属于不同组,即类型不同,那他们不可能对应上,也就不可能作为一对节点进入一致状态

    equation?tex=s

    ​ 于是我们把两个图中所有的节点合起来,一起按照类型分组,分组函数:

    equation?tex=%5Cpsi+%3AV_1%5Ccup+V_2+%5Crightarrow+C,给每个节点分一个组别
    equation?tex=c_i%5Cin+C%3D%5C%7Bc_1%2Cc_2%2C...c_q+%5C%7D,因为匹配上的节点类型必须相同,因此有
    equation?tex=%28u%2Cv%29%5Cin+M+%5CRightarrow+%5Cpsi%28u%29%3D%5Cpsi%28v%29

    ​ 在给节点分组之后,我们又可以将上面6个集合分得更细,分成6q个,q是分组的数量。具体如下:

    1. equation?tex=%5Ctilde+P_1%5E%7Bc_i%7D%28s%29%3D%5C%7Bu%5Cin+%5Ctilde+P_1%28s%29%3A%5Cpsi%28u%29%3Dc_i+%5C%7D
    2. equation?tex=%5Ctilde+S_1%5E%7Bc_i%7D%28s%29%3D%5C%7Bu%5Cin+%5Ctilde+S_1%28s%29%3A%5Cpsi%28u%29%3Dc_i+%5C%7D
    3. equation?tex=%5Ctilde+V_1%5E%7Bc_i%7D%28s%29%3D%5C%7Bu%5Cin+%5Ctilde+V_1%28s%29%3A%5Cpsi%28u%29%3Dc_i+%5C%7D
    4. equation?tex=%5Ctilde+P_2%5E%7Bc_i%7D%28s%29%3D%5C%7Bv%5Cin+%5Ctilde+P_2%28s%29%3A%5Cpsi%28v%29%3Dc_i+%5C%7D
    5. equation?tex=%5Ctilde+S_2%5E%7Bc_i%7D%28s%29%3D%5C%7Bv%5Cin+%5Ctilde+S_2%28s%29%3A%5Cpsi%28v%29%3Dc_i+%5C%7D
    6. equation?tex=%5Ctilde+V_2%5E%7Bc_i%7D%28s%29%3D%5C%7Bv%5Cin+%5Ctilde+V_2%28s%29%3A%5Cpsi%28v%29%3Dc_i+%5C%7D

    C 组织小图中节点的匹配顺序

    ​ 简单计算,假如一个状态

    equation?tex=s对应的匹配集合
    equation?tex=M%28s%29中已经有k对节点,那么到达这个状态共有
    equation?tex=k%21种不同的路径,为了避免如此繁重的计算,我们将状态空间组织成一颗树,而不是原来的图,实则是避免同样的状态
    equation?tex=s在一次搜索中访问多次。

    ​ 在这一步中,我们要组织的是小图中的节点进入匹配的顺序,大图中节点的进入顺序在后面~为了给小图中节点排一个进入匹配的优先级序列(也就是

    equation?tex=N_%7BG_1%7D),要同时用到小图和大图的一些结构信息,原则是优先考虑有更多约束的节点,具体讲有两点:一是在大图中找到对应节点的可能性比较小的应该优先,二是跟已经匹配上的节点的连接比较多的应该优先。这样可以更早地剪掉大分支~

    ​ 实现上述目的的是总流程中3、4行的两个函数:

    • equation?tex=P_f%3DComputeProbabilitys%28G_1%2CG_2%29
    • equation?tex=N_%7BG_1%7D%3DGenerateNodeSequence%28G_1%2CP_%7Bfeas%7D%29

    ​ 首先,

    equation?tex=P_f%28u%29是在大图中找到一个节点
    equation?tex=v可以跟小图节点
    equation?tex=u匹配上的概率,当然这个概率是估算,因为精确计算过于困难而且需要花很大的计算量,这里没必要这么精确。

    ​ 我们这样估计这个概率:

    equation?tex=P_f%28u%29%3DP_r%28%5Clambda_%7Bv_2%7D%28v%29%3D%5Clambda_%7Bv_1%7D%28u%29%2Cd%5E%7Bin%7D%28v%29%5Cgeq+d%5E%7Bin%7D%28u%29%2Cd%5E%7Bout%7D%28v%29%5Cgeq+d%5E%7Bout%7D%28u%29%29,其中
    equation?tex=d%5E%7Bin%7D是入度,
    equation?tex=d%5E%7Bout%7D是出度。

    ​ 很自然,想要在大图中找到一个节点

    equation?tex=v跟小图节点
    equation?tex=u匹配,必须满足三个条件:

    ​ 1.两个节点的label相同;

    ​ 2.大图节点

    equation?tex=v的入度不小于小图节点
    equation?tex=u

    ​ 3.大图节点

    equation?tex=v的出度不小于小图节点
    equation?tex=u

    ​ 我们用同时满足这三个条件的节点概率来估计

    equation?tex=P_f%28u%29~但是在最差的情况下,计算这个概率的时间复杂度为
    equation?tex=O%28N%5E3%29,于是我们进一步假设这三个条件是独立的,于是可以这样估算这个概率:

    equation?tex=P_f%28u%29%3DP_l%28%5Clambda_%7Bv_1%7D%28u%29%29.%5Csum_%7Bd%27%5Cgeq+d%5E%7Bin%7D%28u%29%7DP_d%5E%7Bin%7D%28d%27%29.%5Csum_%7Bd%27%5Cgeq+d%5E%7Bout%7D%28u%29%7DP_d%5E%7Bout%7D%28d%27%29,其中
    equation?tex=P_l%28l%29是节点
    equation?tex=v的label是
    equation?tex=l的概率。

    ​ 用人话解释一下,因为假设三个条件独立,因此可以把三个条件各自满足的可能性相乘来估算同时满足三个条件的概率。第一个概率是节点

    equation?tex=v拥有跟节点
    equation?tex=u相同标签的概率;第二个概率:假设
    equation?tex=u节点的入度为3,那么
    equation?tex=d%27是3,4,5,6......把
    equation?tex=v的入度为这些值的概率全部加起来;第三个概率:假设
    equation?tex=u节点的出度为4,那么
    equation?tex=d%27是4,5,6,7......把
    equation?tex=v的出度为这些值的概率全部加起来。这个计算的复杂度仅为
    equation?tex=O%28N%29.

    ​ 除了考虑以上概率以外,我们还要考虑已经在

    equation?tex=N_%7BG_1%7D里的节点的结构,定义
    equation?tex=d_M为一个节点与已经在
    equation?tex=N_%7BG_1%7D里的节点相连的数量,即节点度的一部分。

    ​ 总体上,

    equation?tex=GenerateNodeSequence%28G_1%2CP_%7Bfeas%7D%29函数首先考虑
    equation?tex=d_M
    equation?tex=d_M大的节点与已经匹配上的节点的连接比较多,优先级高;如果几个节点的
    equation?tex=d_M相同,则按上面计算出的
    equation?tex=P_f排序,
    equation?tex=P_f小的节点优先级高;如果
    equation?tex=P_f也相同,则再考虑节点的度,度大的节点优先级高;最后如果前面三者全部相等,那就随机排~这样我们就把小图的节点匹配顺序排好了,得到了
    equation?tex=N_%7BG_1%7D

    D 预处理

    ​ 每一个状态

    equation?tex=s在搜索树中的高度与它包含的节点对数相同,而小图节点进入
    equation?tex=s的优先级由
    equation?tex=N_%7BG_1%7D确定,树中高度相同的状态
    equation?tex=s的小图节点
    equation?tex=u都相同,而大图节点
    equation?tex=v是动态选择的,每一种
    equation?tex=v的可能都造成了树在这个高度上的一个分支。上图助理解~

    57cd6b79deb1c8e3072bdf97ca914ca4.png

    ​ 作为正式匹配前的最后一步,预处理函数

    equation?tex=PreProcessPatternGraph%28G_1%2CN_%7BG_1%7D%29为每个小图节点提供一个父节点,这是为了后面真正选候选节点对做准备的,而节点对的选择也就是选择上图中
    equation?tex=%3F%3F%3F位置的
    equation?tex=v节点,因为
    equation?tex=u已经被确定了。这里的父节点并不是一个指向它的节点,而是在它之前进入
    equation?tex=s的且与它有连接的节点中优先级最高的那个,第一个
    equation?tex=u没有父节点。

    伪代码如下:

    1:

    equation?tex=function+%5C+%5C+PreProcessPatternGraph%28G_1%2CN_%7BG_1%7D%2CT_1%29

    2:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+i%3D0

    3:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+for%5C+%5C+all%5C+%5C+u%5Cin+N_%7BG_1%7D+%5C+%5C+do

    4:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+for+%5C+%5C+all%5C+%5C+u%27%5Cin+P_1%28u%29%5Ccup+S_1%28u%29%5C+%5C+do

    5:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+c_i%3D%5Cpsi%28u%27%29

    6:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+u%27%5Cin+P_1%28u%29+%5Cland+u%27%5Cnotin+%5Ctilde+P_1%5E%7Bc_i%7D%5C+%5C+then

    7:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Put%5C+%5C+u%27%5C+%5C+in%5C+%5C+%5Ctilde+P_1%5C+%5C+at%5C+%5C+level%5C+%5C+i

    8:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Parent%28u%27%29%3Du

    9:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+u%27%5Cin+S_1%28u%29+%5Cland+u%27%5Cnotin+%5Ctilde+S_1%5E%7Bc_i%7D%5C+%5C+then

    10:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Put%5C+%5C+u%27%5C+%5C+in%5C+%5C+%5Ctilde+S_1%5C+%5C+at%5C+%5C+level%5C+%5C+i

    11:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+Parent%28u%27%29%3Du

    12:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+i%3Di%2B1

    13:

    equation?tex=%5C+%5C+%5C+%5C+%5C+return%5C+%5C+Parent

    E 选择候选节点对

    ​ 前面做了那么多准备,可以说大多数都是为了给这一步做准备的。

    equation?tex=%28u_n%2Cv_n%29%3DGetNextCandidate%28s%2C%28u_c%2Cv_c%29%2CN_%7BG_1%7D%2CParent%2CG_1%2CG_2%29这个函数在匹配过程中为每一个状态
    equation?tex=s选择下一对候选节点,
    equation?tex=%EF%BC%88u_c%2Cv_c%EF%BC%89是当前状态
    equation?tex=s中最后进入的一对节点。对于小图而言,
    equation?tex=u_n节点是
    equation?tex=N_%7BG_1%7D序列中,跟在
    equation?tex=u_c后面的节点;所以接下来的关键工作就是选择大图中的节点
    equation?tex=v_n来与
    equation?tex=u_n对应。

    ​ 首先,

    equation?tex=v_n必须与
    equation?tex=u_n的组别相同,我们把与
    equation?tex=u_n同组的还没匹配上的节点集合记为
    equation?tex=R_2%28s_c%2C%5Cpsi+%28u_n%29%29

    equation?tex=R_2%28s_c%2C%5Cpsi+%28u_n%29%29%3D%5C%7Bv_n%5Cin+V_2%3Av_n%5Cnotin+%5Ctilde+M_2%28s_c%29%5Cland+%5Cpsi%28v_n%29%3D%5Cpsi+%28u_n%29+%5C%7D

    ​ 更进一步,

    equation?tex=v_n与它的父节点
    equation?tex=%5Ctilde+v_n之间的关系得和
    equation?tex=u_n与它的父节点
    equation?tex=%5Ctilde+u_n之间的关系相同。具体来说,如果
    equation?tex=u_n
    equation?tex=%5Ctilde+u_n的后继节点,那么
    equation?tex=v_n也得是
    equation?tex=%5Ctilde+v_n的后继节点;如果
    equation?tex=u_n
    equation?tex=%5Ctilde+u_n的前驱节点,那么
    equation?tex=v_n也得是
    equation?tex=%5Ctilde+v_n的前驱节点。

    ​ 因此最终

    equation?tex=v_n的候选集如下:

    equation?tex=R_2%5ES%28s_c%2C%5Cpsi%28u_n%29%2C%5Ctilde+v%29%3D%5C%7Bv_n%5Cin+V_2%3Av_n%5Cin+S_2%28%5Ctilde+v%29%5Ccap+R_2%28s_c%2Cu_n%29+%5C%7D

    equation?tex=R_2%5EP%28s_c%2C%5Cpsi%28u_n%29%2C%5Ctilde+v%29%3D%5C%7Bv_n%5Cin+V_2%3Av_n%5Cin+P_2%28%5Ctilde+v%29%5Ccap+R_2%28s_c%2Cu_n%29+%5C%7D

    085e3c352558b021dcda7d47d934db89.png

    ​ 上面两条规则很大程度地缩小了可以考虑的

    equation?tex=v_n的范围,根据
    equation?tex=u_n与它的父节点
    equation?tex=%5Ctilde+u_n之间的关系,可以知道该从上面哪个集合中选取
    equation?tex=v_n,然后就取这个集合中的第一个节点当作
    equation?tex=v_n,与
    equation?tex=u_n组成节点对准备进入状态
    equation?tex=s,当然是否真的能进入还要看是否满足可行规则,很有可能被剪枝掉~

    ​ 选取候选节点对伪代码如下:

    1:

    equation?tex=function%5C+%5C+GetNextCandidate%28s%2C%28u_c%2Cv_c%29%2CN_%7BG_1%7D%2CParent%2CG_1%2CG_2%29

    2:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+u_c%3D%5Cepsilon+%5C+%5C+then

    3:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+u_n%3DGetNextInSequence%28N_%7BG_1%7D%2Cs_c%29

    4:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if+%5C+%5C+u_n%3D%5Cepsilon%5C+%5C+then //这个序列结束

    5:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return%5C+%5C+%28%5Cepsilon%2C%5Cepsilon%29

    6:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+else

    7:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+u_n%3Du_c

    8:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+Parent%28u_n%29%3D%5Cepsilon%5C+%5C+then //
    equation?tex=u_n没有父节点

    9:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++v_n%3DGetNextNode%28v_c%2CR_2%28s_c%2C%5Cpsi%28u_n%29%29%29

    10:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++return+%5C+%5C+%28u_n%2Cv_n%29

    11:

    equation?tex=%5C+%5C+%5C+%5C+%5C++else

    12:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+tilde+v+%3D+%5Ctilde+u%28s_c%2CParent%28u_n%29%29 //获取跟
    equation?tex=u_n的父节点对应的节点

    13:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+u_n%5C+%5C+in%5C+%5C+P_1%28Parent%28u_n%29%29 //
    equation?tex=u_n是其父节点的前驱节点

    14:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C++v_n%3DGetNextNode%28v_c%2CR_2%5EP%28s_c%2C%5Cpsi%28u_n%29%2C%5Ctilde+v%29

    15:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return%5C+%5C+%28u_n%2Cv_n%29

    16:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+if%5C+%5C+u_n%5C+%5C+in%5C+%5C+S_1%28Parent%28u_n%29%29 //
    equation?tex=u_n是其父节点的后继节点

    17:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+v_n%3DGetNextNode%28v_c%2CR_2%5ES%28s_c%2C%5Cpsi%28u_n%29%2C%5Ctilde+v%29

    18:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return%5C+%5C+%28u_n%2Cv_n%29

    19:

    equation?tex=%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+%5C+return%5C+%5C+%28%5Cepsilon%2C%5Cepsilon%29 //
    equation?tex=u_n没有对应的候选节点

    F 可行规则

    ​ 在匹配过程中,每一步选取的节点对

    equation?tex=%28u_n%2Cv_n%29加入到状态
    equation?tex=s不一定合适,要么加入后新的状态
    equation?tex=s%27不是一致状态(consistent state),要么加入后未来几步不可能达到一致状态,因此这一搜索分支就可以被砍掉,不再往下搜索,并且回溯到上一状态
    equation?tex=s并选取下一节点对。我们要用一系列的可行规则来判断当前选出的候选节点对是否可以加入状态
    equation?tex=s达到
    equation?tex=s%27

    ​ 我们用可行函数

    equation?tex=IsFeasible%28s_c%2Cu_n%2Cv_n%29来判断在当前状态
    equation?tex=s_c下,加入节点对
    equation?tex=%28u_n%2Cv_n%29是否可行。判断规则主要分为两类,一类是基于节点和边的标签(label),记作
    equation?tex=F_s,另一类基于图的拓扑结构,记作
    equation?tex=F_t。两类规则都得满足,因此有:

    equation?tex=IsFeasible%28s_c%2Cu_n%2Cv_n%29%3DF_s%28s_c%2Cu_n%2Cv_n%29%5Cland+F_t%28s_c%2Cu_n%2Cv_n%29

    equation?tex=F_s的规则很简单,就是要保证新加入节点对后,对应节点和边的label要全部相同:
    1. equation?tex=%5Cforall+u+%5Cin+V_1++%5Cquad++%5Clambda_%7BV_1%7D%28u%29%3D%5Clambda_%7BV_2%7D%28%5Cmu%28u%29%29
    2. equation?tex=%5Cforall+%28u%2Cu%5E%7B%27%7D%29+%5Cin+E_1++%5Cquad++%5Clambda_%7Be_1%7D%28u%2Cu%5E%7B%27%7D%29%3D%5Clambda_%7Be_2%7D%28%5Cmu%28u%29%2C%5Cmu%28u%5E%7B%27%7D%29%29

    ​ 而

    equation?tex=F_t的规则就复杂一些,当然这也是本算法剪枝的精髓所在~这部分规则又可以分为三个小部分,第一:将新节点对加入状态
    equation?tex=s后,检查新的状态
    equation?tex=s%27还是一致状态,记作
    equation?tex=F_c;第二,考虑1-lookahead,判断未来一步是否可能构成一致状态
    equation?tex=s%27%27记作
    equation?tex=F_%7Bla1%7D;第三,考虑2-lookahead,判断未来两步是否可能构成一致状态
    equation?tex=s%27%27%27,记作
    equation?tex=F_%7Bla2%7D

    equation?tex=F_t%28s_c%2Cu_n%2Cv_n%29%3DF_c%28s_c%2Cu_n%2Cv_n%29%5Cland+F_%7Bla1%7D%28s_c%2Cu_n%2Cv_n%29%5Cland+F_%7Bla2%7D%28s_c%2Cu_n%2Cv_n%29

    下面逐个展开~

    第一类规则

    equation?tex=F_c

    equation?tex=s_c已经是一个一致状态,判断要新加入的候选节点对
    equation?tex=%28u_n%2Cv_n%29是否可行,需要满足
    equation?tex=s_c%5Ccup+%28u_n%2Cv_n%29依然是一致状态。

    equation?tex=F_c%28S_c%2Cu_n%2Cv_n%29%3D+%5C%5C+%09%5Cforall+u%27%5Cin+S_1%28u_n%29%5Ccap+%5Ctilde+M_1%28s_c%29%5C+%5C++%5Cexists+v%27%3D%5Ctilde+%5Cmu%28s_c%2Cu%27%29%5Cin+S_2%28v_n%29+%5C%5C+%09%5Cland+%5Cforall+u%27%5Cin+P_1%28u_n%29%5Ccap+%5Ctilde+M_1%28s_c%29%5C+%5C++%5Cexists+v%27%3D%5Ctilde+%5Cmu%28s_c%2Cu%27%29%5Cin+P_2%28v_n%29+%5C%5C+%09%5Cland+%5Cforall+v%27%5Cin+S_2%28v_n%29%5Ccap+%5Ctilde+M_2%28s_c%29%5C+%5C++%5Cexists+u%27%3D%5Ctilde+%5Cmu+%5E%7B-1%7D%28s_c%2Cv%27%29%5Cin+S_1%28u_n%29+%5C%5C+%09%5Cland+%5Cforall+v%27%5Cin+P_2%28v_n%29%5Ccap+%5Ctilde+M_2%28s_c%29%5C+%5C++%5Cexists+u%27%3D%5Ctilde+%5Cmu+%5E%7B-1%7D%28s_c%2Cv%27%29%5Cin+P_1%28u_n%29+%5C%5C

    人话解释一下:

    equation?tex=S_1%28u_n%29
    equation?tex=u_n节点的所有后继节点构成的集合;
    equation?tex=P_1%28u_n%29
    equation?tex=u_n节点的所有前驱节点构成的集合;

    equation?tex=S_2%28v_n%29
    equation?tex=v_n节点的所有后继节点构成的集合;
    equation?tex=P_2%28v_n%29
    equation?tex=v_n节点的所有前驱节点构成的集合。

    ​ 4条规则就说了一件事:新的节点

    equation?tex=u_n与已经匹配上的
    equation?tex=%5Ctilde+M_1%28s_c%29中节点的关系 和 新的节点
    equation?tex=v_n与已经匹配上的
    equation?tex=%5Ctilde+M_2%28s_c%29中节点的关系 要一模一样!不能左边有右边没有或右边有左边没有,也不能乱了顺序和边的方向。

    8dcb5fe656db4e1567571e690932fe5d.png

    8415d8e2a49c887dfa33de7d1225439b.png

    ​ 补充:有的问题需求是,小图中有的边大图中必须有,而大图中有的边小图可以没有,也就是小于等于的关系,那么就把后两条规则删除,也就是最右边的两个图的情况可以被容许。

    第二类规则

    equation?tex=F_%7Bla1%7D

    equation?tex=F_%7Bla1%7D%28s_c%2Cu_n%2Cv_n%29%3DF_%7Bla1%7D%5E1%28s_c%2Cu_n%2Cv_n%29%5Cland+F_%7Bla1%7D%5E2%28s_c%2Cu_n%2Cv_n%29%5Cland+...%5Cland+F_%7Bla1%7D%5Eq%28s_c%2Cu_n%2Cv_n%29%5C%5C+F_%7Bla1%7D%5Ei%28s_c%2Cu_n%2Cv_n%29%3D%5C%5C+%7CP_1%28u_n%29%5Ccap+%5Ctilde+P_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CP_2%28v_n%29%5Ccap+%5Ctilde+P_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C+%5Cland+%7CP_1%28u_n%29%5Ccap+%5Ctilde+S_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CP_2%28v_n%29%5Ccap+%5Ctilde+S_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C+%5Cland+%7CS_1%28u_n%29%5Ccap+%5Ctilde+P_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CS_2%28v_n%29%5Ccap+%5Ctilde+P_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C+%5Cland+%7CS_1%28u_n%29%5Ccap+%5Ctilde+S_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CS_2%28v_n%29%5Ccap+%5Ctilde+S_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C

    ​ 这一类约束主要考虑与当前状态

    equation?tex=s_c中的节点直接相连的节点(
    equation?tex=P%2CS集合)与新的节点对
    equation?tex=%28u_n%2Cv_n%29间的关系。现在考虑的是3部分节点,1是已经在
    equation?tex=M%28s_c%29中的节点,即已经匹配了的;2是新的候选节点;3是
    equation?tex=P%2CS集合中的节点。3的节点中,与1和2的关系可以分成四类,分别对应上述4条规则,然后每一大类还可以按之前的分组分开,一共4q类关系,每一类关系的节点数量都要满足:小图节点数量不大于大图节点数量,若小图某一类的节点数大于大图了,说明未来不可能形成一致状态,因为未来必然会有小图中边,在大图中找不到。

    cd04078aebf09e6cb5e3cb09cc96413d.png

    第三类规则

    equation?tex=F_%7Bla2%7D

    equation?tex=F_%7Bla2%7D%28s_c%2Cu_n%2Cv_n%29%3DF_%7Bla2%7D%5E1%28s_c%2Cu_n%2Cv_n%29%5Cland+F_%7Bla2%7D%5E2%28s_c%2Cu_n%2Cv_n%29%5Cland+...%5Cland+F_%7Bla2%7D%5Eq%28s_c%2Cu_n%2Cv_n%29%5C%5C+F_%7Bla2%7D%5Ei%28s_c%2Cu_n%2Cv_n%29%3D+%5C%5C+%7CP_1%28u_n%29%5Ccap+%5Ctilde+V_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CP_2%28v_n%29%5Ccap+%5Ctilde+V_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C+%5Cland+%7CS_1%28u_n%29%5Ccap+%5Ctilde+V_1%5E%7Bc_i%7D%28s_c%29%7C%5Cle+%7CS_2%28v_n%29%5Ccap+%5Ctilde+V_2%5E%7Bc_i%7D%28s_c%29%7C+%5C%5C

    ​ 这一类约束主要考虑与当前状态

    equation?tex=s_c中的节点不直接相连的节点(
    equation?tex=V集合)与新的节点对
    equation?tex=%28u_n%2Cv_n%29间的关系。现在考虑的是3部分节点,1是已经在
    equation?tex=M%28s_c%29中的节点,即已经匹配了的;2是新的候选节点;3是
    equation?tex=V集合中的节点。3的节点中,与1和2的关系可以分成2类,分别对应上述2条规则,然后每一大类还可以按之前的分组分开,一共2q类关系,每一类关系的节点数量都要满足:小图节点数量不大于大图节点数量,若小图某一类的节点数大于大图了,说明未来不可能形成一致状态,因为未来必然会有小图中边,在大图中找不到。

    d34a2a8d4966c3f77a9ba3a9a57eabec.png

    ​ 上述三类规则其实是把新节点对

    equation?tex=%28u_n%2Cv_n%29的度分成三部分,第一部分是与
    equation?tex=M%28s%29中节点的连接;第二部分是与
    equation?tex=P%28s%29%E3%80%81V%28s%29中节点的连接,即1-lookahead;第三部分是与
    equation?tex=V%28s%29中节点的连接,即2-lookahead。这三类连接又可以分为入度和出度,与其连接的节点又可以按分组分开,其中第一部分
    equation?tex=M%28s%29中已经匹配上的节点分组一定相同,因此可以不考虑分组。这样分类后,每一类度的数量都要满足,小图不大于大图,否则将不可能同构,其中第一类比较特殊,必须完全相同才能同构,当然也有只需要小于等于的需求,这类需求严格意义上已经不是子图同构了。

    3 结语

    ​ 终于写完了,太不好描述了~~~这是近期做的一个复杂网络相关项目中用到的算法,学习实现后记录一下~如果有不对的地方望大佬们指正!

    展开全文
  • 子图同构

    2014-12-09 21:56:00
    子图同构定义: 给定图$Q=(V(Q),E(Q),L_V,F)$和$G=(V(G),E(G),L_V',F')$, 称$Q$子图同构于$G$ 当且仅当存在一个映射$g:V(Q)\rightarrow V(G)$ 使得 \[\forall x\in V(Q), F(v)=F'(g(v))\] 和 \[\forall v_1 ,v_...

    子图同构定义:

          给定图$Q=(V(Q),E(Q),L_V,F)$和$G=(V(G),E(G),L_V',F')$,  称$Q$子图同构于$G$ 当且仅当存在一个映射$g:V(Q)\rightarrow V(G)$ 使得 

    \[\forall x\in V(Q), F(v)=F'(g(v))\]

    \[
    \forall v_1 ,v_2 \in V(Q),\overrightarrow {v_1 v_2 } \in E(Q) \Rightarrow \overrightarrow {g(v_1 )g(v_2 )} \in E(G)
    \]

         例,左图子图同构与右图:

    左图  Q                       右图  G

    图 1

    因为存在映射g(有两种),如下图所示:

       

    左图  Q                            右图  G                                     左图  Q                           右图  G

    图 2                                                                                   图 3

          用$MA,MB$分别表示图$Q,F$的对应的边矩阵,其中$MA[i][j]=1$表示顶点$v_i$与$v_j$有边,$MA[i][j]=0$表示无边. $M'$表示映射g从$Q$到$G$的映射矩阵,$M'[i][j]=1$表示$Q$中第$i$个顶点$v_i$对应到$G$中的第$j$个顶点$v_j^'$,否则没有对应.

          例如,图2中的$Q,G,g$对应的矩阵可以表示为

                         

     图  4

          定理 1  如果图$Q$关于映射$g$子图同构于$G$,令

    \[
    MC = M'(M' \cdot MB)^T
    \].

    ,则

    \[
    \forall i\forall j:(MA[i][j] = 1) \Rightarrow (MC[i][j] = 1).
    \]

          根据图4,$MC = M'(M' \cdot MB)^T $,由于

    这里显然,$MA$与$MC$满足定理1.

            子图同构映射$g$的$M’$满足一下性质:

    1. $M'[i][j]=1$ 表示Q中第$i$-个顶点对应$G$中的第$j$个顶点;
    2. $M'$的每行仅有一个$1$;
    3. $M'$的每列$1$的个数至多只有一个。

           子图同构就变成了寻找矩阵$M'$,那么如何寻找$M'$?1976年Ullmann给出了寻找算法(Ullmann Algorithm).

            Ullmann Algorithm的大致过程:

    1.  寻找矩阵$M'_{n\times m}$使得\[MC = M'(M' \cdot MB)^T ,\ \ \forall i\forall j:(MA[i][j] = 1) \Rightarrow (MC[i][j] = 1).\]
    2.  否则,报告不存在矩阵$M'$.

          Ullmann Algorithm的基本思想

          Step 1.  建立矩阵$M_{n\times m}$。 使得$M[i][j]=1$,如果

    1. Q中第$i$-个顶点与$G$中第$j$-个顶点有相同的标签;
    2. Q中第$i$-个顶点的度小于等于$G$中第$j$-个顶点的度;

          Step  2.  从矩阵$M_{n\times m}$生成矩阵$M'$. 即对$M_{n\times m}$进行逐行检查,将部分不为0的元素变成0,使得矩阵$M'$满足每行有且仅有一个元素为1,每列最多只有一个元素不为0.(最大深度为$|MA|$.)

          Step  3   按照以下规则判断矩阵$M'$是否满足条件:

    \[MC = M'(M' \cdot MB)^T ,\ \ \forall i\forall j:(MA[i][j] = 1) \Rightarrow (MC[i][j] = 1).\]

         Step 4   迭代以上步骤,列出所有可能的矩阵$M'$.

     

         以上最坏的情况是,可能有$O(|MB|!)$个可能的矩阵$M'$. 实际上,子图同构算法是一个经典的NP-hard问题。

     

     

     

     

     

     

    转载于:https://www.cnblogs.com/huadongw/p/4154295.html

    展开全文
  • 一种方法是制作长度为4的简单路径的图形并使用子图同构vf2函数.这是最好/最快的方式吗?我没有源节点,我想在整个图中存在长度为4的所有简单路径.在我的数据中,可能很少有这样的路径,我希望能够有效地迭代它们.解决...
  • 子图同构之Ullmann

    2020-09-24 22:56:16
    子图同构之Ullmann 1.子图同构问题描述 ​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。 ​ 精确点:一个图G=(V,E)G=(V,E)G=...
  • 1.子图同构问题描述​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。​ 精确点:一个图由集合和集合组成,是节点(node)集合,...
  • 超图查询&子图同构

    2014-04-05 13:42:57
    本文档细致的讲述了超图查询问题、子图同构问题,比给出常用的计算方法。
  • 子图同构之VF3

    2020-09-24 23:45:40
    子图同构之VF3 1.子图同构问题描述 ​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。 ​ 精确点:一个图G=(V,E)G=(V,E)G=(V,E...
  • 子图同构之VF2

    2020-09-24 23:22:52
    子图同构之VF2 1.子图同构问题描述 ​ 首先描述一下子图同构是什么意思,一个图由一系列节点和一系列连接节点的边构成,节点和边都可以有标签,也就是可以给他们按属性分类。 ​ 精确点:一个图G=(V,E)G=(V,E)G=(V,E...
  • 子图同构算法实现,Ullman算法,用java代码实现。
  • 子图同构定义 子图同构的映射关系 Reference 写在后面的话写在前面的话谨以此片献给 my best love, grandpa.时光匆匆流逝,我们永远无能为力,我能做的就是脚踏实地,变成你的骄傲~和你在一起的时光,是我所有的宝藏...
  • 为了找出随采掘进行而开挖的高联巷道因风流不稳定导致危险性较高的区域,提出了一种基于子图同构的煤矿高风险区域自动识别方法。分析了典型高危区域的拓扑结构特性,构建了高风险区域的等效图模型;实现了通风系统的...
  • 关于子图同构算法VF2的论文,实现和测试数据。用于学习子图同构算法,用作借鉴。
  • 提出了一种新的虚拟网络嵌入(VNE)算法,该算法改进了原始子图同构搜索过程,克服了现有VNE算法的缺陷。 首先,提出了一种节点资源评估方法,该方法同时考虑了节点资源需求(能力)和拓扑属性,以改善虚拟节点的...
  • 图 和图 的导出子图有哪些同构的问题可以看成一个约束满足问题(CSP) ,CSP的详细定义见:约束规划,约束传播和CSP问题 导出子图同构问题的形式化简单地说,图 在 中的嵌入(embedding) 满足(1) ,(2) ,(3) ,是 和 的...
  • 基于大图处理框架的分布式子图同构研究,刘杨,张熙,在大数据时代,越来越多的实际计算问题都涉及到大图的处理,例如互联网和各式各样的社交网络。子图同构是图处理领域的基础性研究
  • 图 和图 的导出子图有哪些同构的问题可以看成一个约束满足问题(CSP) ,CSP的详细定义见:约束规划,约束传播和CSP问题 导出子图同构问题的形式化简单地说,图 在 中的嵌入(embedding) 满足(1) ,(2) ,(3) ,是 和 的...
  • 子图同构的Ullmann算法的matlab实现

    千次阅读 2014-05-18 13:58:03
    %Ullmann算法:子图同构算法中最简单的一种 %判断图b中是否有子图同构于a %a和b是图的邻接布尔矩阵 %返回0代表没有找到,1代表找到了. %p1和p2代表a和b的阶  [p1,tmp]=size(a);  [p2,tmp]=size(b);  %ab...
  • 最近在项目中用到了子图同构算法VF2在这里记录一下。内容主要来自一篇论文(A (Sub)Graph Isomorphism Algorithm for Matching Large Graphs)
  • Naive alogrithm for Subgraph Isomorphism. 1. 如何判定子图同构。...设A是子图,B是原图。那么有一个A的点到B的点的映射。这个映射的模式叫做M。M是pa行,pb列的。M有一个性质就是每行只有一个1,每列至多一个1。...
  • 图说子图同构算法——VF2算法(一)

    万次阅读 热门讨论 2016-10-09 01:53:47
    写在前面的话谨以此系列献给 my grandpa~体验过...1.2你必需知道的事情虽然子图同构问题没有图的同构问题要求这么严,图的同构必须要求结点的度必须相同,否则不同构。如果在一个图中某个节点的度大于要匹配的图形的
  • 子图同构问题Ullmann 算法(二)

    千次阅读 热门讨论 2016-10-07 12:19:05
    对于图的同构问题,Ullmann 算法是一个简单的图同构算法,它采取的手段就是利用枚举找到子图同构。 这个算法的目的就是 对于一个给定的图Q,要找出在图G当中的和图Q同构的所有的子图。 用我们上一张的例子来说:...
  • 最近在学习子图同构算法。什么是子图同构,看这里-->图论。在图论的维基百科中有子图同构的描述。 子图同构一直是图论中比较重要的一个问题,经过各位大牛长时间的学习和研究,发现求解子图同构是一个NP完全问题。...
  • GSI:GPU-friendly Subgraph Ismorphism——ICDE 2020GPU加速子图同构算法作者: 曾立 邹磊 M. Tamer Özsu 胡琳 张藩论文链接:https://arxiv.org/abs/1906.03420 本次论文讲解的是曾立、邹磊、M. Tamer Özsu、...
  • 用java实现子图同构算法Ullmann,并采取了refinement来提高效率。
  • GPU加速子图同构算法作者: 曾立 邹磊 M. Tamer Özsu 胡琳 张藩论文链接:https://arxiv.org/abs/1906.03420 本次论文讲解的是曾立、邹磊、M. Tamer Özsu、胡琳、张藩等作者在 ICDE 2020上发表的论文 GSI: GPU-...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 171
精华内容 68
关键字:

同构子图