लूप आक्रमणकारी क्या है?


268

मैं सीएलआरएस द्वारा "इंट्रोडक्शन टू एलगोरिदम" पढ़ रहा हूं। अध्याय 2 में, लेखक "लूप इनवेरिएंट्स" का उल्लेख करते हैं। लूप आक्रमणकारी क्या है?


4
यह समझाने में बहुत अच्छा लगता है: cs.miami.edu/~burt/learning/Math120.1/Notes/LoopInvar.html
टॉम गुलेन

इस लिंक की जाँच करें प्रोग्रामर
आदिल अब्बासी

बस अगर कोई व्यक्ति लूप इनवेरिएंट की अवधारणा के आधार पर एक वास्तविक एल्गोरिदम कोडिंग समस्या को हल करना चाहता है, तो कृपया इस समस्या को HackerRank पर देखें। उन्होंने अवधारणा को विस्तृत करने के लिए केवल प्रविष्टि सॉर्ट समस्या को भी संदर्भित किया है।
RBT

सैद्धांतिक समझ के लिए यहां एक नोट का भी उल्लेख किया जा सकता है।
RBT

जवाबों:


345

सरल शब्दों में, एक लूप इनवेरियंट कुछ विधेय (स्थिति) है जो लूप के प्रत्येक पुनरावृत्ति के लिए होता है। उदाहरण के लिए, आइए एक साधारण forलूप देखें जो इस तरह दिखता है:

int j = 9;
for(int i=0; i<10; i++)  
  j--;

इस उदाहरण में यह सच है (प्रत्येक पुनरावृत्ति के लिए) i + j == 9। एक कमजोर आक्रमणकारी जो सत्य भी है i >= 0 && i <= 10


29
यह एक उत्कृष्ट उदाहरण है। कई बार जब मैंने एक प्रशिक्षक को लूप इनवेरिएंट का वर्णन सुना है, तो यह केवल 'लूप की स्थिति' है, या कुछ इसी तरह की है। आपका उदाहरण दिखाता है कि आक्रमणकारी बहुत अधिक हो सकता है।
ब्रायन एस

77
मुझे यह एक अच्छा उदाहरण नहीं दिखता है क्योंकि लूप इनवेरिएंट कुछ हद तक लूप का लक्ष्य होना चाहिए ... सीएलआरएस इसका उपयोग सॉर्टिंग एल्गोरिथ्म की शुद्धता को बढ़ावा देने के लिए करता है। सम्मिलन प्रकार के लिए, लूप को दबाना i के साथ पुनरावृत्ति करता है, प्रत्येक लूप के अंत में, सरणी को i-th तत्व तक ऑर्डर किया जाता है।
क्लैश

5
हाँ, यह उदाहरण गलत नहीं है, लेकिन सिर्फ पर्याप्त नहीं है। मैं बैक अप @ क्लैश करता हूं, क्योंकि लूप इनवेरिएंट लक्ष्य को प्रस्तुत करना चाहिए, न कि केवल अपने लिए।
जैक

7
@ टोमस पेट्रिसक - जब लूप समाप्त हो जाता है, तो मैं = 10 और j = -1; इसलिए आपके द्वारा दिया गया कमजोर आक्रमणकारी उदाहरण सही नहीं हो सकता (?)
राजा

7
यद्यपि मैं ऊपर की टिप्पणियों से सहमत हूं, मैंने इस उत्तर को बदल दिया है क्योंकि ... लक्ष्य यहां परिभाषित नहीं है। किसी भी लक्ष्य को परिभाषित करें जो कि फिट बैठता है, और उदाहरण महान है।
फ्लाविस

119

मुझे यह बहुत सरल परिभाषा पसंद है: ( स्रोत )

एक लूप इनवेरिएंट एक शर्त है [प्रोग्राम चर के बीच] जो लूप के प्रत्येक पुनरावृत्ति के तुरंत पहले और तुरंत बाद जरूरी है। (ध्यान दें कि यह एक सत्य या मिथ्यात्व के बारे में कुछ भी नहीं कहता है कि एक पुनरावृत्ति के माध्यम से।)

