概述
若干年以后,由于转行或者不再做技术等原因,你可能已经记不太清楚之前费尽千辛万苦习得的各种技术细节;但是,最终你会发现:依然有很多宝贵的概念留存并沉淀于脑海深处(比如中学课本中的某些物理概念)。
今天来一起了解下:基于模型开发中,一个非常重要的概念---圈复杂度。
1,圈复杂度
simulink官方文档定义如下:
读起来,会不会有点懵圈呢?
没关系。后面会逐步进行解释。
首先圈复杂度可以用来衡量单元模型的结构复杂程度。
圈复杂度越高,说明模型越复杂,可测性就越差,那么相对来说也更容易出问题。
如果你设计过相对复杂的逻辑,可能体会更加深刻一些,因为它真的容易出错啊。
因此,这也给我们一些警示:
作为软件架构工程师,需要合理划分软件单元。不能让某个单元过于复杂,以至于难以测试。
作为模型开发者,应该尽量使用更简洁的方式搭建或者表达模型(别忘了美国程序员因无法忍受同事代码不规范而枪杀4名同事的疯狂事迹)。这就需要在软件需求分析方面多下功夫:用心解读软件需求,并弄清楚其内在的逻辑性和关联性。
2,Simulink如何计算圈复杂度?
那么simulink中,圈复杂度是如何计算的呢?
按Fig1 中定义的公式:
其中N代表判定分支节点的个数,
需要指出,if else 、switch case 、 for/while循环等,都属于一个判定分支节点。
2.1,switch模块
对于该子系统,只存在一个判定节点,即switch模块(其生成代码后就是一个if else语句呀),且该模块输出只有两种可能,即true or false。
因此圈复杂度为:
覆盖度报告中给出的圈复杂度结果也为1,如下图:
可以看出,simulink计算的圈复杂度和圈复杂度原始的概念定义存在一些差别。
维基百科:圈复杂度由Thomas J. McCabe, Sr.于1976年提出。圈复杂度大小可以表示为判定分支节点数目加1。按照这个原始定义的话,switch模块的圈复杂度应该为1+1=2。注意这点区分就行了。
2.2,Multiport Switch模块
对于该子系统,只存在一个判定分支模块,即MultiportSwitch模块(生成代码后就是switch case语句呀),而且这个分支模块输出只有4种可能,即inport2,inport3,inport4或inport5。
圈复杂度为:
和覆盖度报告中提供的结果相等,如下图:
2.3,stateflow流程图
可将for循环看作一个判定模块,共有三个判定分支模块,每个判定节点均有两种结果(true or false)。
覆盖度报告中的计算结果如下图,和上述计算结果相同:
那为什么stateflow内部逻辑的圈复杂度结果为3,而整个stateflow子系统的结果却为4呢?
见圈复杂度定义Fig1:对于stateflow模块或者原子子系统,需要额外加1。
那么,Fig 8中模型的圈复杂度为多少呢?
有人认为,它是3,其实也不错,这是由原始的圈复杂度定义所得出的结果。
simulink却定义它仍然是1,如下图:
这也是simulink中的圈复杂度定义与已有圈复杂度定义的区别之处:simulink中,它仅仅和判定分支覆盖(Decision)概念相对应,和条件覆盖(Condition)没有必然联系。
至于Decision/Condition/MCDC覆盖之间的区别,我们后面再讨论。
3,降低圈复杂度
好了,说了这么多,目的不就是想降低圈复杂度吗?
该如何做呢?
我这里仅仅举一个简单的例子,以抛砖引玉。如果大家有好想法(可以降低圈复杂度),欢迎评论区讨论。
由前述分析可知:如果能降低判定分支数目,那么也就能降低圈复杂度。
举例如下。
Simulink模型为:
case合并前的逻辑为:
function out = unmerge(input)
switch(input)
case 1
out=2;
case 2
out=4;
case 3
out=6;
case 4
out=10;
otherwise
out=100;
end
case合并后的逻辑为:
function out = merge(input)
switch(input)
case {1,2,3}
out=input*2;
case 4
out=10;
otherwise
out=100;
end
执行仿真,获得case合并前后的圈复杂度及判定覆盖度(分支覆盖度)对比结果,如下图:
可知,合并case后,圈复杂度从6降低为4,基于同样的测试案例输入(见下图),合并后的matlab function 判定覆盖度已经达到100%;而未执行合并的判定覆盖度仅为67%,需要提供更多的测试输入才能达到100%覆盖。
可知,圈复杂度降低,使得逻辑更加简洁的同时,也可以提高测试效率(让测试更简单)!!!
不足之处,希望大佬们不吝指出。
如果本篇文章对你有些帮助或者启发,记得点赞哦。
你也可以关注我的公众号:土人很土。
参考文献:
1,matlab官方帮助文档
2,圈复杂度原理和实践
最后
以上就是忐忑老鼠为你收集整理的simulink中if模块_Simulink与圈复杂度的全部内容,希望文章能够帮你解决simulink中if模块_Simulink与圈复杂度所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复