चक्रवाती जटिलता को समझना


11

मैं हाल ही में Cyclomatic Complexity में आया हूं और मैं इसे बेहतर तरीके से समझने की कोशिश करना चाहता हूं।

विभिन्न कारकों के कुछ व्यावहारिक कोडिंग उदाहरण क्या हैं जो जटिलता की गणना में जाते हैं? विशेष रूप से, विकिपीडिया समीकरण के लिए M = E − N + 2P, मैं बेहतर समझना चाहता हूं कि निम्नलिखित में से प्रत्येक का क्या अर्थ है:

  • ई = ग्राफ के किनारों की संख्या
  • एन = ग्राफ के नोड्स की संख्या
  • पी = जुड़े घटकों की संख्या

मुझे संदेह है कि कोड के एक ब्लॉक में या तो या एन निर्णय बिंदुओं की संख्या हो सकती है (यदि, अन्यथा, यदि, फॉरचेट, आदि), लेकिन मुझे यकीन नहीं है कि कौन सा है या दूसरा कौन सा संकेत देता है। मैं यह भी अनुमान लगा रहा हूं कि पी फ़ंक्शन कॉल और क्लास इंस्टेंटिएशन को संदर्भित करता है, लेकिन एक स्पष्ट परिभाषा नहीं है जिसे मैं देख सकता हूं। यदि कोई प्रत्येक के कुछ स्पष्ट कोड उदाहरणों के साथ थोड़ा और प्रकाश बहा सकता है, तो इससे मदद मिलेगी।

अनुवर्ती के रूप में, क्या साइक्लोमैटिक जटिलता 100% पथ कवरेज के लिए आवश्यक इकाई परीक्षणों की संख्या से सीधे संबंधित है ? एक उदाहरण के रूप में, 4 की जटिलता के साथ एक विधि इंगित करती है कि उस पद्धति को कवर करने के लिए 4 इकाई परीक्षणों की आवश्यकता है?

अंत में, नियमित अभिव्यक्तियाँ साइक्लोमैटिक जटिलता को प्रभावित करती हैं, और यदि हां, तो कैसे?


मैंने पाया कि आप विकिपीडिया से मैककेबे द्वारा मूल पेपर प्राप्त कर सकते हैं और Google पुस्तकें उस पुस्तक का उत्पादन करेंगे जिसका उपयोग मैककेबे ने अपने मूल कागज के लिए किया था। दिलचस्प बात यह है कि तब आपको पता चलेगा कि मैककेबे ने मूल प्रमेय का गलत तरीके से इस्तेमाल किया (और यह भी भ्रमित रूप से समझाता है कि उसे अप्रत्यक्ष ग्राफ़ के साथ शुरू करना चाहिए और इसे पहले स्थान पर मजबूती से जोड़ने की कोई आवश्यकता नहीं है) लेकिन संख्याएं सही तरह से बाहर आती हैं। सही सूत्र M = E + 1-N + P होगा, लेकिन जैसा कि P हमेशा 1 होता है, वह फिट बैठता है ...) यह विचार होता है कि आधुनिक "अपवाद हैंडलिंग" उस मीट्रिक के कार्यों में एक स्पैनर फेंकता है।
डेविड टोनहोफर

... और पुनरावर्ती कॉल के बारे में क्या (संभवतः कार्यों की एक श्रृंखला के माध्यम से जा रहा है)। क्या कोई फ़्यूज़ ग्राफ़ को फ्यूज करता है? "&&" जैसे छोटे परिचालित बूलियन ऑपरेटरों के बारे में कैसे। "रेफरी .x" जैसे संरक्षित संचालक जो रेफरल शून्य है, तो उपज शून्य है? ओह ठीक है, यह सिर्फ एक और मीट्रिक है। लेकिन यहाँ एक छोटे से विश्वविद्यालय परियोजना के लिए कुछ काम है।
डेविड टोनहोफर

जवाबों:


8

सूत्र के बारे में: नोड्स राज्यों का प्रतिनिधित्व करते हैं, किनारों राज्य परिवर्तनों का प्रतिनिधित्व करते हैं। हर कार्यक्रम में, बयान कार्यक्रम की स्थिति में बदलाव लाते हैं। प्रत्येक लगातार बयान को एक किनारे से दर्शाया जाता है, और कार्यक्रम के बाद (या उससे पहले) की स्थिति का विवरण नोड का निष्पादन है।

यदि आपके पास एक शाखा विवरण है ( ifउदाहरण के लिए) - तो आपके पास दो नोड्स निकल रहे हैं, क्योंकि राज्य दो तरीकों से बदल सकता है।

