ค่าคงที่แบบวนซ้ำคืออะไร?


268

ฉันกำลังอ่าน "ความรู้เบื้องต้นเกี่ยวกับอัลกอริทึม" โดย CLRS ในบทที่ 2 ผู้เขียนพูดถึง "loop invariants" ค่าคงที่แบบวนซ้ำคืออะไร?


4
ดูเหมือนว่าจะอธิบายได้ค่อนข้างดี: cs.miami.edu/~burt/learning/Math120.1/Notes/LoopInvar.html
Tom Gullen

ตรวจสอบลิงค์นี้programmers.stackexchange.com/questions/183815/…
Adil Abbasi

ในกรณีที่ใครบางคนต้องการที่จะแก้ปัญหาการเข้ารหัสอัลกอริทึมจริงตามแนวคิดของการวนรอบคงที่โปรดอ้างอิงปัญหานี้บน HackerRank พวกเขายังอ้างถึงปัญหาการเรียงลำดับการแทรกเพื่อให้รายละเอียดแนวคิด
RBT

ท่านสามารถอ้างอิงบันทึกที่นี่เพื่อความเข้าใจในทางทฤษฎี
RBT

คำตอบ:


345

ในคำง่าย ๆ , ค่าคงที่ของลูปคือเพรดิเคต (เงื่อนไข) บางอย่างที่เก็บไว้สำหรับการวนซ้ำทุกครั้งของลูป ตัวอย่างเช่นลองดูforลูปแบบง่าย ๆที่มีลักษณะดังนี้:

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

ในตัวอย่างนี้มันเป็นความจริง (สำหรับทุกซ้ำ) i + j == 9ที่ i >= 0 && i <= 10คงอ่อนแอที่ยังเป็นความจริงก็คือว่า


29
นี่เป็นตัวอย่างที่ยอดเยี่ยม หลายครั้งที่ฉันได้ยินผู้สอนอธิบายถึงค่าคงที่ของลูปมันเป็นเพียง 'สภาพลูป' หรือสิ่งที่คล้ายกัน ตัวอย่างของคุณแสดงให้เห็นว่าค่าคงที่สามารถเพิ่มได้อีกมาก
Brian S

77
ฉันไม่เห็นสิ่งนี้เป็นตัวอย่างที่ดีเพราะค่าคงที่แบบวนซ้ำควรเป็นเป้าหมายของลูป ... CLRS ใช้เพื่อประมวลความถูกต้องของอัลกอริทึมการเรียงลำดับ สำหรับการเรียงลำดับการแทรกสมมติว่าลูปกำลังวนซ้ำกับ i ในตอนท้ายของแต่ละลูปอาร์เรย์จะถูกเรียงลำดับจนกว่าองค์ประกอบ i-th
Clash

5
ใช่ตัวอย่างนี้ไม่ผิด แต่ก็ไม่เพียงพอ ฉันสำรอง @Clash up ไว้เนื่องจาก loop invariant ควรแสดงเป้าหมายไม่ใช่เฉพาะสำหรับตัวเองเท่านั้น
แจ็ค

7
@Tomas Petricek - เมื่อลูปยุติ i = 10 และ j = -1; ตัวอย่างที่คงที่ที่อ่อนแอกว่าที่คุณให้อาจไม่ถูกต้อง (?)
ราชา

7
แม้ว่าฉันจะเห็นด้วยกับความคิดเห็นข้างต้น แต่ฉันได้ตอบคำถามนี้เพราะ ... ไม่ได้กำหนดเป้าหมายที่นี่ กำหนดเป้าหมายที่เหมาะสมและตัวอย่างนั้นยอดเยี่ยม
Flavius

119

ฉันชอบคำนิยามที่เรียบง่ายมาก: (ที่มา )

