【问题标题】:Cyclomatic complexity of IF((A>B) AND (C>D)) and IF((A>B) OR (C>D))IF((A>B) AND (C>D)) 和 IF((A>B) OR (C>D)) 的圈复杂度
【发布时间】:2012-09-26 10:43:48
【问题描述】:

我想知道两段代码的圈复杂度,

IF((A>B) AND (C>D)) 
{ a=a+b;c=c+d;}

据我所知,上述代码的圈复杂度=2+1=3,

另一个代码

IF((A>B) OR (C>D))
{a=a+b;c=c+d;}

以上代码的复杂度是=4+1=5,

上述复杂性是否正确?

【问题讨论】:

    标签: cyclomatic-complexity


    【解决方案1】:

    两个复杂度相同且等于 3,以 4 种方式计算。我同意 Neil 使用 De Morgan 证明它们是相同的,我认为可以从对复杂性计数很重要的图表中看到相同的情况。

    图表

    让我们从两个代码段的图表开始。

    解释的话:

    1. McCabe 图由基本块组成,这意味着我可以将许多语句合并为一个,只要控制在它们之间线性传递。
    2. 我将您的代码视为简单的过程,一个入口点,一个出口点。
    3. 退出点被添加为所有结束的接收器。在此请注意,因为我很少有使用 McCabe 计算代码构建图形的示例,但我记得没有一个示例是这样做的,但我认为这感觉很自然,考虑到什么是基本块以及节点/边的含义。
    4. 出口和入口点之间的边缘仅与简化复杂性计算相关,因此注释和不同的标记(颜色、箭头)。
    5. 基本块由可能非线性传递控制的指令分隔:while、for、if 等。
    6. 引用 McCabe 本人,AND 和 OR 增加了复杂性 +1,因为它们基本上是 if and ifif or if,所以有两个 if。因此我的第二个节点是一个单独的节点。

    如您所见,两个代码段之间的数字没有区别。节点、边、区域都是一样的。区别在于哪个节点与哪个节点连接,这来自于短路的工作原理。显然,对于没有它的语言,图表需要有所不同。

    复杂性定义

    不止一个。复杂度等于

    边 - 节点 + 2*(出口)

    边数 = 5;节点 = 4;退出 = 1;

    两种情况下的复杂度 = 5-4+2*(1) = 3。此定义不需要强连通图,因此我们删除了添加的边。

    边 - 节点 + 出口提供强连通图

    边数 = 6;节点 = 4;退出 = 1;

    两种情况下的复杂度 = 6-4+1 = 3。这个定义的出现是因为它在拓扑上更有意义,并且在循环计数(图形方式)方面更容易考虑。当您考虑计算许多例程/函数的复杂性时,它会更有用,比如类中的所有方法。因此,认为可以在循环中调用函数是有道理的。但我离题了。

    地区

    地区:3。

    这来自欧拉公式 区域 + 节点 - 边 = 2 改写这个: 区域 = 边 - 节点 + 2

    因此,区域的数量与复杂性相同(假设一个出口点)。这是为了在单出口子例程中简化图表中的计数复杂性。

    决策点+1

    McCabe 自己指出

    在实践中,复合谓词如 IF "c1 AND c2" THEN 被视为有贡献 两个复杂度,因为没有连接词 AND 我们将有 IF c1 THEN IF c2 THEN 它有两个谓词。出于这个原因和测试目的,已经发现 在计算复杂度时更方便计算条件而不是谓词

    在两个代码段中,我们都有一个复合条件,所以 Decisions = 2;

    复杂度 = 2+1 = 3。

    值得注意的是,圈复杂度以计数循环开始,但出于实用目的以计数条件结束。

    进一步阅读

    先试试 McCabe 的论文http://www.literateprogramming.com/mccabe.pdf

    维基百科有一篇很好的文章依赖于该论文,但我发现如果不遵循基本块和连接组件是不够的:

    1. http://en.wikipedia.org/wiki/Cyclomatic_complexity
    2. http://en.wikipedia.org/wiki/Basic_block
    3. http://en.wikipedia.org/wiki/Connected_component_(graph_theory)

    我在钱伯斯的页面上找到了一个简洁但很好的总结:http://www.chambers.com.au/glossary/mc_cabe_cyclomatic_complexity.php

    第 8 章中的“软件工程集成方法”一书有一个示例说明复杂性计算(尽管我认为他们在图上吃了一条边,图 8.7)。

    http://books.google.pl/books?id=M-mhFtxaaskC&lpg=PA385&ots=jB8P0avJU7&d&hl=pl&pg=PR1#v=onepage

    【讨论】:

      【解决方案2】:

      我认为它们具有相同的圈复杂度 3;这可以使用德摩根定律来证明。

      IF((A>B) OR (C>D)) {a=a+b;c=c+d;} ELSE {}
      
      IF(!((A>B) OR (C>D))) {} ELSE {a=a+b;c=c+d;}
      
      IF(!(A>B) AND !(C>D)) {} ELSE {a=a+b;c=c+d;}
      

      查看它的另一种方法是获取图形并交换条件块和退出点(并反转它们之间的边),这会将其从 AND 转换为 OR,而不会更改节点或边的数量。

      【讨论】:

      • 在第一种情况下 'if ((a>b) AND (c>d)){a=a+b; c=c+d;}' 我们可以写成 'if(a>b){ if(c>d){a=a+b; c=c+d;}' 所以很明显复杂度是条件 +1 的数量,即 2+1=3。但是第二种情况我们可以写成 'IF(a>b) { if(c>d){a=a+b; c=c+d;} if(c!>d){a=a+b; c=c+d;} } ELSE{ 如果 (c>d){a=a+b; c=c+d;}}' 所以复杂度根据公式没有。 if 条件 +1 即 4+1=5
      • 没有理智的编译器会这样做。
      猜你喜欢
      • 2011-06-13
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 2018-09-14
      • 1970-01-01
      • 2015-06-15
      相关资源
      最近更新 更多