अपने आप में, एक लूप अपरिवर्तनीय बहुत कुछ नहीं करता है। हालांकि, एक उपयुक्त अशुभ संकेत दिया, यह एक एल्गोरिथ्म की शुद्धता साबित करने में मदद करने के लिए इस्तेमाल किया जा सकता है। सीएलआरएस में सरल उदाहरण संभवतः छंटाई के साथ करना है। उदाहरण के लिए, अपने लूप को अपरिवर्तित करें, जैसे कि लूप की शुरुआत में, iइस सरणी की पहली प्रविष्टियां क्रमबद्ध हैं। यदि आप यह साबित कर सकते हैं कि यह वास्तव में एक लूप इनवेरिएंट है (अर्थात यह प्रत्येक लूप पुनरावृत्ति के पहले और बाद में है), तो आप इसका उपयोग सॉर्टिंग एल्गोरिथ्म की शुद्धता को साबित करने के लिए कर सकते हैं: लूप की समाप्ति पर, लूप इनवेरिएंट अभी भी संतुष्ट है , और काउंटर iसरणी की लंबाई है। इसलिए, पहली iप्रविष्टियों को क्रमबद्ध किया जाता है, जिसका अर्थ है कि संपूर्ण सरणी क्रमबद्ध है।

एक और भी सरल उदाहरण: लूप्स इनवेरिएंट्स, सुधार और प्रोग्राम व्युत्पत्ति

जिस तरह से मैं एक लूप अपरिवर्तनीय समझता हूं, वह कार्यक्रमों के बारे में व्यवस्थित, औपचारिक उपकरण के रूप में है। हम एक ऐसा बयान देते हैं जिसे हम सच साबित करने पर ध्यान केंद्रित करते हैं, और हम इसे लूप इनवेरिएंट कहते हैं। यह हमारे तर्क को व्यवस्थित करता है। जबकि हम बस कुछ एल्गोरिथ्म की शुद्धता के बारे में अनौपचारिक रूप से बहस कर सकते हैं, एक लूप इनवेरिएंट का उपयोग हमें बहुत सावधानी से सोचने के लिए मजबूर करता है और यह सुनिश्चित करता है कि हमारा तर्क एयरटाइट है।


10
यह ध्यान दिया जाना चाहिए कि "प्रत्येक पुनरावृत्ति के तुरंत बाद" में लूप समाप्त होने के बाद भी शामिल है - चाहे वह कैसे भी समाप्त हो।
रॉबर्ट एस। बार्न्स

इस उत्तर के लिए बहुत बहुत धन्यवाद! इससे सबसे बड़ा लेना यह है कि इस लूप को अपरिवर्तित करने का उद्देश्य एल्गोरिदम की शुद्धता को साबित करने में मदद करना है। अन्य उत्तर केवल इस बात पर ध्यान केंद्रित करते हैं कि लूप इनवेरिएंट क्या है!
नीकी

39

एक बात यह है कि बहुत से लोगों को तुरंत नहीं पता है जब छोरों और आक्रमणकारियों से निपटते हैं। वे लूप इनवेरिएंट और लूप सशर्त (लूप की समाप्ति को नियंत्रित करने वाली स्थिति) के बीच भ्रमित हो जाते हैं।

जैसा कि लोग बताते हैं, लूप इनवेरियन सही होना चाहिए

  1. लूप शुरू होने से पहले
  2. लूप के प्रत्येक पुनरावृत्ति से पहले
  3. लूप समाप्त होने के बाद

(हालांकि यह लूप के शरीर के दौरान अस्थायी रूप से गलत हो सकता है)। दूसरी ओर लूप की स्थिति लूप समाप्त होने के बाद झूठी होनी चाहिए, अन्यथा लूप कभी समाप्त नहीं होगा।

इस प्रकार लूप इनवेरिएंट और लूप सशर्त अलग-अलग स्थिति होनी चाहिए।

द्विआधारी खोज के लिए एक जटिल लूप इनवेरिएंट का एक अच्छा उदाहरण है।