loop invariant เป็นเงื่อนไข [ระหว่างตัวแปรโปรแกรม] ที่จำเป็นต้องเป็นจริงในทันทีก่อนและทันทีหลังจากการวนซ้ำของลูปแต่ละครั้ง (โปรดทราบว่าสิ่งนี้ไม่ได้กล่าวถึงความจริงหรือความเท็จของมันผ่านการทำซ้ำ)

โดยตัวมันเองค่าคงที่แบบวนรอบไม่ได้ทำอะไรมาก อย่างไรก็ตามด้วยค่าคงที่ที่เหมาะสมสามารถใช้เพื่อพิสูจน์ความถูกต้องของอัลกอริทึม ตัวอย่างง่าย ๆ ใน CLRS อาจเกี่ยวข้องกับการเรียงลำดับ ตัวอย่างเช่นปล่อยให้ลูปคงที่ของคุณเป็นอย่างที่ตอนต้นของลูปiรายการแรกของอาร์เรย์นี้จะถูกเรียงลำดับ หากคุณสามารถพิสูจน์ได้ว่านี่เป็นลูปคงที่แน่นอน (นั่นคือมันจะเก็บไว้ก่อนและหลังการวนซ้ำทุกรอบ) คุณสามารถใช้สิ่งนี้เพื่อพิสูจน์ความถูกต้องของอัลกอริทึมการเรียงลำดับ: ที่การสิ้นสุดของลูป และตัวนับiคือความยาวของอาร์เรย์ ดังนั้นiรายการแรกจะถูกจัดเรียงหมายความว่าอาร์เรย์ทั้งหมดจะถูกจัดเรียง

ตัวอย่างได้ง่าย: ลูป Invariants, ความถูกต้องและโปรแกรมที่มา

วิธีที่ฉันเข้าใจค่าคงที่แบบวนรอบเป็นเครื่องมือที่เป็นระบบและเป็นทางการเพื่อให้เหตุผลเกี่ยวกับโปรแกรม เราสร้างคำแถลงเดียวที่เรามุ่งเน้นการพิสูจน์ความจริงและเราเรียกมันว่าวนรอบไม่แปรเปลี่ยน สิ่งนี้จัดตรรกะของเรา ในขณะที่เราสามารถโต้แย้งอย่างไม่เป็นทางการเกี่ยวกับความถูกต้องของอัลกอริทึมได้ แต่การใช้ loop invariant ทำให้เราต้องคิดอย่างรอบคอบ


10
ควรชี้ให้เห็นว่า "ทันทีหลังจากการทำซ้ำแต่ละครั้ง" รวมถึงหลังจากการวนซ้ำสิ้นสุดลง - ไม่ว่ามันจะถูกยกเลิก
Robert S. Barnes

ขอบคุณมากสำหรับคำตอบนี้! สิ่งที่ยิ่งใหญ่ที่สุดจากจุดนี้คือจุดประสงค์ของการมีลูปคงที่นี้เพื่อช่วยพิสูจน์ความถูกต้องของอัลกอริทึม คำตอบอื่น ๆ เพียงมุ่งเน้นไปที่สิ่งที่เป็นค่าคงที่วนรอบ!
Neekey

39

มีสิ่งหนึ่งที่หลายคนไม่เข้าใจทันทีเมื่อจัดการกับลูปและค่าคงที่ พวกเขาสับสนระหว่าง loop invariant และ loop conditional (เงื่อนไขที่ควบคุมการสิ้นสุดของ loop)

เมื่อผู้คนชี้ให้เห็นค่าคงที่ของวงจะต้องเป็นจริง

  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 )แต่เราทำการทดสอบให้สั้นลงเนื่องจากส่วนแรกมีการบอกเป็นนัย เงื่อนไขนี้เป็นเท็จอย่างชัดเจนหลังจากลูปไม่ว่าลูปจะสิ้นสุดลงอย่างไร


