Algumas observações sobre isso que eu ociosamente escrevo ...
Especificamente, para a equação da Wikipedia de M = E - N + 2P
Essa equação está muito errada .
Por alguma razão, McCabe realmente o usa em seu artigo original ("Uma Medida de Complexidade", IEEE Transactions on Software Engineering, Vo .. SE-2, No.4, dezembro de 1976), mas sem justificá-lo e depois de realmente citar o correto fórmula na primeira página, que é
v (G) = e - v + p
(Aqui, os elementos da fórmula foram rotulados novamente)
Especificamente, McCabe faz referência ao livro C.Berge, Graphs and Hypergraphs (abreviado abaixo para G&HG). Diretamente desse livro :
Definição (página 27 na parte inferior da G&HG):
O número ciclomático v (G) de um gráfico (não direcionado) G (que pode ter vários componentes desconectados) é definido como:
v (G) = e - v + p
onde e = número de arestas, v = número de vértices, p = número de componentes conectados
Teorema (página 29 no topo de G&HG) (não usado por McCabe):
O número ciclomático v (G) de um gráfico G é igual ao número máximo de ciclos independentes
Um ciclo é uma sequência de vértices iniciando e terminando no mesmo vértice, com cada dois vértices consecutivos na sequência adjacentes um ao outro no gráfico.
Intuitivamente, um conjunto de ciclos é independente se nenhum dos ciclos puder ser construído dos outros, sobrepondo as caminhadas.
Teorema (página 29 no meio de G&HG) (usado por McCabe):
Em um gráfico fortemente conectado G, o número ciclomático é igual ao número máximo de circuitos linearmente independentes.
Um circuito é um ciclo sem repetições de vértices e arestas permitidas.
Diz-se que um gráfico direcionado está fortemente conectado se todos os vértices puderem ser alcançados a partir de qualquer outro vértice passando pelas bordas na direção designada.
Observe que aqui passamos de gráficos não direcionados para gráficos fortemente conectados (que são direcionados ... Berge não deixa isso totalmente claro)
McCabe agora aplica o teorema acima para derivar uma maneira simples de calcular um "Número de complexidade ciclomática de McCabe" (CCN) da seguinte forma:
Dado um gráfico direcionado representando a "topologia de salto" de um procedimento (o gráfico de fluxo de instruções), com um vértice designado representando o ponto de entrada exclusivo e um vértice designado representando o ponto de saída exclusivo (o vértice do ponto de saída pode precisar ser "construído" adicionando-o no caso de retornos múltiplos), crie um gráfico fortemente conectado adicionando uma aresta direcionada do vértice do ponto de saída ao vértice do ponto de entrada, tornando assim o vértice do ponto de entrada acessível a partir de qualquer outro vértice.
McCabe agora postula (de maneira bastante confusa) que o número ciclomático do gráfico de fluxo de instruções modificado "está de acordo com nossa noção intuitiva de 'número mínimo de caminhos'" e, portanto, devemos usar esse número como medida de complexidade.
Legal, então:
O número de complexidade ciclomática do gráfico de fluxo de instruções modificado pode ser determinado contando os "menores" circuitos no gráfico não direcionado. Isso não é particularmente difícil de ser feito pelo homem ou pela máquina, mas a aplicação do teorema acima nos fornece uma maneira ainda mais fácil de determiná-lo:
v (G) = e - v + p
se alguém desconsiderar a direcionalidade das arestas.
Em todos os casos, consideramos apenas um único procedimento, portanto, há apenas um componente conectado no gráfico inteiro e, portanto:
v (G) = e - v + 1.
Caso se considere o gráfico original sem a borda "saída a entrada" adicionada , obtém-se simplesmente:
ṽ (G) = ẽ - v + 2
como ẽ = e - 1
Vamos ilustrar usando o exemplo de McCabe de seu artigo:
Aqui temos:
- e = 10
- v = 6
- p = 1 (um componente)
- v (G) = 5 (estamos contando claramente 5 ciclos)
A fórmula para o número ciclomático diz:
v (G) = e - v + p
que produz 5 = 10 - 6 + 1 e, portanto, correto!
O "número de complexidade ciclomática de McCabe", conforme indicado em seu artigo, é
5 = 9 - 6 + 2 (nenhuma explicação adicional é fornecida no artigo sobre como)
que está correto (resulta em v (G)), mas pelas razões erradas, ou seja, usamos:
ṽ (G) = ẽ - v + 2
e assim ṽ (G) = v (G) ... ufa!
Mas essa medida é boa?
Em duas palavras: não muito
- Não está totalmente claro como estabelecer o "gráfico de fluxo de instruções" de um procedimento, especialmente se o tratamento e a recursão de exceção entrarem em cena. Observe que McCabe aplicou sua idéia ao código escrito no FORTRAN 66 , uma linguagem sem recursão, sem exceções e uma estrutura de execução direta.
- O fato de um procedimento com uma decisão e um procedimento com um loop produzir o mesmo CCN não é um bom sinal.
- Ainda menos bom é o fato de que
for
loops e while
loops são tratados da mesma maneira (observe que em C, pode-se abusar da for
expressão de uma while
de outra maneira; aqui estou falando sobre o for (int i=0;i<const_val;i++)
loop estrito ). Sabemos pela ciência da computação teórica que essas duas construções produzem poderes computacionais totalmente diferentes: funções primitivas-recursivas se você estiver equipado apenas for
, funções μ-recursivas parciais se você estiver equipado while
.
- Um experimento com especialistas julgar a complexidade de shows de código que CCN não capta a idéia de "complexidade do código", bem como outras medidas, nomeadamente a ciência software da Halstead e tamanho funcional cognitiva Shao e Wangs' (sendo este último, aparentemente, o vencedor), consulte Aplicabilidade de três métricas de complexidade cognitiva, Conferência Internacional sobre Avanços em TIC para Regiões Emergentes, 2012, de 12 a 15 de dezembro de 2012.
- A verificação empírica mostra que (pelo menos para código maduro), o CCN está fortemente correlacionado linearmente com o LOC (linhas de código), ou seja, o CCN aumenta naturalmente com a duração do procedimento e você também pode usar a contagem de LOC para expressar complexidade. Uma medida melhor que a CCN absoluta pode ser CCN / LOC. Veja em particular: Métricas de complexidade ciclomática revisitadas - DSpace @ MIT e O papel do empirismo na melhoria da confiabilidade de futuros softwares