bsearch(type A[], type a) {
start = 1, end = length(A)

    while ( start <= end ) {
        mid = floor(start + end / 2)

        if ( A[mid] == a ) return mid
        if ( A[mid] > a ) end = mid - 1
        if ( A[mid] < a ) start = mid + 1

    }
    return -1

}

तो लूप सशर्त बहुत सीधे आगे लगता है - जब शुरू> अंत लूप समाप्त होता है। लेकिन लूप सही क्यों है? पाश अपरिवर्तनीय क्या है जो यह साबित करता है कि यह शुद्धता है?

आक्रमणकारी तार्किक कथन है:

if ( A[mid] == a ) then ( start <= mid <= end )

यह कथन एक तार्किक आधार है - यह विशिष्ट लूप / एल्गोरिथम के संदर्भ में हमेशा सही होता है जिसे हम साबित करने की कोशिश कर रहे हैं । और यह समाप्त होने के बाद लूप की शुद्धता के बारे में उपयोगी जानकारी प्रदान करता है।

अगर हम वापस लौटते हैं क्योंकि हमने एरे में तत्व पाया है, तो कथन स्पष्ट रूप से सही है, यदि A[mid] == aतब aऐरे में है और midशुरू और अंत के बीच होना चाहिए। और अगर पाश समाप्त क्योंकि start > endतो कोई संख्या हो सकती है ऐसा है कि start <= mid और mid <= end और इसलिए हम जानते हैं कि बयान A[mid] == aझूठा होना चाहिए। हालाँकि, परिणामस्वरूप समग्र तार्किक कथन अभी भी शून्य अर्थ में सत्य है। (तर्क में कथन यदि (असत्य) है तो (कुछ) हमेशा सत्य है)

अब लूप सशर्त के बारे में मैंने क्या कहा जो जरूरी है कि लूप समाप्त होने पर गलत है? ऐसा लगता है कि जब तत्व सरणी में पाया जाता है तो लूप की स्थिति तब सही होती है जब लूप समाप्त हो जाता है !? यह वास्तव में नहीं है, क्योंकि निहित लूप सशर्त वास्तव में है, while ( A[mid] != a && start <= end )लेकिन हम वास्तविक परीक्षण को छोटा करते हैं क्योंकि पहला भाग निहित है। यह शर्त लूप के बाद स्पष्ट रूप से झूठी है कि लूप कैसे समाप्त होता है।


यह तर्क है कि लूप इनवेरिएंट के रूप में एक तार्किक कथन का उपयोग करना है, क्योंकि सभी तार्किक कथन हमेशा सही हो सकते हैं, चाहे वह कोई भी स्थिति हो।
अक्जेंट्री

इतना अजीब नहीं है कि मुझे सोचना चाहिए, क्योंकि इसमें कोई गारंटी नहीं है कि aयह मौजूद है A। अनौपचारिक रूप से यह होगा, "यदि कुंजी aसरणी में मौजूद है, तो यह बीच startऔर endसमावेशी होना चाहिए "। तब यह अनुसरण करता है कि यदि A[start..end]खाली है, तो वह a
स्केन्नी

33

पिछले उत्तरों ने एक लूप इनवेरिएंट को बहुत अच्छे तरीके से परिभाषित किया है।

इसके बाद सीएलआरएस के लेखकों ने इंसर्शन सॉर्ट की शुद्धता साबित करने के लिए लूप इनवेरिएंट का उपयोग किया ।

प्रविष्टि सॉर्ट एल्गोरिथ्म (जैसा कि पुस्तक में दिया गया है):

INSERTION-SORT(A)
    for j ← 2 to length[A]
        do key ← A[j]
        // Insert A[j] into the sorted sequence A[1..j-1].
        i ← j - 1
        while i > 0 and A[i] > key
            do A[i + 1] ← A[i]
            i ← i - 1
        A[i + 1] ← key

इस मामले में लूप इनवेरिएंट: उप-सरणी [1 से j-1] को हमेशा क्रमबद्ध किया जाता है।

अब हम इसे जांचते हैं और साबित करते हैं कि एल्गोरिथ्म सही है।