เป็นที่น่าสังเกตว่าการใช้คำสั่งแบบลอจิคัลเป็นแบบวนรอบไม่แปรเปลี่ยนเนื่องจากเป็นคำสั่งแบบลอจิคัลทั้งหมดสามารถเป็นจริงเสมอไม่ว่าเงื่อนไขใด
acgtyrant

ไม่แปลกดังนั้นฉันควรจะคิดว่าตั้งแต่มีการรับประกันว่าไม่มีอยู่ในa Aอย่างไม่เป็นทางการก็จะเป็น "ถ้าคีย์aมีอยู่ในอาเรย์นั้นจะต้องเกิดขึ้นระหว่างstartและendรวม" จากนั้นตามด้วยถ้าA[start..end]ว่างเปล่าaจะไม่มีอยู่ใน A.
scanny

33

คำตอบก่อนหน้าได้กำหนดค่าคงที่แบบวนซ้ำในวิธีที่ดีมาก

ต่อไปนี้เป็นวิธีที่ผู้เขียน CLRS ใช้ลูปค่าคงที่เพื่อพิสูจน์ความถูกต้องของการจัดเรียงการแทรก

อัลกอริธึมการจัดเรียงแทรก (ตามที่ระบุในหนังสือ):

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

Loop Invariant ในกรณีนี้: Sub-array [1 ถึง j-1] จะถูกจัดเรียงเสมอ

ตอนนี้ให้เราตรวจสอบและพิสูจน์ว่าอัลกอริทึมถูกต้อง

การเริ่มต้น : ก่อนการทำซ้ำครั้งแรก j = 2 ดังนั้น sub-array [1: 1] จึงเป็นอาร์เรย์ที่จะทำการทดสอบ เนื่องจากมันมีองค์ประกอบเดียวเท่านั้นดังนั้นมันจึงถูกจัดเรียง ดังนั้นค่าคงที่จึงเป็นที่พอใจ

การบำรุงรักษา : สิ่งนี้สามารถตรวจสอบได้อย่างง่ายดายโดยตรวจสอบค่าคงที่หลังการวนซ้ำแต่ละครั้ง ในกรณีนี้มันเป็นที่น่าพอใจ

การสิ้นสุด : นี่คือขั้นตอนที่เราจะพิสูจน์ความถูกต้องของอัลกอริทึม

เมื่อลูปสิ้นสุดลงดังนั้นค่าของ j = n + 1 วนซ้ำไม่เปลี่ยนแปลงก็พอใจ ซึ่งหมายความว่าควรเรียงลำดับย่อย [1 ถึง n]

นี่คือสิ่งที่เราต้องการจะทำกับอัลกอริทึมของเรา ดังนั้นอัลกอริทึมของเราถูกต้อง


1
เห็นด้วย ... คำชี้แจงการยกเลิกมีความสำคัญมากที่นี่
Gaurav Aradhye

18

นอกเหนือจากคำตอบที่ดีทั้งหมดฉันเดาว่าเป็นตัวอย่างที่ดีจาก วิธีคิดเกี่ยวกับอัลกอริทึมโดย Jeff Edmondsสามารถอธิบายแนวคิดได้เป็นอย่างดี:

ตัวอย่าง 1.2.1 "อัลกอริธึมสองนิ้ว Find-Max

1) ข้อมูลจำเพาะ: อินสแตนซ์อินพุตประกอบด้วยรายการ L (1..n) ขององค์ประกอบ เอาต์พุตประกอบด้วยดัชนี i ที่ L (i) มีค่าสูงสุด หากมีหลายรายการที่มีค่าเดียวกันนี้รายการใดรายการหนึ่งจะถูกส่งคืน

2) ขั้นตอนพื้นฐาน: คุณเป็นผู้ตัดสินใจเกี่ยวกับวิธีการสองนิ้ว นิ้วขวาของคุณวิ่งลงมาจากรายการ

3) การวัดความคืบหน้า: การวัดความก้าวหน้าคือระยะทางที่คุณใช้ไปทางขวาของรายการ