साइक्लोमैटिक कॉम्प्लेक्सिटी नंबर (CCN) की गणना करने का एक और तरीका यह है कि आपके पास निष्पादन के ग्राफ में कितने "क्षेत्र" हैं (जहां "स्वतंत्र क्षेत्र" एक सर्कल है जिसमें अन्य सर्कल शामिल नहीं हैं)। इस मामले में CCN स्वतंत्र क्षेत्रों की संख्या 1 होगा (जो कि पिछले सूत्र आपको देता है, ठीक उसी संख्या में होगा)।

CCN का उपयोग ब्रांचिंग कवरेज या पथ कवरेज के लिए किया जाता है , जो समान है। CCN एक एकल थ्रेडेड अनुप्रयोग में सैद्धांतिक रूप से संभव विभिन्न शाखाओं में बंटी पथ की संख्या के बराबर है (जिसमें " if x < 2 and x > 5 then" जैसी शाखाएं शामिल हो सकती हैं , लेकिन इसे एक अप्राप्य कोड के रूप में एक अच्छे संकलक द्वारा पकड़ा जाना चाहिए)। आपके पास कम से कम अलग-अलग परीक्षण मामलों की संख्या होनी चाहिए (अधिक हो सकती है क्योंकि कुछ परीक्षण मामलों को पिछले वाले द्वारा कवर किए गए पथ दोहरा सकते हैं, लेकिन प्रत्येक मामले को एक पथ को कवर करने से कम नहीं मानते)। यदि आप किसी भी संभावित परीक्षण मामले के साथ एक पथ को कवर नहीं कर सकते हैं - तो आपको अगम्य कोड मिला (हालांकि आपको वास्तव में खुद को साबित करना होगा कि यह अनुपलब्ध क्यों है, शायद कुछ नेस्टेड x < 2 and x > 5लुकिंग कहीं है)।

नियमित अभिव्यक्तियों के रूप में - निश्चित रूप से वे प्रभावित करते हैं, कोड के किसी अन्य टुकड़े के रूप में। हालाँकि, रेगेक्स निर्माण का CCN संभवतः एकल इकाई परीक्षण में शामिल होने के लिए बहुत अधिक है, और आप मान सकते हैं कि regex इंजन का परीक्षण किया गया है, और अपनी परीक्षण आवश्यकताओं के लिए अभिव्यक्ति की शाखा क्षमता की अनदेखी करें (जब तक कि आप अपना परीक्षण नहीं कर रहे हों रेगेक्स इंजन, निश्चित रूप से)।


2
+1: वास्तव में, आपको विश्वास होना चाहिए कि रेगेक्स इंजन का परीक्षण किया गया है। आपको इस पर विश्वास नहीं करते हैं, एक मिल है कि आप कर भरोसा है।
एस.लूट।

"CCN एकल थ्रेडेड एप्लिकेशन में संभव विभिन्न निष्पादन पथों की संख्या के बराबर है" यह गलत है क्योंकि CCN कोड के टोपोलॉजी पर आधारित है न कि इसके अर्थ पर । इन रास्तों का एक अच्छा प्रतिशत व्यायाम करने के लिए असंभव हो सकता है क्योंकि वे इनपुट स्थिति की मांग करते हैं जो सेट नहीं किया जा सकता है (कुछ x 5 और उदाहरण के लिए 2 से कम भी )। सच कहूँ तो, मुझे लगता है कि चलाने के लिए परीक्षण मामलों पर निर्णय लेने के लिए CCN का उपयोग करना विकृत है। CCN डेवलपर को यह बताने के लिए एक नंबर है कि "आप यहाँ पर गए हो सकते हैं, कृपया विचार करें" और फिर भी, उच्च CCN के लिए अच्छा कारण हो सकता है।
डेविड टोनहोफर

1
@ दाविद ने संबोधन में एक वाक्य जोड़ा। CCN एक शाखा कवरेज है और निम्न स्तर पर उच्च CCN के लिए कभी भी अच्छे कारण नहीं होते हैं (आमतौर पर मेरा सुझाव है कि प्रति व्यक्ति फ़ंक्शन लागू करें)।
littleadv

शाखा कवरेज और पथ कवरेज समान नहीं हैं। शाखा कवरेज का उद्देश्य सभी शाखाओं को कवर करना है जबकि पथ कवरेज का उद्देश्य शाखाओं के सभी संयोजनों को कवर करना है।
मौविसियल

13

इस पर कुछ टिप्पणी कि मैं मूर्खतापूर्ण लिखना ...

विशेष रूप से, M = E - N + 2P के विकिपीडिया समीकरण के लिए

वह समीकरण बहुत गलत है

किसी कारण से, मैककेबे वास्तव में इसका उपयोग अपने मूल पेपर ("ए कॉम्प्लेक्सिटी माप", आईईई लेनदेन पर सॉफ्टवेयर इंजीनियरिंग, वीओ .. एसई -2, नंबर 4, दिसंबर 1976) में करता है, लेकिन इसे औचित्य दिए बिना और वास्तव में सही का हवाला देते हुए। पहले पृष्ठ पर सूत्र , जो है

