Як отриманий інваріант циклу в алгоритмі знаходження кореня, пов'язаного з квадратним коренем?


10

Спочатку на math.SE, але там без відповіді.

Розглянемо наступний алгоритм.

u := 0
v := n+1;
while ( (u + 1) is not equal to v) do
   x :=  (u + v) / 2;
   if ( x * x <= n) 
     u := x;
   else
     v := x;
   end_if
end_while 

де u, v і n - цілі числа, а ділення - це ціле ділення.

  • Поясніть, що обчислюється алгоритмом.
  • Використовуючи свою відповідь у частині I як пост-умову для алгоритму, встановіть цикл інваріант і покажіть, що алгоритм припиняється і є правильним.

У класі встановлено, що пост-умова дорівнює а інваріант . Я не дуже розумію, як отримували пост-стан та інваріанти. Я вважаю, що умова посади була ... що, очевидно, не так. Тож мені цікаво, як було отримано пост-стан та інваріант. Мені також цікаво, як можна отримати попередню умову, використовуючи пост-умову. 0 u 2n < v 2 , u + 1 v u + 1 = v0u2n<(u+1)20u2n<v2,u+1vu+1=v


Ви знайомі з логікою Хоара, і чи очікуєте ви відповіді, що торкнеться її?
Рафаель

Відповіді:


8

Жилль правий, що загальна техніка полягає в тому, щоб піти на риболовлю для цікавих спостережень.

У цьому випадку ви можете помітити, що програма є екземпляром двійкового пошуку, оскільки вона має таку форму:

while i + 1 != k
  j := strictly_between(i, k)
  if f(j) <= X then i := j
  if f(j) > X then k := j

Тоді ви просто підключити вашу приватність f, X... в загальний інваріант для бінарного пошуку. У Dijkstra приємно обговорюється бінарний пошук .


7

u + 1 v u = [ця цікава річ] v = [ця цікава річ]u+1=v - це справді пост-умова циклу while (чому ви вважаєте, що "явно" це не так?). Це завжди у випадку циклу, який не містить a break: коли цикл закінчується, це може бути лише тому, що умова циклу (тут, ) хибна. Це не єдине, що буде істинним, коли цикл закривається тут (цей алгоритм насправді обчислює щось цікаве, як ви бачили у своєму класі, тому і теж є умовами), але це найбільш очевидно.u+1vu=[this interesting thing]v=[this interesting thing]

Тепер, щоб знайти інші цікаві властивості, загального рецепту немає. Насправді, існує якийсь офіційний сенс, в якому немає загального рецепту, щоб знайти петльові інваріанти. Найкраще, що ви можете зробити, це застосувати деякі прийоми, які працюють лише в деяких випадках, або взагалі ловляться на риболовлю для цікавих спостережень (що працює краще і краще, коли ви отримуєте більше досвіду).

Якщо ви запустите цикл для декількох ітерацій з деяким значенням , ви побачите, що на кожній ітерації:n

  • або підскакує до ;( u + v ) / 2u(u+v)/2
  • або стрибає вниз до .v(u+v)/2

Зокрема, починається менше, ніж , і ніколи його не обійде. Крім того, починається додатним і збільшується, тоді як починається від і зменшується. Тож є інваріантом у всій програмі.uvuvn+10uvn+1

Одна річ , яка не так очевидно , є чи будь- НЕ може бути дорівнює . Це важливо: якщо і коли-небудь стануть рівними, у нас буде і цикл буде продовжуватися. Отже, вам потрібно довести, що і ніколи не стають рівними, щоб довести, що алгоритм правильний (тобто не циклічний назавжди). Після того, як ця потреба виявлена, легко довести (я залишаю це як вправу), що - це інваріант циклу (майте на увазі, що і - цілі числа, тому це еквівалентно ).uvuvx=u=vuvu<vuvu+1v

Оскільки в кінці програми, то поставлену вам умову можна також записати (частина є тривіальною). Причина, коли ми хочемо, щоб така умова була такою, включаючи , полягає в тому, що ми хочемо пов'язати результат програми з входом . Чому саме цей стан? Ми шукаємо щось максимально точне, і ми дивимось, де з'являється всередині циклу:v=u+1u2n<v20u2nnn

  • маємо ;uxv
  • коли , ми вибираємо наступне щоб бути , так що (і не змінюється);u x u 2n vx2nuxu2nv
  • коли , ми вибираємо наступне щоб бути , так що (і не змінюється).v x n < v 2 ux2>nvxn<v2u

Ця дихотомія натякає, що, можливо, весь час. Іншими словами, ми підозрюємо, що це цикл інваріант. Підтвердження цього залишається читачем як вправа (не забудьте перевірити, чи властивість спочатку відповідає дійсності).u2n<v2

І тепер, коли ми все це зробили, ми бачимо, що і : - квадратний корінь округлений до найближчого цілого числа.( u + 1 ) 2 > n u nu2n(u+1)2>nun


"Отже, вам потрібно довести, що u і v стають рівними, щоб довести, що алгоритм правильний". Я думаю, що в цьому реченні відсутнє "не".
sepp2k

@KenLi Оскільки це ваше питання в сенсі обміну стеками, чи хотілося б якесь покращення?
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.