4) The Loop Invariant:วง Invariant ระบุว่านิ้วซ้ายของคุณชี้ไปที่หนึ่งในรายการที่ใหญ่ที่สุดที่พบโดยนิ้วขวาของคุณ

5) ขั้นตอนหลัก: การวนซ้ำแต่ละครั้งคุณเลื่อนนิ้วขวาของคุณลงหนึ่งรายการในรายการ หากนิ้วขวาของคุณชี้ไปที่รายการที่มีขนาดใหญ่กว่ารายการของนิ้วซ้ายให้เลื่อนนิ้วซ้ายไปอยู่ด้วยนิ้วขวาของคุณ

6) ทำให้ความคืบหน้า: คุณทำให้ความคืบหน้าเพราะนิ้วขวาของคุณย้ายหนึ่งรายการ

7) รักษาค่าคงที่แบบวนรอบ:คุณรู้ว่าค่าคงที่แบบวนซ้ำได้รับการปรับปรุงดังต่อไปนี้ สำหรับแต่ละขั้นตอนองค์ประกอบนิ้วซ้ายใหม่คือ Max (องค์ประกอบนิ้วซ้ายเก่าองค์ประกอบใหม่) โดยค่าคงที่แบบวนซ้ำนี่คือ Max (Max (รายการที่สั้นกว่า) องค์ประกอบใหม่) ในทางคณิตศาสตร์นี่คือ Max (รายการที่ยาวกว่า)

8) การสร้าง Loop Invariant:คุณเริ่มต้นการวนลูป invariant โดยเริ่มต้นด้วยการใช้นิ้วทั้งสองไปที่องค์ประกอบแรก

9) เงื่อนไขการออก: คุณจะทำเมื่อนิ้วขวาของคุณเสร็จสิ้นการสำรวจรายการ

10) การสิ้นสุด: ในตอนท้ายเรารู้ว่าปัญหาได้รับการแก้ไขดังนี้ เมื่อออกจากระบบนิ้วขวาของคุณพบรายการทั้งหมด นิ้วชี้ซ้ายของคุณชี้ไปที่ค่าสูงสุดของค่าเหล่านี้ ส่งคืนรายการนี้

11) เวลาสิ้นสุดและเวลาที่ใช้งาน: เวลาที่ใช้คือค่าคงที่คูณความยาวของรายการ

12) กรณีพิเศษ: ตรวจสอบสิ่งที่เกิดขึ้นเมื่อมีหลายรายการที่มีค่าเท่ากันหรือเมื่อ n = 0 หรือ n = 1

13) การเข้ารหัสและรายละเอียดการใช้งาน: ...

14) การพิสูจน์อย่างเป็นทางการ: ความถูกต้องของอัลกอริทึมดังต่อไปนี้จากขั้นตอนข้างต้น


ฉันคิดว่าคำตอบนี้จริง ๆ "วางนิ้วของมัน" ในส่วนสำคัญของการเปลี่ยนแปลง :)
scanny

6

ควรสังเกตว่า Loop Invariant สามารถช่วยในการออกแบบอัลกอริธึมแบบวนซ้ำเมื่อพิจารณาการยืนยันที่แสดงความสัมพันธ์ที่สำคัญระหว่างตัวแปรที่ต้องเป็นจริงเมื่อเริ่มการวนซ้ำทุกครั้งและเมื่อการวนซ้ำสิ้นสุดลง หากเป็นเช่นนี้การคำนวณก็อยู่บนเส้นทางสู่ความมีประสิทธิผล หากเป็นเท็จแสดงว่าอัลกอริทึมล้มเหลว


5

ค่าคงที่ในกรณีนี้หมายถึงเงื่อนไขที่ต้องเป็นจริง ณ จุดหนึ่งในการวนซ้ำทุกครั้ง