प्रारंभिककरण : पहले पुनरावृत्ति से पहले j = 2। इसलिए उप-सरणी [1: 1] परीक्षण किया जाने वाला सरणी है। जैसा कि इसमें केवल एक तत्व है इसलिए इसे क्रमबद्ध किया गया है। इस प्रकार अपरिवर्तनीय संतुष्ट है।

रखरखाव : यह प्रत्येक पुनरावृत्ति के बाद आसानी से जाँचकर्ता द्वारा सत्यापित किया जा सकता है। इस मामले में यह संतुष्ट है।

समाप्ति : यह वह चरण है जहां हम एल्गोरिथ्म की शुद्धता साबित करेंगे।

जब लूप समाप्त हो जाता है तो j = n + 1 का मान। फिर से पाश अपरिवर्तनीय संतुष्ट है। इसका अर्थ है कि उप-सरणी [1 से n] को क्रमबद्ध किया जाना चाहिए।

यही हम अपने एल्गोरिथ्म के साथ करना चाहते हैं। इस प्रकार हमारा एल्गोरिथ्म सही है।


1
सहमत ... समाप्ति का बयान यहाँ बहुत महत्वपूर्ण है।
गौरव आराध्या

18

सभी अच्छे उत्तरों के अलावा, मैं जेफ एडमंड्स द्वारा अवधारणा को बहुत अच्छी तरह से समझा सकता हूं कि कैसे एल्गोरिदम के बारे में सोचना है, से एक महान उदाहरण लगता है :

उदाहरण 1.2.1 "द फाइंड-मैक्स टू-फिंगर एल्गोरिथम"

1) विनिर्देशों: एक इनपुट उदाहरण में तत्वों की एक सूची L (1..n) होती है। आउटपुट में एक इंडेक्स i होता है, जिसमें L (i) का अधिकतम मूल्य होता है। यदि इसी मान के साथ कई प्रविष्टियाँ हैं, तो उनमें से किसी एक को लौटा दिया जाता है।

2) बेसिक स्टेप्स: आप टू-फिंगर मेथड पर निर्णय लेते हैं। आपकी दाहिनी उंगली नीचे की ओर जाती है।

3) प्रगति का माप: प्रगति का माप आपकी दाहिनी उंगली की सूची से कितनी दूर है।

4) लूप इनवेरिएंट : लूप इनवेरिएंट बताता है कि आपकी बायीं ऊँगली एक दायीं उँगली से अब तक हुई सबसे बड़ी प्रविष्टियों में से एक है।

5) मुख्य चरण: प्रत्येक पुनरावृत्ति, आप सूची में एक प्रविष्टि के नीचे अपनी दाहिनी उंगली ले जाते हैं। यदि आपकी दाहिनी उंगली अब एक ऐसी प्रविष्टि की ओर इशारा कर रही है जो बड़ी है तो बाईं उंगली का प्रवेश, तो अपनी बाईं उंगली को अपनी दाहिनी उंगली से ले जाएं।

6) प्रगति करें: आप प्रगति करते हैं क्योंकि आपकी दाहिनी उंगली एक प्रवेश करती है।

7) लूप इनवेरिएंट बनाए रखें: आप जानते हैं कि लूप इनवेरिएंट को निम्न प्रकार से बनाए रखा गया है। प्रत्येक चरण के लिए, नई बाईं उंगली तत्व मैक्स (पुरानी बाईं उंगली तत्व, नया तत्व) है। लूप इनवेरिएंट द्वारा, यह मैक्स (अधिकतम (छोटी सूची), नया तत्व) है। मैथ- मैटिक, यह मैक्स (लंबी सूची) है।

8) लूप इनवेरिएंट की स्थापना : आप शुरू में लूप इनवेरिएंट को बिंदु से स्थापित करते हैं- दोनों अंगुलियों को पहले तत्व पर।

9) बाहर निकलने की स्थिति: आप तब करते हैं जब आपकी दाहिनी उंगली ने सूची को पीछे छोड़ दिया है।

10) अंत: अंत में, हम जानते हैं कि समस्या हल हो गई है। एग्जिट कोंड- tion द्वारा, आपकी दाहिनी उंगली ने सभी प्रविष्टियों का सामना किया है। लूप इनवेरिएंट द्वारा, आपकी बायीं ऊँगली इनमें से अधिकतम पर इंगित करती है। इस प्रविष्टि को वापस करें।

