Деякі зауваження з цього приводу, що я складно пишу ...
Зокрема, для Вікіпедії рівняння M = E - N + 2P
Це рівняння дуже неправильне .
Чомусь МакКейб справді використовує це у своєму первісному документі ("Захід про складність", IEEE Transaction on Software Engineering, Vo .. SE-2, No.4, грудень 1976 р.), Але не виправдовуючи це і після фактичного посилання на правильне формула на першій сторінці, яка є
v (G) = e - v + p
(Тут елементи формули були відновлені)
Зокрема, МакКейб посилається на книгу C.Berge, Graphs and Hypergraphs (скорочено нижче G&HG). Безпосередньо з цієї книги :
Визначення (стор. 27 внизу G&HG):
Цикломатичне число v (G) (непрямого) графіка G (який може мати декілька від'єднаних компонентів) визначається як:
v (G) = e - v + p
де e = кількість ребер, v = кількість вершин, p = кількість з'єднаних компонентів
Теорема (стор. 29 вгорі G&HG) (не використовується McCabe):
Цикломатичне число v (G) графа G дорівнює максимальній кількості незалежних циклів
Цикл являє собою послідовність вершин , починаючи і закінчуючи в одній вершині, з кожними двома послідовними вершинами в послідовності суміжних один з одним в графіку.
Інтуїтивно зрозумілий набір циклів не залежить, якщо жоден з циклів не може бути побудований з інших шляхом накладення прогулянок.
Теорема (стор. 29, середина G&HG) (як використовує МакКейб):
У сильно зв'язаному графіку G цикломатичне число дорівнює максимальній кількості лінійно незалежних ланцюгів.
Схема є циклом, без повторень вершин і ребер , дозволених.
Кажуть, що спрямований графік сильно пов'язаний, якщо кожна вершина досягається від кожної іншої вершини, проходячи через ребра в їх визначеному напрямку.
Зауважте, що тут ми перейшли від ненаправлених графіків до сильно з’єднаних графіків (які спрямовані ... Берж не робить це повністю зрозумілим)
МакКейб зараз застосовує вищевказану теорему, щоб отримати простий спосіб обчислити таким чином "число цикломатичної складності МакКабі" (CCN):
Даний спрямований графік, що представляє "топологію стрибка" процедури (графік потоку інструкцій), з позначеною вершиною, що представляє унікальну точку входу, і позначеною вершиною, що представляє унікальну точку виходу (вершину точки виходу може знадобитися "побудувати" додавши його у випадку декількох повернень), створіть сильно з’єднаний графік, додавши спрямований край від вершини точки виходу до вершини точки вступу, зробивши таким чином вершину точки входу доступною для будь-якої іншої вершини.
МакКейб зараз вважає (досить заплутано я можу сказати), що цикломатичне число модифікованого графіка потоку інструкцій "відповідає нашому інтуїтивному поняттю" мінімальна кількість шляхів ", і тому ми будемо використовувати це число як міру складності.
Класно, так:
Цикломатичний номер складності модифікованого графіка потоку інструкцій може бути визначений шляхом підрахунку "найменших" схем у непрямому графіку. Це не особливо важко зробити людиною чи машиною, але застосування вищевказаної теореми дає нам ще простіший спосіб її визначення:
v (G) = e - v + p
якщо нехтувати спрямованістю ребер.
У всіх випадках ми просто розглядаємо одну процедуру, тому в усьому графіку є лише один підключений компонент, і так:
v (G) = e - v + 1.
Якщо ви вважаєте оригінальний графік без доданого краю "вихід-вхід" , ви отримуєте просто:
ṽ (G) = ẽ - v + 2
як ẽ = e - 1
Давайте проілюструємо, використовуючи приклад МакКейба з його статті:
Тут ми маємо:
- e = 10
- v = 6
- p = 1 (одна складова)
- v (G) = 5 (ми чітко підраховуємо 5 циклів)
Формула цикломатичного числа говорить:
v (G) = e - v + p
який дає 5 = 10 - 6 + 1 і так правильно!
"Цикломатичний номер складності МакКейба", як зазначено в його статті, є
5 = 9 - 6 + 2 (більше жодних пояснень у роботі не наводиться)
що буває правильним (він дає v (G)), але з неправильних причин, тобто ми використовуємо:
ṽ (G) = ẽ - v + 2
і, отже, ṽ (G) = v (G) ... феу!
Але чи корисний цей захід?
Два слова: Не дуже
- Не зовсім зрозуміло, як встановити "графік потоку інструкцій" процедури, особливо, якщо обробка виключень та рекурсія входять у зображення. Зауважимо, що МакКейб застосував свою ідею до коду, написаного на FORTRAN 66 , мові без рекурсії, без винятків та прямої структури виконання.
- Те, що процедура з рішенням і процедура з циклом дають ту саму CCN, не є хорошим знаком.
- Ще менш корисним є той факт, що
for
петлями та while
петлями обробляються однаково (зауважте, що в C можна зловживати for
виразом а while
іншим способом; тут я говорю про сувору for (int i=0;i<const_val;i++)
петлю). З теоретичної інформатики ми знаємо, що ці дві конструкції дають абсолютно різні обчислювальні сили: примітивно-рекурсивні функції, якщо ви лише оснащені for
, часткові μ-рекурсивні функції, якщо вам це оснащено while
.
- Експеримент , що мають експерт судити про складність коду показує , що CCN не відображає ідею «коду складності», а також інших заходів, зокрема програмного забезпечення науки HALSTEAD в і пізнавальному функціональному розмірі Шао і Wangs ' (останній , по- видимому переможець), див. Застосування трьох показників когнітивної складності, Міжнародна конференція з питань розвитку ІКТ для країн, що розвиваються, 12-15 грудня 2012 р.
- Емпірична верифікація показує, що (принаймні для зрілого коду) CCN сильно лінійно корелює з LOC (рядки коду), тобто CCN природно збільшується з тривалістю процедури, і ви можете також скористатися підрахунком LOC для вираження складності. Кращою мірою, ніж абсолютна CCN, може бути CCN / LOC. Див. Зокрема: Переглянуті метрики цикломатичної складності - DSpace @ MIT та Роль емпіризму в підвищенні надійності майбутнього програмного забезпечення