P-Programowanie

Pole figury ograniczonej krzywymi

18 listopada 2013, kategoria: Matura z informatyki

Obliczanie pola figury ograniczonej krzywymi było jednym z zadań na maturze z informatyki w 2006 roku. Według mnie jest to najtrudniejsze zadania jakie zostało umieszczone w arkuszach egzaminacyjnych z informatyki. Gdy przygotowywałem się do matury i rozwiązywałem zadania z poprzednich lat, było to jedyne zadanie, którego nie udało mi się wtedy samemu rozwiązać.

Treść zadania

Przez F(C) oznaczamy figurę narysowaną w kartezjańskim układzie współrzędnych, która ograniczona jest przez:

  • oś OY z lewej strony
  • prostą o równaniu X=10 z prawej strony
  • krzywą o równaniu f(x)=\frac{-x^2}{50} od dołu
  • krzywą o równaniu g(x)=1+\frac{x^2}{100}-\frac{x}{200} od góry

Oblicz pole figury F(C) z dokładnością do 0,01.

pole figury ograniczonej krzywymi C++

Podejście matematyczne do problemu

Niestety w 4 technikum nie wiedziałem co to całka. Zanim zaprezentuję moje błędne myślenie oraz poprawne rozwiązanie, obliczmy zadania używając analizy matematycznej.

Całka oznaczona z funkcji h(x) jest to pole obszaru ograniczonego wykresem funkcji h(x) oraz osią OX w określonych przedziałach [a,b].

Pole figury F(C) można prosto wyznaczyć całkując funkcje podane w zadaniu, w przedziałach [0,10].

Policzmy osobno dwie całki f(x) i g(x) oznaczone w przedziałach [0,10]. Licząc całkę z funkcji f(x) należy pamiętać aby zmienić znak, ponieważ jej wykres leży poniżej osi OX.

Całka z f(x):

\int\limits_{0}^{10}\frac{-x^2}{50}dx=-\frac{1}{50}\int\limits_{0}^{10}x^2dx=-\frac{1}{50} \cdot \frac{x^3}{3}=\frac{-x^3}{150} \Bigg|_0^{10}=-\frac{10^3}{150}-0=-\frac{1000}{150}=-\frac{20}{3}

Całka z g(x):

\int\limits_{0}^{10}1+\frac{x^2}{100}-\frac{x}{200}dx=\int\limits_{0}^{10}1 dx + \int\limits_{0}^{10}\frac{x^2}{100}dx-\int\limits_{0}^{10}\frac{x}{200}dx =x\Bigg|_0^{10}+\frac{1}{100} \cdot \frac{1}{3} \cdot x^3 \Bigg|_0^{10}-\frac{1}{200} \cdot \frac{1}{2} \cdot x^2 \Bigg|_0^{10}=10+\frac{1000}{300}-\frac{100}{400}=10+\frac{10}{3}-\frac{1}{4}=\frac{157}{12}

 

Sumując wyniki otrzymujemy:

\frac{157}{12}+\frac{20}{3}=\frac{79}{4}=19,75

Po krótkich obliczeniach, otrzymujemy dokładne pole figury F(C), które wynosi 19,75 [j^2].

Moje błędne rozwiązanie

Będąc w technikum udało mi się po części dojść do prawidłowego wyniku, jednak nie mam pojęcia jak metoda została by oceniona przez egzaminatora. Przypuszczam, że miał bym wielkie szanse dostać 100% punktów, ponieważ pani Bożenka, która uczy informatyki w szkole średniej nie umiała by poprawnie ocenić tego zadania. Gdyby zobaczyła poprawny wynik i całą stronę kodu C++ nie zastanawiała by się nad szczegółami. Muszę także nadmienić, że na błędną drogę rozwiązania zadania nakierował mnie mój nauczyciel od programowania.

