Wstęp do programowania/Wstęp do algorytmów/Ćwiczenia: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Linia 3: Linia 3:
===Analiza specyfikacji===
===Analiza specyfikacji===
* Czy specyfikacja podana w zadaniu jest wystarczająca do zapisania algorytmu ?
* Czy specyfikacja podana w zadaniu jest wystarczająca do zapisania algorytmu ?
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
 
'''Odpowiedź''' 
{{odpowiedz||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">  
<div class="mw-collapsible-content" style="display:none">  
Nie, nie wiadomo co to znaczy zadane, nie wiadomo czy prostokąty są domknięte (z brzegiem), nie wiadomo co zlecający wykonanie zadania rozumiał przez wyliczanie.
Nie, nie wiadomo co to znaczy zadane, nie wiadomo czy prostokąty są domknięte (z brzegiem), nie wiadomo co zlecający wykonanie zadania rozumiał przez wyliczanie.
</div>
</div>
</div>
</div>}}
 
*Co może być częścią wspólną ?  
*Co może być częścią wspólną ?  
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
{{odpowiedz||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">  
'''Odpowiedź''' 
<div class="mw-collapsible-content" style="display:none">  
Jeśli prostokąty są z brzegiem to prostokąt o bokach równoległych do osi układu, odcinek pionowy lub poziomy, punkt, zbiór pusty; wszystkie te przypadki możemy traktować jako szczególne rodzaje pierwszego przypadku.
Jeśli prostokąty są z brzegiem to prostokąt o bokach równoległych do osi układu, odcinek pionowy lub poziomy, punkt, zbiór pusty; wszystkie te przypadki możemy traktować jako szczególne rodzaje pierwszego przypadku.
</div>
</div>
</div>
</div>}}
 
* Jaka może być postać danych ?
* Jaka może być postać danych ?
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
{{odpowiedz||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">  
'''Odpowiedź''' 
<div class="mw-collapsible-content" style="display:none">  
Można rozważać kilka różnych postaci:
Można rozważać kilka różnych postaci:
# współrzędne dwu przeciwległych wierzchołków,
# współrzędne dwu przeciwległych wierzchołków,
Linia 35: Linia 32:
Reprezentacje 3,4,5 są poprawne, w zależności od tego co chcemy robić z wynikiem naszych obliczeń mogą się okazać warte wybrania.
Reprezentacje 3,4,5 są poprawne, w zależności od tego co chcemy robić z wynikiem naszych obliczeń mogą się okazać warte wybrania.
Reprezentacje 2 i 1 wydają się równoważne, dopiero przy wyborze reprezentacji wyniku okaże się, że różnica między nimi w tym akurat zadaniu jest bardzo istotna.</div>
Reprezentacje 2 i 1 wydają się równoważne, dopiero przy wyborze reprezentacji wyniku okaże się, że różnica między nimi w tym akurat zadaniu jest bardzo istotna.</div>
</div>
</div>}}
 
* Jaka może być postać wyniku ?
* Jaka może być postać wyniku ?
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
{{odpowiedz||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">  
'''Odpowiedź''' 
<div class="mw-collapsible-content" style="display:none">  
Skoro możemy traktować każdy możliwy wynik jako (być może zdegenerowany) prostokąt o bokach równoległych do osi układu, to byłoby dobrze użyć tu tej samej reprezentacji co dla danych (nam jako piszącym będzie łatwiej, a przede wszystkim jest to lepsze dla użytkownika, który będzie mógł zastosować nasz algorytm do wyników przez ten algorytm policzonych).  I tu okazuje się wyższość reprezentacji 2, która pozwala reprezentować także pusty prostokąt, w przeciwieństwie do reprezentacji 1. (Reprezetacje 3-6 też są dobre, moglibyśmy także np.  rysować wynik na ekranie.)
Skoro możemy traktować każdy możliwy wynik jako (być może zdegenerowany) prostokąt o bokach równoległych do osi układu, to byłoby dobrze użyć tu tej samej reprezentacji co dla danych (nam jako piszącym będzie łatwiej, a przede wszystkim jest to lepsze dla użytkownika, który będzie mógł zastosować nasz algorytm do wyników przez ten algorytm policzonych).  I tu okazuje się wyższość reprezentacji 2, która pozwala reprezentować także pusty prostokąt, w przeciwieństwie do reprezentacji 1. (Reprezetacje 3-6 też są dobre, moglibyśmy także np.  rysować wynik na ekranie.)
</div>
</div>
</div>
</div>}}