11) समाप्ति और रनिंग टाइम: आवश्यक समय सूची की लंबाई के कुछ स्थिर समय है।

12) विशेष मामले: चेक करें कि क्या होता है जब एक ही मान के साथ कई प्रविष्टियाँ हों या जब n = 0 या n = 1 हो।

13) कोडिंग और कार्यान्वयन विवरण: ...

14) औपचारिक प्रमाण: एल्गोरिथ्म की शुद्धता उपरोक्त चरणों से होती है।


मुझे लगता है कि यह जवाब वास्तव में "एक अँगूठी के सहज ज्ञान युक्त" पर अपनी उंगली डालता है :)।
स्कैन

6

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


5

इस मामले में अपरिवर्तनीय का अर्थ है एक शर्त जो प्रत्येक लूप पुनरावृत्ति में एक निश्चित बिंदु पर सही होनी चाहिए।

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


4

अपरिवर्तनीय का अर्थ कभी भी परिवर्तन नहीं होता है

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


2

लूप इनवेरिएंट प्रॉपर्टी एक ऐसी स्थिति है जो लूप्स निष्पादन के हर चरण के लिए होती है (यानी लूप के लिए, जबकि लूप आदि)।

यह लूप इन्वारिएंट प्रूफ के लिए आवश्यक है, जहां कोई यह दिखाने में सक्षम है कि एक एल्गोरिथ्म सही ढंग से निष्पादित होता है यदि इसके निष्पादन के हर चरण में यह लूप इनवेरियेंट प्रॉपर्टी रखता है।

एल्गोरिथ्म सही होने के लिए, लूप इनवेरिएंट को अपने पास रखना चाहिए:

प्रारंभ (शुरुआत)

रखरखाव (प्रत्येक चरण के बाद)

समाप्ति (जब यह समाप्त हो जाए)

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

इस प्रकार, लूप इनवेरिएंट प्रॉपर्टी का अर्थ है कि लिए गए पथ में कम से कम वजन है। पर शुरुआत हम नहीं जोड़े हैं किनारों, तो यह संपत्ति सच है (यह इस मामले में, झूठी नहीं है)। पर हर कदम , हम सबसे कम वजन बढ़त (लालची कदम) का पालन करें, तो फिर हम सबसे कम वजन पथ ले जा रहे हैं। पर अंत में, हम तो हमारे संपत्ति भी सच है, सबसे कम भारित पथ मिल गया है।

यदि एक एल्गोरिथ्म ऐसा नहीं करता है, तो हम यह साबित कर सकते हैं कि यह इष्टतम नहीं है।


1

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

... // लूप इनवेरिएंट यहाँ सही होना चाहिए
(टेस्ट कॉन्स्टिट्यूशन) {
// लूप के ऊपर
...
// लूप के नीचे
// लूप इनवेरेंट यहाँ सही होना चाहिए
}
// टर्मिनेशन + लूप इनवेरिएंट = लक्ष्य
...
लूप के ऊपर और नीचे के बीच, हेडवे संभवतः लूप के लक्ष्य तक पहुंचने के लिए बनाया जा रहा है। यह अतिक्रमणकर्ता को परेशान कर सकता है। लूप इनवेरिएंट्स का मुद्दा यह वादा है कि प्रत्येक बार लूप बॉडी को दोहराने से पहले इनवेरिएंट को बहाल किया जाएगा। इसके दो फायदे हैं:

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

लूप इनवेरिएंट बनाया जाना चाहिए ताकि जब समाप्ति की स्थिति प्राप्त हो, और अयोग्य सच हो, तो लक्ष्य पूरा हो गया है:

invariant + समाप्ति => लक्ष्य
यह invariants बनाने के लिए अभ्यास लेता है जो सरल हैं और संबंधित हैं जो समाप्ति को छोड़कर लक्ष्य प्राप्ति के सभी पर कब्जा करते हैं। लूप आक्रमणकारियों को व्यक्त करने के लिए गणितीय प्रतीकों का उपयोग करना सबसे अच्छा है, लेकिन जब यह अधिक जटिल परिस्थितियों की ओर जाता है, तो हम स्पष्ट गद्य और सामान्य ज्ञान पर भरोसा करते हैं।


