u+1=v jest rzeczywiście warunkiem końcowym pętli while (dlaczego według ciebie nie jest tak „tak”?). Dzieje się tak zawsze w przypadku pętli while, która nie zawiera break
: gdy pętla kończy działanie, może być tak tylko dlatego, że warunek pętli (tutaj, ) jest fałszywy. To nie jedyna rzecz, która będzie prawdą, gdy pętla zostanie zamknięta tutaj (ten algorytm oblicza coś interesującego, jak widzieliście w klasie, więc i są również warunkami wstępnymi), ale jest to najbardziej oczywiste.u+1≠vu=[this interesting thing]v=[this interesting thing]
Teraz, aby znaleźć inne interesujące właściwości, nie ma ogólnej recepty. W rzeczywistości istnieje formalny sens, w którym nie ma ogólnej recepty na znalezienie niezmienników pętli. Najlepsze, co możesz zrobić, to zastosować techniki, które działają tylko w niektórych przypadkach, lub ogólnie wybrać się na ciekawe obserwacje (które działają coraz lepiej, gdy zdobędziesz więcej doświadczenia).
Jeśli uruchomisz pętlę dla kilku iteracji z pewną wartością , zobaczysz to przy każdej iteracji:n
- albo skacze do ;u(u+v)/2
- lub przeskakuje do .v(u+v)/2
W szczególności mniej niż i nigdy go nie wyprzedzisz. Ponadto zaczyna się od dodatniej i wzrasta, podczas gdy zaczyna się od i maleje. Więc jest niezmiennikiem w całym programie.uvuvn+10≤u≤v≤n+1
Jedną rzeczą, która nie jest tak oczywiste, czy może kiedykolwiek być równa . To ważne: jeśli i kiedykolwiek staną się równe, otrzymamy a pętla będzie działać wiecznie. Musisz więc udowodnić, że i nigdy nie stają się równe, aby udowodnić, że algorytm jest poprawny (tj. Nie zapętla się na zawsze). Po zidentyfikowaniu tej potrzeby łatwo jest udowodnić (pozostawiam to jako ćwiczenie), że jest niezmiennikiem pętli (pamiętaj, że i są liczbami całkowitymi, więc jest to równoważne ).uvuvx=u=vuvu<vuvu+1≤v
Ponieważ na końcu programu, podany warunek końcowy można również zapisać (część jest trywialna). Powodem, dla którego chcemy takiego warunku końcowego, obejmującego , jest to, że chcemy powiązać wynik programu z wejściem . Skąd ten precyzyjny warunek? Szukamy czegoś tak precyzyjnego, jak to możliwe, i patrzymy, gdzie pojawia się w pętli:v=u+1u2≤n<v20≤u2nnn
- mamy ;u≤x≤v
- kiedy , wybieramy następny jako , aby (i się nie zmienia);x2≤nuxu2≤nv
- gdy , wybieramy następne jako , aby ( się nie zmienia).v x n < v 2 ux2>nvxn<v2u
Ta dychotomia sugeruje, że być może cały czas . Innymi słowy, podejrzewamy, że jest to niezmienna pętla. Sprawdzanie tego pozostawia się czytelnikowi jako ćwiczenie (pamiętaj, aby początkowo sprawdzić, czy właściwość jest prawdziwa).u2≤n<v2
A teraz, kiedy to wszystko zrobiliśmy, widzimy, że i : jest pierwiastkiem kwadratowym z zaokrąglonym w dół do najbliższej liczby całkowitej.( u + 1 ) 2 > n u nu2≤n(u+1)2>nun