Metoda polegała na podzieleniu obszaru figury na 10000 „pasków”. Deklarujemy obydwie funkcje, aby po podaniu argumentu otrzymać wartość. Ostatnim krokiem jest zbudowanie pętli for, zaczynając od 0 i kończąc na 10. Najważniejszym elementem jest krok pętli, który wynosi 0,001. Jest to pierwsza rzecz, która jest niezgodna z treścią zadania, ponieważ pole miało zostać policzone z dokładnością do 0,01.

Po kolejnych obiegach pętli sumujemy długość „pasków” w przedziale [0,10].

Przed wyświetleniem wyniku konieczne było zaokrąglenie wyniku do 2 miejsc po przecinku, ponieważ wynik nie zgadzał się o 0.0019.

Po zmienieniu dokładności z 0,001 na 0,01 (czyli zgodnie z treścią), pole nie zgadzało się o około 0,1.

Rozwiązanie optymalne

Rozwiązaniem optymalnym było użycie metody trapezów do obliczania całek numerycznych. Nie wiem kto wpadł na chytry plan, aby umieścić takie zadanie na maturze w szkole średniej, jednak na moje oko było ono trudne, szczególnie narzucona w kluczu metoda trapezów której w szkole średniej chyba nikt nie przerabiał (MES).

Przeglądając opinie na temat zadania przeczytałem o osobach, które policzyły pole figury matematycznie (całkami), jednak nikt nie pisał aby wstrzelił się w klucz.

Całkowanie numeryczne metodą trapezów opisałem w osobnym artykule: Całkowanie numeryczne – metoda trapezów, dlatego nie będę dokładnie jej opisywał. Dalsza część artykułu pisana jest z przekonaniem, że rozumiesz metodę trapezów.

Rysunek poglądowy wykorzystując trapezy wygląda mniej więcej tak:

obliczanie pola figury metodą trapezów

Trapezami wypełniłem tylko jedną funkcję, aby rysunek wyglądał bardziej przejrzyście. Na rysunku znajduje się 5 trapezików, co oznacza że dokładność obliczeń (krok h) wynosi 2:

h=\frac{x_{k}-x_{p}}{n} h=\frac{10-0}{5}=2

W zadaniu jest napisane, aby pole figury obliczyć z dokładnością 0,01 co oznacza, że krok (h) musi wynosić dokładnie 0,01. Aby uzyskać taką dokładność należy podzielić obszar pod całką na 1000 malutkich trapezów, co staje się nie możliwe do przedstawienia graficznie.

h=\frac{10-0}{1000}=0,01

Wynikiem całki  (polem całkowitym) z górnej funkcji będzie suma wszystkich pól trapezów:

P_{c}=P_{1}+P_{2}+\ldots+P_{1000}

Rozpiszmy teraz wzór dla 1000 trapezów:

P_{c}=\frac{f(x_{0})+f(x_{1})}{2}\cdot h+\frac{f(x_{1})+f(x_{2})}{2}\cdot h+\ldots+\frac{f(x_{999})+f(x_{1000})}{2}\cdot h

Uprośćmy wzór, wyłączając odpowiednie czynniki przed nawias (jeżeli nie wiesz o co chodzi to przeczytaj artykuł o całkowaniu numerycznym):

P_{c}=\frac{h}{2}\cdot(f(x_{0}) + 2\cdot f(x_{1})+\ldots+2\cdot f(x_{999})+f(x_{1000})) P_{c}=h\cdot(\frac{f(x_{0})}{2}+f(x_{1})+\ldots+f(x_{999})+\frac{f(x_{1000})}{2})

Podanym wzorem można obliczyć całkę z funkcji g(x). Taki sam wzór posłuży do liczenia całki z funkcji f(x), będzie trzeba tylko zmienić znak. Wzór poda nam pole z dokładnością do 0,01 ponieważ podzieliliśmy obszar na 1000 małych trapezów.

Oczywiście nie będziemy liczyć tego na piechotę a wzór został wyprowadzony tylko po to, aby zobaczyć ważną zależność. Aby obliczyć całkę z g(x) (czyli pole) wystarczy zsumować podstawy wewnętrznych trapezów, następnie zsumować z nimi „zewnętrzne podstawy” x0 oraz x1000 podzielone przez 2. Na samym końcu otrzymaną liczbę mnożymy przez krok (h).