ในการเขียนโปรแกรมสัญญาคงที่เป็นเงื่อนไขที่จะต้องเป็นจริง (โดยสัญญา) ก่อนและหลังวิธีการใด ๆ ที่สาธารณะจะเรียกว่า


4

ความหมายของค่าคงที่ไม่เปลี่ยนแปลง

นี่คือค่าคงที่ของวงซึ่งหมายความว่า "การเปลี่ยนแปลงที่เกิดขึ้นกับตัวแปรในลูป (การเพิ่มขึ้นหรือลดลง) ไม่ได้เป็นการเปลี่ยนแปลงสภาพของลูปนั่นคือเงื่อนไขเป็นที่น่าพอใจ" ดังนั้นแนวคิดของค่าคงที่ลูป


2

คุณสมบัติ Loop Invariant เป็นเงื่อนไขที่เก็บไว้สำหรับการดำเนินการลูปทุกขั้นตอน (เช่นสำหรับลูปในขณะที่ลูปเป็นต้น)

นี่เป็นสิ่งสำคัญสำหรับการพิสูจน์ค่าคงที่ของวงวนที่หนึ่งสามารถแสดงให้เห็นว่าอัลกอริทึมดำเนินการอย่างถูกต้องหากในทุกขั้นตอนของการดำเนินการคุณสมบัติลูปนี้จะไม่เปลี่ยนแปลง

เพื่อให้อัลกอริทึมที่ถูกต้องนั้น Loop Invariant ต้องถือที่

การเริ่มต้น (จุดเริ่มต้น)

การบำรุงรักษา (แต่ละขั้นตอนหลังจาก)

การเลิกจ้าง (เมื่อเสร็จสิ้น)

สิ่งนี้ใช้เพื่อประเมินสิ่งต่างๆมากมาย แต่ตัวอย่างที่ดีที่สุดคืออัลกอริธึมโลภสำหรับการสำรวจกราฟด้วยน้ำหนัก สำหรับอัลกอริทึมโลภที่จะให้ทางออกที่ดีที่สุด (เส้นทางข้ามกราฟ) นั้นจะต้องเชื่อมต่อโหนดทั้งหมดในเส้นทางน้ำหนักต่ำสุดเท่าที่จะทำได้

ดังนั้นคุณสมบัติของลูปคงที่คือเส้นทางที่นำมามีน้ำหนักน้อยที่สุด ในตอนแรกเรายังไม่ได้เพิ่มขอบดังนั้นคุณสมบัตินี้เป็นจริง (ไม่ใช่ในกรณีนี้) ในแต่ละขั้นตอนเราทำตามขอบน้ำหนักต่ำสุด (ขั้นตอนโลภ) ดังนั้นอีกครั้งเราจึงใช้เส้นทางน้ำหนักต่ำสุด ในตอนท้ายเราพบเส้นทางที่มีน้ำหนักต่ำที่สุดดังนั้นทรัพย์สินของเราก็เป็นจริงเช่นกัน

หากอัลกอริทึมไม่ทำเช่นนี้เราสามารถพิสูจน์ได้ว่ามันไม่เหมาะสม


1

เป็นการยากที่จะติดตามว่าเกิดอะไรขึ้นกับลูป ลูปที่ไม่ยุติหรือยุติลงโดยไม่ได้รับพฤติกรรมตามเป้าหมายเป็นปัญหาที่พบบ่อยในการเขียนโปรแกรมคอมพิวเตอร์ วนค่าคงที่ช่วย loop invariant เป็นคำสั่งอย่างเป็นทางการเกี่ยวกับความสัมพันธ์ระหว่างตัวแปรในโปรแกรมของคุณซึ่งถือเป็นจริงก่อนที่ loop จะถูกเรียกใช้ (สร้าง invariant) และเป็นจริงอีกครั้งที่ด้านล่างของ loop แต่ละครั้งผ่าน loop (การบำรุงรักษา invariant ) นี่คือรูปแบบทั่วไปของการใช้ Loop Invariants ในรหัสของคุณ:

