u + 1 ≠ v u = [ця цікава річ] v = [ця цікава річ]u+1=v - це справді пост-умова циклу while (чому ви вважаєте, що "явно" це не так?). Це завжди у випадку циклу, який не містить a break
: коли цикл закінчується, це може бути лише тому, що умова циклу (тут, ) хибна. Це не єдине, що буде істинним, коли цикл закривається тут (цей алгоритм насправді обчислює щось цікаве, як ви бачили у своєму класі, тому і теж є умовами), але це найбільш очевидно.u+1≠vu=[this interesting thing]v=[this interesting thing]
Тепер, щоб знайти інші цікаві властивості, загального рецепту немає. Насправді, існує якийсь офіційний сенс, в якому немає загального рецепту, щоб знайти петльові інваріанти. Найкраще, що ви можете зробити, це застосувати деякі прийоми, які працюють лише в деяких випадках, або взагалі ловляться на риболовлю для цікавих спостережень (що працює краще і краще, коли ви отримуєте більше досвіду).
Якщо ви запустите цикл для декількох ітерацій з деяким значенням , ви побачите, що на кожній ітерації:n
- або підскакує до ;( u + v ) / 2u(u+v)/2
- або стрибає вниз до .v(u+v)/2
Зокрема, починається менше, ніж , і ніколи його не обійде. Крім того, починається додатним і збільшується, тоді як починається від і зменшується. Тож є інваріантом у всій програмі.uvuvn+10≤u≤v≤n+1
Одна річ , яка не так очевидно , є чи будь- НЕ може бути дорівнює . Це важливо: якщо і коли-небудь стануть рівними, у нас буде і цикл буде продовжуватися. Отже, вам потрібно довести, що і ніколи не стають рівними, щоб довести, що алгоритм правильний (тобто не циклічний назавжди). Після того, як ця потреба виявлена, легко довести (я залишаю це як вправу), що - це інваріант циклу (майте на увазі, що і - цілі числа, тому це еквівалентно ).uvuvx=u=vuvu<vuvu+1≤v
Оскільки в кінці програми, то поставлену вам умову можна також записати (частина є тривіальною). Причина, коли ми хочемо, щоб така умова була такою, включаючи , полягає в тому, що ми хочемо пов'язати результат програми з входом . Чому саме цей стан? Ми шукаємо щось максимально точне, і ми дивимось, де з'являється всередині циклу:v=u+1u2≤n<v20≤u2nnn
- маємо ;u≤x≤v
- коли , ми вибираємо наступне щоб бути , так що (і не змінюється);u x u 2 ≤ n vx2≤nuxu2≤nv
- коли , ми вибираємо наступне щоб бути , так що (і не змінюється).v x n < v 2 ux2>nvxn<v2u
Ця дихотомія натякає, що, можливо, весь час. Іншими словами, ми підозрюємо, що це цикл інваріант. Підтвердження цього залишається читачем як вправа (не забудьте перевірити, чи властивість спочатку відповідає дійсності).u2≤n<v2
І тепер, коли ми все це зробили, ми бачимо, що і : - квадратний корінь округлений до найближчого цілого числа.( u + 1 ) 2 > n u nu2≤n(u+1)2>nun