这是一个示例程序依赖图。**
这是生成上图的代码。我想比较这两种类型的两个图形,有没有任何方法比较这些图形的相似性百分比。我也在考虑比较图形的图像以获得相似百分比,请建议我该怎么做。
digraph cfg {
subgraph cluster_sum {
graph [label="sum"];
s1[label="i = 0;"];
s1 -> s2;
s2[label="sum_0 = 0;"];
s2 -> s3;
s3[label="i = x;"];
s3 -> s4;
s4[label="<loop>"];
s4 -> s6;
s6[label="if i <= y"];
s6 -> s8;
s6 -> s7;
s7[label="<break>"];
s7 -> s11;
s8[label="<enter block>"];
s8 -> s9;
s9[label="sum_0 -= i;"];
s9 -> s10;
s10[label="i ++;"];
s10 -> s4;
s11[label="<return>"];
}
subgraph cluster_main {
graph [label="main"];
s13[label="res = 0;"];
s13 -> s14;
s14[label="a = 2;"];
s14 -> s15;
s15[label="b = 5;"];
s15 -> s16;
s16[label="res = sum(a,b);"];
s16 -> s17;
s17[label="printf(\"%d\",res);"];
s17 -> s18;
s18[label="__retres = 0;"];
s18 -> s21;
s21[label="<return>"];
}
}
答案 0 :(得分:2)
最简单的方法是将图形(可以使用ocamlgraph
库在OCaml中读取)转换为规范化形式,其中删除所有语法差异(例如,使用通用命名方案重命名所有变量)或者用正则表达式代替),然后你可以根据比较函数比较得到的图形。
但当然这只是一个黑客攻击。对于更复杂的课程,你应该参加几门课程分析,撰写论文,回答自己,一般来说它是无法解决的......但最终,你会写出像BinDiff这样的东西。
关于比较两张图片的内容,我认为它甚至是一个更粗糙的黑客。但通常的方法是进行2D卷积,这将使您回归平等。 OCaml fftw
库拥有您需要的一切。
答案 1 :(得分:1)
通过查看渲染图像来比较图形的方法很糟糕:Graphviz可以自由地替换节点的位置,甚至可以轻微地修改图形。
您应该以更代数的方式比较图形,但算法将高度依赖于您如何定义&#34;相似性&#34;。如果我是你,我会尝试编辑树木的距离。我最近用它来衡量&#34;相似性&#34; OCaml类型表达式(是的,它们的AST基本上是树,但可以有循环),并得到了一个很好的结果。您应该能够通过搜索&#34;编辑树的距离来找到大量信息&#34;。
程序执行流程具有循环,因此它们可能应该作为一般有向图而不是具有少量循环的树进行比较。我相信应该有一些专门的研究工作,但我根本不知情。
为了实现,我从未尝试过,但是OCamlDot(http://zoggy.github.io/ocamldot/)可以用来解析点文件格式以获得图形的代数表示。