v (जी) = ई - वी + पी

(यहां, सूत्र तत्वों को स्थानांतरित कर दिया गया है)

विशेष रूप से, मैककेब ने सी.बर्गर, ग्राफ़ और हाइपरग्राफ (जी एंड एचजी के नीचे संक्षिप्त रूप में) पुस्तक का संदर्भ दिया है । सीधे उस पुस्तक से :

परिभाषा (पृष्ठ 27 जी और एचजी के नीचे):

एक (अप्रत्यक्ष) ग्राफ जी (जिसमें कई डिस्कनेक्ट किए गए घटक हो सकते हैं) के साइक्लोमैटिक नंबर v (G) को परिभाषित किया गया है:

v (जी) = ई - वी + पी

जहाँ e = किनारों की संख्या, v = संख्याओं की संख्या, p = जुड़े घटकों की संख्या

प्रमेय (पृष्ठ 29 जी एंड एचजी के ऊपर) (मैककेबे द्वारा उपयोग नहीं किया गया):

एक ग्राफ G का चक्रवाती संख्या v (G) स्वतंत्र चक्रों की अधिकतम संख्या के बराबर है

एक चक्र एक ही शीर्ष पर शुरू और समाप्त होने वाले सिरों का एक क्रम है, जिसमें ग्राफ़ में एक दूसरे से सटे अनुक्रम में लगातार दो कोने होते हैं।

सहज रूप से, चक्रों का एक सेट स्वतंत्र है यदि चक्रों को सुपरइम्पोज़ करके दूसरों में से कोई भी चक्र का निर्माण नहीं किया जा सकता है।

प्रमेय (पृष्ठ 29 जी एंड एचजी के बीच) (जैसा कि मैककेबे द्वारा उपयोग किया जाता है):

एक दृढ़ता से जुड़े ग्राफ जी में, चक्रवाती संख्या रैखिक रूप से स्वतंत्र सर्किट की अधिकतम संख्या के बराबर है।

एक सर्किट एक चक्र है जिसमें बिना कोने और किनारों की पुनरावृत्ति की अनुमति है।

एक निर्देशित ग्राफ को दृढ़ता से जुड़ा हुआ कहा जाता है यदि प्रत्येक वर्टेक्स उनके निर्दिष्ट दिशा में किनारों से गुजरते हुए हर दूसरे शीर्ष से पहुंचता है।

ध्यान दें कि यहां हम अप्रत्यक्ष रेखांकन से दृढ़ता से जुड़े ग्राफ़ से गुज़रे हैं (जो निर्देशित हैं ... बर्ज यह पूरी तरह से स्पष्ट नहीं करता है)

मैककेबे अब उपरोक्त प्रमेय को एक "मैककेबे साइक्लोमैटिक कॉम्प्लेक्सिटी नंबर" (सीसीएन) की गणना करने के लिए एक सरल तरीका प्राप्त करने के लिए लागू करता है:

एक प्रक्रिया के "जंप टोपोलॉजी" (निर्देश प्रवाह ग्राफ) का प्रतिनिधित्व करने वाले एक निर्देशित ग्राफ को देखते हुए, एक निर्दिष्ट प्रविष्टि के साथ एक यूनिक एंट्री पॉइंट का प्रतिनिधित्व किया जाता है और एक यूनीवर्सल एग्जिट पॉइंट ( एग्जिट पॉइंट वर्टेक्स) का प्रतिनिधित्व करने के लिए एक निर्दिष्ट वर्कट "निर्माण" करने की आवश्यकता होती है। इसे कई रिटर्न के मामले में जोड़कर), एक्ज़िट पॉइंट वर्टेक्स से एंट्री पॉइंट वर्टेक्स तक निर्देशित किनारे को जोड़कर एक जोरदार कनेक्टेड ग्राफ बनाएँ, जिससे एंट्री पॉइंट वर्टेक्स किसी अन्य वर्टेक्स से पहुंच योग्य हो जाता है।

मैककेबे अब पॉज़िट करता है (बल्कि भ्रामक रूप से मैं कह सकता हूं) कि संशोधित अनुदेश प्रवाह ग्राफ का चक्रवाती नंबर "पथों की न्यूनतम संख्या" की हमारी सहज धारणा के अनुरूप है, और इसलिए हम उस संख्या को जटिलता माप के रूप में उपयोग करेंगे।

शांत, इतना:

संशोधित अनुदेश प्रवाह ग्राफ के चक्रवाती जटिलता संख्या को अप्रत्यक्ष ग्राफ में "सबसे छोटे" सर्किट की गिनती के द्वारा निर्धारित किया जा सकता है। यह विशेष रूप से आदमी या मशीन द्वारा करना मुश्किल नहीं है, लेकिन उपरोक्त प्रमेय को लागू करने से हमें इसे निर्धारित करने का एक आसान तरीका मिल जाता है:

v (जी) = ई - वी + पी

यदि कोई किनारों की दिशा की उपेक्षा करता है।

सभी मामलों में, हम सिर्फ एक ही प्रक्रिया पर विचार करते हैं, इसलिए पूरे ग्राफ में केवल एक जुड़ा हुआ घटक है, और इसलिए:

v (जी) = ई - वी + १।

यदि कोई अतिरिक्त "एक्जिट-टू-एंट्री" एज के बिना मूल ग्राफ पर विचार करता है, तो एक को बस प्राप्त होता है:

= (जी) = ẽ - v + 2

as as = e - 1

आइए अपने पेपर से मैककेबे के उदाहरण का उपयोग करके स्पष्ट करें:

मैककेबे का उदाहरण

हमारे पास है:

  • ई = १०
  • v = 6
  • पी = 1 (एक घटक)
  • v (G) = 5 (हम स्पष्ट रूप से 5 चक्र गिन रहे हैं)

चक्रवाती संख्या का सूत्र कहता है:

v (जी) = ई - वी + पी

जो पैदावार 5 = 10 - 6 + 1 और इतना सही है!

"मैककेब साइक्लोमैटिक जटिलता संख्या" जैसा कि उनके पेपर में दिया गया है

5 = 9 - 6 + 2 (कागज में आगे कोई स्पष्टीकरण नहीं दिया गया है कि कैसे)

जो सही होता है (यह v (G) देता है) लेकिन गलत कारणों से, जिसका हम उपयोग करते हैं:

= (जी) = ẽ - v + 2

और इस प्रकार G (G) = v (G) ... phew!

लेकिन क्या यह उपाय कोई अच्छा है?

दो शब्दों में: बहुत नहीं

  • यह पूरी तरह से स्पष्ट नहीं है कि किसी प्रक्रिया के "निर्देश प्रवाह ग्राफ" को कैसे स्थापित किया जाए, खासकर अगर अपवाद हैंडलिंग और पुनरावृत्ति तस्वीर में प्रवेश करते हैं। ध्यान दें कि मैककेबे ने फोरट्रान 66 में लिखा कोड , बिना किसी पुनरावृत्ति वाली भाषा, बिना किसी अपवाद और सीधी निष्पादन संरचना के अपने विचार को लागू किया ।
  • तथ्य यह है कि एक निर्णय के साथ एक प्रक्रिया और एक लूप के साथ एक प्रक्रिया समान CCN उपज देती है एक अच्छा संकेत नहीं है।

यहाँ छवि विवरण दर्ज करें


1
@JayElston अच्छा कैच। वास्तव में मैं करूंगा। फिक्स्ड!
डेविड टोनहोफर

1
मूल पेपर से जोड़ने के लिए बिग +1। उस समय के बारे में लिखे गए कई कागजात किसी भी मध्य स्तर के प्रोग्रामर के लिए काफी पठनीय हैं और उन्हें पढ़ा जाना चाहिए।
डैनियल टी।

1

अनुवर्ती के रूप में, क्या साइक्लोमैटिक जटिलता 100% पथ कवरेज के लिए आवश्यक इकाई परीक्षणों की संख्या से सीधे संबंधित है?

हां, मूल रूप से। रिफ्लेक्टर कब देना है, इसका एक संकेत के रूप में साइक्लोमैटिक जटिलता का उपयोग करना भी एक अच्छा विचार है। मेरे अनुभव में, निचली सीसी के लिए परीक्षणशीलता और पुन: प्रयोज्यता बहुत बढ़ जाती है (हालांकि आपको व्यावहारिक होना चाहिए - ओवर-रिफ्लेक्टर नहीं है, और कुछ तरीकों में उनके स्वभाव के कारण उच्च सीसी होगा - यह हमेशा कोशिश करने और इसे मजबूर करने के लिए समझ में नहीं आता है कम)।

अंत में, नियमित अभिव्यक्तियाँ साइक्लोमैटिक जटिलता को प्रभावित करती हैं, और यदि हां, तो कैसे?

हां, यदि आप सटीक होना चाहते हैं, हालांकि अधिकांश कोड विश्लेषण उपकरण उन्हें उस तरह से ध्यान में नहीं लेते हैं। नियमित अभिव्यक्ति सिर्फ परिमित राज्य मशीनें हैं, इसलिए मुझे लगता है कि उनके CC की गणना FSM ग्राफ से की जा सकती है, लेकिन यह काफी बड़ी संख्या होगी।


+1 - मैं अनुमान लगा रहा हूं कि RegExes के लिए CC की गणना करना कोई मज़ेदार काम नहीं है।
VirtuosiMedia
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.