一种图形相似性分级算法的Python实现

一种图形相似性分级算法的Python实现,python,algorithm,graph,Python,Algorithm,Graph,我正在寻找执行以下任务的算法的Python实现: 给定两个可能包含圈的有向图及其根, 对两个图表的相似性进行评分。 (Python的difflib可以对两个序列执行的方式) 希望有这样的实现。否则,我将尝试自己实现一个算法。在这种情况下,最好实现什么算法(关于简单性) 算法的工作方式对我来说并不重要,尽管它的复杂性很高。 此外,只要像我所描述的那样,一个图形可以用这个DS来表示,一个使用不同数据结构的算法也是可以接受的 我要强调的是,默示会更好 编辑: 似乎同构算法是不相关的。有人建议图形编辑距

我正在寻找执行以下任务的算法的Python实现:

给定两个可能包含圈的有向图及其根, 对两个图表的相似性进行评分。

(Python的
difflib
可以对两个序列执行的方式)

希望有这样的实现。否则,我将尝试自己实现一个算法。在这种情况下,最好实现什么算法(关于简单性)

算法的工作方式对我来说并不重要,尽管它的复杂性很高。 此外,只要像我所描述的那样,一个图形可以用这个DS来表示,一个使用不同数据结构的算法也是可以接受的

我要强调的是,默示会更好

编辑:
似乎同构算法是不相关的。有人建议图形编辑距离更接近点,这将我的搜索范围缩小到一个解决方案,即执行图形编辑距离将图形简化为树,然后执行树编辑距离

节点本身由几行汇编代码组成。

我认为定义相似性的方式不是很标准,因此可能更容易找到同构检查、图形编辑距离和最大公共子图的实现,然后自己组合它们

然而,人们应该理解,计算这样一个相似性度量可能会很昂贵,所以如果有很多图,你可能需要先做一些筛选

例如,可以检查同构


编辑:实际上,您可能只需要编辑距离,因为MCS的存在通常是不相关的,正如我在上面指出的,如果编辑距离为0,两个图形无论如何都是同构的。

我们最后做的是实现以下所述的算法:

我们使用NetworkX来表示图形和查找max集团

编辑:

基本上,您创建一个新的图,每个节点(v)表示从图a(a)到图B(B)的节点的可能配对。

如果应用程序中的两个节点(a、b)相似或不相似,则从新图形中删除对应于不同配对(a、b)的节点(v)。 如果两个节点彼此不矛盾,则用一条边连接它们。 例如,配对(a,b)和(a,c)相互矛盾(正式定义见文章)。 然后,在新图形中找到一个具有最大节点数的群组

如果在应用程序中,两个节点的相似性不是二进制的,则在一定范围内(例如(0,1))为新节点赋予权重。 您可以启发式地删除相似度等级低于预定义阈值的新节点。 然后在新图中找到一个具有最大权重的群组(节点指定权重的总和)

无论哪种方式,最后都会生成相似性等级:集团的大小/总权重除以原始图形属性的函数(a和B的大小/权重的最大值/最小值/平均值)

一个很好的特点是,你可以从你发现的“更强”配对中推断出相似性的“来源”

进一步澄清:
这些约束取决于应用程序。我们使用这种方法来比较函数控制流图对。通常,该方法发现第一个图中的一些节点与第二个图(子图到子图)中的一些节点相匹配。关联图中的每个节点表示从第一个图到第二个图中的单个节点的可能匹配。因为最终选择了一个团(节点的子集),所以边意味着两个匹配并不相互矛盾。要应用不同的应用程序,您应该询问可能的配对标准是什么(或者我创建了哪些节点),以及选择一个配对如何影响另一个配对的选择(或者我如何将节点与边连接)。

另一种方法是使用所谓的特征向量相似性。基本上,计算每个图的邻接矩阵的拉普拉斯特征值。对于每个图,找出最小的k,使得k个最大特征值之和至少占所有特征值之和的90%。如果两个图之间的k值不同,则使用较小的一个。相似性度量是图之间最大k个特征值之间的平方差之和。这将产生[0]范围内的相似性度量,∞), 其中接近零的值更相似

例如,如果使用
networkx

def select_k(spectrum, minimum_energy = 0.9):
    running_total = 0.0
    total = sum(spectrum)
    if total == 0.0:
        return len(spectrum)
    for i in range(len(spectrum)):
        running_total += spectrum[i]
        if running_total / total >= minimum_energy:
            return i + 1
    return len(spectrum)

laplacian1 = nx.spectrum.laplacian_spectrum(graph1)
laplacian2 = nx.spectrum.laplacian_spectrum(graph2)

k1 = select_k(laplacian1)
k2 = select_k(laplacian2)
k = min(k1, k2)

similarity = sum((laplacian1[:k] - laplacian2[:k])**2)

这是一个老问题,但我想分享我的方法。 我有一个CVRP(容量限制车辆路径问题)任务。我的启发式算法生成了几个不同的图,以便找到解决方案。 为了不陷入局部最优,我使用了放松和修复程序

在这一点上,我不得不过滤掉太相似的解决方案。 由于大多数启发式方法使用局部搜索过程中邻域的系统变化来提供解决方案,
Edit
距离(
Levenshtein distance
)非常适合我。
Levenshtein
算法的复杂性为
O(n*m)
其中n和m是两个字符串的长度。因此,通过图形节点和路由的字符串表示,我能够计算出相似性。
编辑操作
可以被视为
邻域操作
,因此它可以被视为搜索空间距离(而不是解空间距离)

A更好的/g
import py_stringmatching as sm
nw = sm.NeedlemanWunsch(gap_cost=0.5, sim_func=lambda s1, s2: (0.0 if s1 == s2 else 1.0))
print('\nNeedleman-Wunsch: ', nw.get_raw_score('045601230', '062401530'))