=== Znajdowanie algorytmu ===
=== Znajdowanie algorytmu ===

Wersja z 10:08, 1 sie 2006

Zadanie 1

Podaj algorytm wyliczający część wspólną dwóch zadanych prostokątów o bokach równoległych do osi układu współrzędnych.

Analiza specyfikacji

  • Czy specyfikacja podana w zadaniu jest wystarczająca do zapisania algorytmu ?

Odpowiedź

{{{2}}}
  • Co może być częścią wspólną ?

Odpowiedź

{{{2}}}
  • Jaka może być postać danych ?

Odpowiedź

{{{2}}}
  • Jaka może być postać wyniku ?

Odpowiedź

{{{2}}}

Znajdowanie algorytmu

Gdy zaczniemy analizować możliwe wzajemne położenia prostokątów okaże się, że przypadków jest co najmniej kilkanaście. Prostokaty.png

Wskazówka 1

Wskazówka 2

Rozwiązanie

Testowanie

Mając algorytm/program powinniśmy go przetestować, czyli sprawdzić jakie daje wyniki dla przykładowych danych. Warto testować z jednej strony przypadki typowe, z drugiej zaś szczególne przypadki graniczne (np. prostokąty dotykające się jednym rogiem lub jeden prostokąt zawarty w drugim). Testowanie jest ważne i trzeba je robić, mimo że, w przypadku gdy nie wykryje błędów, nic nie daje (nawet nie mamy pewności, że dla przetestowanych danych zawsze dostaniemy poprawny wynik, bo np. mamy niezainicjalizowane zmienne).

Dowód poprawności

Skoro testowanie nie daje pewności, że mamy dobry program to potrzebujemy innego narzędzia, które pozwoli nam spać spokojnie - możemy (przynajmniej teoretycznie) dowieść formalnie poprawność programu. Powinniśmy ustalić co jest formalną specyfikacją naszego zadania (W = A ∩ B) i zrobić formalny dowód, że dla każdego punktu p zdanie p ε A ∩ B jest równoważne temu, że p ε W. Teraz już możemy spać spokojnie - nasz algorytm jest poprawny (o ile nie pomylilismy się w dowodzie)!

Dowód

Najważniejszy morał z tego zadania, to pochwała myślenia - trzeba wykonać dużo pracy (myślowej) zanim zacznie się pisać pierwszy wiersz programu/algorytmu.

Inna wersja zadania

A co by było gdyby prostokąty były otwarte (czyli bez brzegu) ?

Reprezentacja używana powyżej jest nadal dobra zarówno dla danych jak i dla wyniku. Tym razem możliwe są tylko dwie postacie wyniku: albo prostokąt (z wnętrzem) o bokach równoległych do osi układu, albo zbiór pusty. Algorytm który podaliśmy powyżej działa również dla prostokątów otwartych; w dowodzie poprawności trzeba by jedynie zamienić nierówności nieostre (≤, ≥) na ostre (<, >).

Zadanie 2

Podaj algorytm wyliczający najmniejszy prostokąt o bokach równoległych do osi układu współrzędnych zawierający dwa zadane prostokąty o bokach równoległych do osi układu współrzędnych.

Wskazówka

Rozwiązanie

Zadanie 3

Używając tylko czterech podstawowych działań arytmetycznych sprawdź czy dwa odcinki na płaszczyźnie, zadane porzez współrzędne końców, przecinają się.

Wskazówka 1

Wskazówka 2

Wskazówka 3

Rozwiązanie

Zadanie 4

Sprawdż czy dane dwa równolełoboki na płaszczyźnie przecinają się. Równoległoboki mają boki dowolnie nachylone do osi współrzędnych i zadane są porzez współrzędne czterech rogów podanych zgodnie z ruchem wskazówek zegara.

Wskazówka 1

Rozwiązanie