Długości podstaw bardzo łatwo obliczyć w C++ używając pętli i iteratora:

Podst_{i}=f(x_{p} +i \cdot h), dla i=1..999

Po wyjściu z pętli liczymy długości podstaw brzegowych zgodnie z wyprowadzonym wzorem i dzielimy je przez 2:

Podst_{0}=\frac{f(x_{p})}{2} Podst_{1000}=\frac{f(x_{k})}{2}

Na samym końcu sumujemy poszczególne podstawy i mnożymy przez krok h. Pamiętaj aby funkcję f(x) odejmować a nie dodawać, ponieważ jej wykres znajduje się poniżej osi OX.

Kompletny kod w C++, spełniający wymagania egzaminatorów, liczący pole z dokładnością do 0,01 i wykorzystujący metodę trapezów wygląda następująco:

Ciekawe ile osób poradziło sobie z tym zadaniem mając na nie 50 minut?
Działający program znajdziesz przechodząc na podstronę: http://p-programowanie.pl/pliki/calka1.html

Komentarze:

Użytkownik Janusz napisał/a:

24 listopada 2013


Hej, głowa do góry :)
Myśl o swoich czytelnikach co dla nich jest pomocne, w czym im możesz pomóc.

Użytkownik Unnamed napisał/a:

02 stycznia 2014


W moim podręczniku, jedyną metodą jest metoda prostokątów. Myślę, że ta metoda powinna być poprawna. Jedynym problemem jest dokładność, bo z tego co pamiętam jak robiłam to zadanie przez obliczanie pól prostokątów, musiałam znacznie zwiększyć ilość tych prostokątów, bo wynik nie mieścił się w dopuszczalnej granicy. ;)

Użytkownik Ryś napisał/a:

18 września 2014


Mam tylko jedną uwagę dokłądność obliczeń 0.01 oznacza że dalsze zmniejszanie szerokości trapezów powoduje zmianę wielkości pola o mniej niż 1/100. Natomiast nie oznacza to stałej szerokości przedziału. Czyli zadanie jest jeszcze bardziej skomplikowane ponieważ oprócz liczenia pola trzeba jeszcze sprawdzać po każdej iteracji o ile się zmieniła wartość.

Użytkownik Tomasz napisał/a:

01 grudnia 2016


Tak jest, @Ryś, też wydaje mi się że z tą dokładnością to sprawa wcale nie jest taka prosta.
Moim zdaniem trzeba by badać w jaki sposób na zmianę wyniku wpływa zagęszczanie podziałów.

Czyli w przypadku funkcji liniowej wystarczy po prostu 0 podziałów i wynik będzie 100% dokładny a zagęszczanie podziałów nie będzie dawało nic.

Zupełnie inaczej będzie w przypadku funkcji harmonicznych, tutaj ilość podziałów powinna stanowić wielokrotność okresów objętych przedziałem całkowania.

Użytkownik Logman napisał/a:

08 stycznia 2017


Autorze dlaczego uważasz że metoda „pasków” nie jest poprawna? Zarówno metoda pierwsza jak i metoda prostokątów narażona jest na błąd związany z próbkowaniem funkcji. Czyli tym więcej próbek tym bardziej dokładny wynik. Problemem może okazać się również użycie float zamiast double przy wysokiej częstotliwości próbkowania.

Autorze przedstawienie wyniku z odpowiednią dokładnością nie jest tym samym co częstotliwość próbkowania!

Piszę tu ponieważ strona ta pokazuje się jako pierwszy wynik w google przy próbie szukania zadań maturalnych i jeszcze jakiś „informatyk” zacznie stawiać negatywne oceny za sposób rozwiązania który autor określił jako niepoprawny a poprawnym jak najbardziej jest.

Zachęcam Cię do zostawienia komentarza!

Ilość znaków: 0

Zachęcam Cię do polubienia bloga na facebooku! Dając lajka wspierasz moją pracę - wszystkie artykuły na blogu są za darmo!