1

क्षमा करें, मेरे पास टिप्पणी की अनुमति नहीं है।

@ टॉमस पेट्रिसक जैसा कि आपने बताया

एक कमजोर आक्रमणकारी जो सच भी है कि i> = 0 && i <10 (क्योंकि यह निरंतरता की स्थिति है!)

यह कैसे एक पाश अपरिवर्तनीय है?

मुझे उम्मीद है कि मैं गलत नहीं हूं, जहां तक ​​मैं समझता हूं [1] , लूप अपरिवर्तनीय लूप की शुरुआत में सही होगा (प्रारंभ), यह प्रत्येक पुनरावृत्ति (रखरखाव) से पहले और बाद में सच होगा और यह बाद में भी सच होगा लूप की समाप्ति (समाप्ति) । लेकिन अंतिम पुनरावृत्ति के बाद मैं 10. हो जाता है, इसलिए, i> = 0 && i <10 गलत हो जाता है और लूप को समाप्त कर देता है। यह लूप इनवेरिएंट की तीसरी संपत्ति (समाप्ति) का उल्लंघन करता है।

[१] http://www.win.tue.nl/~kbuchin/teaching/JBP030/notebooks/loop-invariants.html


मेरा अनुमान है कि यह सच है क्योंकि लूप वास्तव में उन परिस्थितियों में निष्पादित नहीं होता है।
मुइइउ

0

पाश अपरिवर्तनीय एक गणितीय सूत्र है जैसे कि (x=y+1)। उस उदाहरण में, xऔर yएक लूप में दो चर का प्रतिनिधित्व करते हैं। कोड के निष्पादन के दौरान वे चर के बदलते व्यवहार को देखते हुए, यह करने के लिए सभी संभव परीक्षण करने के लिए लगभग असंभव है xऔर yमूल्यों और देखें कि क्या वे किसी भी बग का उत्पादन। कहते हैं xकि एक पूर्णांक है। इंटेगर मेमोरी में 32 बिट स्पेस रख सकता है। उस नंबर से अधिक है, बफर अतिप्रवाह होता है। इसलिए हमें यह सुनिश्चित करने की आवश्यकता है कि कोड के निष्पादन के दौरान, यह कभी भी उस स्थान से अधिक न हो। उसके लिए, हमें एक सामान्य सूत्र को समझने की आवश्यकता है जो चर के बीच के संबंध को दर्शाता है। आखिरकार, हम सिर्फ कार्यक्रम के व्यवहार को समझने की कोशिश करते हैं।


0

सरल शब्दों में, यह एक लूप स्थिति है जो हर लूप पुनरावृत्ति में सच है:

for(int i=0; i<10; i++)
{ }

इसमें हम कह सकते हैं कि मैं राज्य है i<10 and i>=0



-1

रैखिक खोज में (पुस्तक में दिए गए अभ्यास के अनुसार), हमें दिए गए सरणी में मान V खोजने की आवश्यकता है।

सरणी को 0 <= k <लंबाई से स्कैन करना और प्रत्येक तत्व की तुलना करना सरल है। यदि V पाया जाता है, या यदि स्कैनिंग सरणी की लंबाई तक पहुंचता है, तो बस लूप को समाप्त करें।

उपरोक्त समस्या में मेरी समझ के अनुसार-

लूप आक्रमणकारियों (प्रारंभिक): V k - 1 पुनरावृत्ति में नहीं पाया जाता है। बहुत पहले पुनरावृत्ति, यह -1 होगा इसलिए हम कह सकते हैं कि वी -1 स्थिति में नहीं मिला है

अनुरक्षण: अगले पुनरावृत्ति में, V k-1 में नहीं पाया गया है

टर्मिनेशन: यदि वी को k स्थिति में या k सरणी की लंबाई तक पहुँचता है, तो लूप को समाप्त करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.