... // the Loop Invariant ต้องเป็นจริงที่นี่
ในขณะที่ (TEST CONDITION) {
// ด้านบนของลูป
...
// ด้านล่างของลูป
// // Loop Invariant ต้องเป็นจริงที่นี่
}
// การสิ้นสุด + Loop Invariant = เป้าหมาย
...
ระหว่างส่วนบนและด้านล่างของลูปความคืบหน้าจะเกิดขึ้นเมื่อไปถึงเป้าหมายของลูป สิ่งนี้อาจรบกวน (ทำให้เป็นเท็จ) ค่าคงที่ Point of Loop Invariants คือคำสัญญาที่ว่า invariant จะถูกกู้คืนก่อนที่จะวนซ้ำลูปในแต่ละครั้ง มีข้อดีสองข้อดังนี้:

งานจะไม่ถูกส่งต่อไปยังรหัสผ่านถัดไปด้วยวิธีการที่ซับซ้อนและขึ้นอยู่กับข้อมูล แต่ละคนเดินผ่านวงในอิสระของคนอื่น ๆ ด้วยค่าคงที่ให้บริการที่จะผูกผ่านกันเป็นทั้งการทำงาน การให้เหตุผลว่าการวนซ้ำของคุณลดลงไปตามการให้เหตุผลว่าค่าคงที่แบบวนซ้ำจะถูกกู้คืนด้วยการผ่านแต่ละรอบ สิ่งนี้จะทำให้พฤติกรรมโดยรวมที่ซับซ้อนของลูปเป็นขั้นตอนง่าย ๆ เล็ก ๆ ซึ่งสามารถพิจารณาแยกกันได้ เงื่อนไขการทดสอบของลูปไม่ได้เป็นส่วนหนึ่งของค่าคงที่ มันเป็นสิ่งที่ทำให้วงจบ คุณพิจารณาสองสิ่งแยกต่างหาก: ทำไมลูปจึงควรยุติและทำไมลูปถึงเป้าหมายของมันเมื่อมันสิ้นสุด การวนซ้ำจะสิ้นสุดลงหากแต่ละครั้งที่ผ่านการวนซ้ำที่คุณเคลื่อนที่เข้าใกล้เพื่อให้เป็นไปตามเงื่อนไขการเลิกจ้าง มันง่ายที่จะรับประกันสิ่งนี้เช่น: เหยียบตัวแปรตัวนับทีละตัวจนกว่าจะถึงขีด จำกัด สูงสุดคงที่ บางครั้งการใช้เหตุผลในการเลิกจ้างนั้นยากกว่า

ลูปค่าคงที่ควรถูกสร้างขึ้นเพื่อที่ว่าเมื่อเงื่อนไขของการสิ้นสุดนั้นบรรลุและค่าคงที่นั้นเป็นจริงดังนั้นถึงเป้าหมายแล้ว:

+ ค่าคงที่การสิ้นสุด => เป้าหมาย
จะใช้วิธีการในการสร้างค่าคงที่ซึ่งเรียบง่ายและเกี่ยวข้องซึ่งจับภาพการบรรลุเป้าหมายทั้งหมดยกเว้นการยกเลิก เป็นการดีที่สุดที่จะใช้สัญลักษณ์ทางคณิตศาสตร์เพื่อแสดงค่าคงที่ของวง แต่เมื่อสิ่งนี้นำไปสู่สถานการณ์ที่ซับซ้อนเกินไปเราจะต้องใช้งานประพันธ์ที่ชัดเจนและสามัญสำนึกที่ชัดเจน


1

ขออภัยฉันไม่ได้รับอนุญาตให้แสดงความคิดเห็น

@Tomas Petricek ตามที่คุณพูดถึง

