我懒散地写了一些关于此的评论...
具体来说,对于Wikipedia方程,M = E − N + 2P
这个等式是非常错误的。
由于某种原因,McCabe确实在他的原始论文中使用了它(“复杂性测度”,IEEE Transactions on Software Engineering,Vo。SE-2,No.4,1976年12月),但没有给出正当理由,并且在引用了正确的文献后第一页上的公式
v(G)= e-v + p
(此处,公式元素已重新标记)
特别是,McCabe引用了《C.Berge,图和超图》一书(以下缩写为G&HG)。直接从那本书:
定义(G&HG的第27页底部):
(无向)图G(可能具有多个断开的分量)的圈数v(G)定义为:
v(G)= e-v + p
其中e =边数,v =顶点数,p =连接的组件数
定理(《 G&HG》第29页顶部)(未被McCabe使用):
图G的圈数v(G)等于独立循环的最大数目
甲周期是开始,并在同一顶点结束,与序列中在图中彼此相邻的每两个连续的顶点的顶点序列。
直观地,如果没有一个循环可以通过叠加行走而与其他循环构成,则一组循环是独立的。
定理(G&HG的第29页中间)(由McCabe使用):
在强连接图G中,圈数等于线性独立电路的最大数目。
甲电路是不允许有顶点和边的重复的循环。
如果每个顶点都可以通过沿其指定方向穿过边而从每个其他顶点到达,则称有向图是牢固连接的。
请注意,这里我们从无向图传递到强连接图(有向图 ... Berge并未完全清楚这一点)
现在,McCabe应用上述定理得出一种简单的方法来计算“ McCabe环复杂度数”(CCN):
给定一个表示过程“跳转拓扑”的有向图(指令流图),其中指定的顶点表示唯一的入口点,指定的顶点表示唯一的出口点(可能需要“构造”出口点的顶点)通过在有多个返回的情况下将其相加),通过将从出口点顶点到入口点顶点的有向边添加有向边来创建强连接图,从而使入口点顶点可从任何其他顶点到达。
McCabe现在假定(我可能会说这有点令人困惑),修改后的指令流程图的圈数“符合我们对“最小路径数”的直观概念”,因此我们将使用该数作为复杂性度量。
很酷,所以:
可以通过对无向图中的“最小”电路进行计数来确定修改后的指令流程图的圈复杂度数。用人或机器并不是很难做到这一点,但是应用上述定理可以使我们更容易地确定它:
v(G)= e-v + p
如果忽略边缘的方向性。
在所有情况下,我们只考虑一个过程,因此整个图中只有一个连接的组件,因此:
v(G)= e-v + 1。
如果考虑原始图而没有添加“退出进入”边缘,则可以简单地获得:
ṽ(G)=ẽ-v + 2
如ẽ= e-1
让我们用他的论文中的McCabe的例子来说明:
这里我们有:
- e = 10
- v = 6
- p = 1(一个分量)
- v(G)= 5(我们显然在计算5个周期)
圈数的公式表示:
v(G)= e-v + p
得出5 = 10-6 + 1,所以正确!
他的论文中给出的“ McCabe圈复杂度数”为
5 = 9-6 + 2(本文没有给出进一步的解释)
碰巧是正确的(它产生v(G)),但是由于错误的原因,即我们使用:
ṽ(G)=ẽ-v + 2
因此ṽ(G)= v(G)... phe!
但这有什么好处吗?
用两个词来说:不是很
- 尚不清楚如何建立程序的“指令流程图”,特别是在异常处理和递归进入画面的情况下。请注意,McCabe将他的想法应用到了用FORTRAN 66编写的代码中,该语言没有递归,没有异常且具有简单的执行结构。
- 具有决策的过程和具有循环的过程产生相同的CCN的事实并不是一个好兆头。