Alcune osservazioni su questo che scrivo pigramente ...
In particolare, per l'equazione di Wikipedia di M = E - N + 2P
Quell'equazione è molto sbagliata .
Per qualche ragione, McCabe lo utilizza davvero nel suo documento originale ("A Complexity Measure", IEEE Transactions on Software Engineering, Vo .. SE-2, No.4, December 1976), ma senza giustificarlo e dopo aver effettivamente citato il corretto formula sulla prima pagina, che è
v (G) = e - v + p
(Qui, gli elementi della formula sono stati rietichettati)
In particolare, McCabe fa riferimento al libro C.Berge, Graphs and Hypergraphs (abbreviato di seguito in G&HG). Direttamente da quel libro :
Definizione (pagina 27 in fondo a G&HG):
Il numero ciclomatico v (G) di un grafico (non orientato) G (che può avere diversi componenti disconnessi) è definito come:
v (G) = e - v + p
dove e = numero di spigoli, v = numero di vertici, p = numero di componenti collegati
Teorema (pagina 29 in cima a G&HG) (non usato da McCabe):
Il numero ciclomatico v (G) di un grafico G è uguale al numero massimo di cicli indipendenti
Un ciclo è una sequenza di vertici che iniziano e finiscono con lo stesso vertice, con ogni due vertici consecutivi nella sequenza adiacenti l'uno all'altro nel grafico.
Intuitivamente, una serie di cicli è indipendente se nessuno dei cicli può essere costruito dagli altri sovrapponendo le camminate.
Teorema (pagina 29 al centro di G&HG) (usato da McCabe):
In un grafico G fortemente connesso, il numero ciclomatico è uguale al numero massimo di circuiti linearmente indipendenti.
Un circuito è un ciclo senza ripetizioni di vertici e bordi consentiti.
Si dice che un grafico diretto è fortemente connesso se ogni vertice è raggiungibile da ogni altro vertice passando attraverso i bordi nella direzione designata.
Si noti che qui si è passati da grafi non orientati a grafici fortemente connesse (che sono diretti ... Berge non rende questo tutto chiaro)
McCabe ora applica il suddetto teorema per derivare un modo semplice per calcolare un "McCabe Cyclomatic Complexity Number" (CCN) in questo modo:
Dato un grafico diretto che rappresenta la "topologia di salto" di una procedura (il diagramma di flusso dell'istruzione), con un vertice designato che rappresenta il punto di ingresso univoco e un vertice designato che rappresenta il punto di uscita univoco (potrebbe essere necessario "costruire" il vertice del punto di uscita aggiungendolo in caso di più ritorni), creare un grafico fortemente connesso aggiungendo un bordo diretto dal vertice del punto di uscita al vertice del punto di entrata, rendendo così il vertice del punto di entrata raggiungibile da qualsiasi altro vertice.
McCabe ora ipotizza (piuttosto confondentemente direi) che il numero ciclomatico del diagramma di flusso delle istruzioni modificato "sia conforme alla nostra nozione intuitiva di" numero minimo di percorsi "", e quindi useremo quel numero come misura di complessità.
Bene, quindi:
Il numero di complessità ciclomatica del diagramma di flusso delle istruzioni modificato può essere determinato contando i circuiti "più piccoli" nel grafico non diretto. Questo non è particolarmente difficile da fare da parte dell'uomo o della macchina, ma l'applicazione del teorema sopra ci dà un modo ancora più semplice per determinarlo:
v (G) = e - v + p
se si ignora la direzionalità dei bordi.
In tutti i casi, consideriamo solo una singola procedura, quindi c'è un solo componente collegato nell'intero grafico e quindi:
v (G) = e - v + 1.
Nel caso in cui si consideri il grafico originale senza il bordo "exit-to-entry" aggiunto , si ottiene semplicemente:
ṽ (G) = ẽ - v + 2
come ẽ = e - 1
Illustriamo usando l'esempio di McCabe dal suo articolo:
Qui abbiamo:
- e = 10
- v = 6
- p = 1 (un componente)
- v (G) = 5 (contiamo chiaramente 5 cicli)
La formula per il numero ciclomatico dice:
v (G) = e - v + p
che produce 5 = 10 - 6 + 1 e quindi corretto!
Il "numero di complessità ciclomatica di McCabe" riportato nel suo documento è
5 = 9 - 6 + 2 (non sono fornite ulteriori spiegazioni nel documento su come)
che sembra essere corretto (produce v (G)) ma per ragioni sbagliate, cioè usiamo:
ṽ (G) = ẽ - v + 2
e quindi ṽ (G) = v (G) ... eh!
Ma questa misura è buona?
In due parole: non molto
- Non è del tutto chiaro come stabilire il "diagramma di flusso delle istruzioni" di una procedura, specialmente se la gestione delle eccezioni e la ricorsione entrano nell'immagine. Si noti che McCabe ha applicato la sua idea al codice scritto in FORTRAN 66 , una lingua senza ricorsione, senza eccezioni e una struttura di esecuzione semplice.
- Il fatto che una procedura con una decisione e una procedura con un ciclo producano lo stesso CCN non è un buon segno.