ค่าคงที่ที่อ่อนกว่าที่เป็นจริงก็คือ i> = 0 && i <10 (เพราะนี่คือเงื่อนไขต่อเนื่อง!) "

มันเป็นค่าคงที่อย่างไร

ฉันหวังว่าฉันจะไม่ผิดเท่าที่ฉันเข้าใจ[1] , ค่าคงที่ของลูปจะเป็นจริงในตอนต้นของลูป (การเริ่มต้น) มันจะเป็นจริงก่อนและหลังการทำซ้ำแต่ละครั้ง (การบำรุงรักษา) และมันจะเป็นจริงด้วยเช่นกัน การสิ้นสุดของวง (สิ้นสุด) แต่หลังจากการทำซ้ำครั้งล่าสุดฉันกลายเป็น 10 ดังนั้นเงื่อนไข i> = 0 && i <10 กลายเป็นเท็จและยุติการวนซ้ำ มันเป็นการละเมิดคุณสมบัติที่สาม (การเลิกจ้าง) ของลูปค่าคงที่

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


ฉันเดาว่านี่เป็นเรื่องจริงเพราะลูปไม่ได้ทำงานภายใต้เงื่อนไขเหล่านั้น
muiiu

0

(x=y+1)ห่วงคงเป็นสูตรทางคณิตศาสตร์เช่น ในตัวอย่างนั้นxและyแสดงถึงสองตัวแปรในวง เมื่อพิจารณาถึงพฤติกรรมที่เปลี่ยนแปลงของตัวแปรเหล่านั้นตลอดการดำเนินการของรหัสที่มันเป็นไปไม่ได้เกือบที่จะทดสอบเป็นไปได้ทั้งหมดไปxและyค่านิยมและดูว่าพวกเขาผลิตข้อผิดพลาดใด ให้บอกว่าxเป็นจำนวนเต็ม จำนวนเต็มสามารถเก็บพื้นที่ 32 บิตในหน่วยความจำ หากจำนวนนั้นเกินจะเกิดการบัฟเฟอร์ล้น ดังนั้นเราต้องแน่ใจว่าตลอดการใช้งานโค้ดมันจะไม่เกินพื้นที่นั้น สำหรับสิ่งนั้นเราต้องเข้าใจสูตรทั่วไปที่แสดงความสัมพันธ์ระหว่างตัวแปร ท้ายที่สุดเราแค่พยายามทำความเข้าใจพฤติกรรมของโปรแกรม


0

กล่าวง่ายๆคือเป็นเงื่อนไข LOOP ที่เป็นจริงในการวนซ้ำทุกครั้ง:

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

ในที่นี้เราสามารถพูดได้ว่าสถานะของฉันคือ i<10 and i>=0



-1

ในการค้นหาเชิงเส้น (ตามแบบฝึกหัดที่ให้ไว้ในหนังสือ) เราจำเป็นต้องค้นหาค่า V ในอาร์เรย์ที่กำหนด

มันง่ายเหมือนการสแกนอาร์เรย์จาก 0 <= k <ความยาวและเปรียบเทียบแต่ละองค์ประกอบ หากพบ V หรือหากการสแกนถึงความยาวของอาเรย์ให้ยุติการวนซ้ำ

ตามความเข้าใจของฉันในปัญหาข้างต้น -

วนรอบไม่คงที่ (การกำหนดค่าเริ่มต้น): ไม่พบ V ในการวนซ้ำ k - 1 การทำซ้ำครั้งแรกนี่จะเป็น -1 ดังนั้นเราจึงสามารถบอกว่า V ไม่พบที่ตำแหน่ง -1

การบำรุงรักษา: ในการทำซ้ำครั้งถัดไป V ไม่พบใน k-1 ถือเป็นจริง

ยุติ: ถ้า V พบในตำแหน่ง k หรือ k ถึงความยาวของอาร์เรย์ให้ยุติการวนซ้ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.