Różne I – Java na olimpiadzie fizycznej

Programowanie jest chyba najbardziej uniwersalnym narzędziem do rozwiązywania problemów naukowych. Od data processingu, gdzie mamy duże ilości próbek pomiarowych po niemożliwe (ze względu na czasochłonność) do zrealizowana ręcznie obliczenia. Umiejętność zrzucenia pracy na komputer daje sporo możliwości.

W tegorocznej olimpiadzie fizycznej w której brałem udział, w drugiej części zadań pierwszego etapu pojawiło się zadanie, co do którego sami autorzy zachęcali do napisania programu w arkuszu kalkulacyjnym lub dowolnym języku programowania i dostarczenie działającej, opisanej wersji.

Za to zadanie dostałem 15/20 punktów, więc ten post raczej mógłby być przykładem dla przyszłych uczestników, jak mniej więcej rozwiązywać zadania numeryczne OF.


Wstęp do problemu

zadanieCałość dostępna jest na stronie KGOF.

Aby uniknąć nieporozumień, oto ilustracja brachistochrony (czerwony tor) znaleziona na Wikipedii:

Braquistócrona.gif

Zacznijmy od krótkiego wstępu fizycznego, dla osób głebiej zainteresowanych tematem, niżej w odnośnikach załączam omówienie problemu i wyników z programu które wysłałem na OF.

Mamy koralik, wiemy że będzie poruszał się po torze opisanym parabolą. Tor z definicji jest zbiorem punktów odwiedzonych przez ciało w czasie ruchu, co oznacza, że do jakiejś chwili t można przypisać punkt na tej paraboli (i na odwrót).

Z twierdzenia o pracy i energii (w układzie mamy siłę tarcia, więc musimy uwzględnić jej pracę w równaniu energetycznym) możemy obliczyć ile energii straciło/zyskało ciało przemieszczając się z jednego punktu toru do drugiego i przeliczyć tę energię na prędkość  ciała.

W podpowiedzi od autora otrzymaliśmy formułę na długość bardzo małego odcinka paraboli, co jest nam potrzebne, bo w przybliżeniu ten odcinek jest linią prostą – a jak liczymy czas poruszania się po prostej, w przybliżeniu ruchem jednostajnym? Zwykłym t = S / V.

Teraz co nam zostało – przeiterować po współczynnikach ‘a’ funkcji kwadratowej i dobrać taki, przy którym suma czasów na wszystkich małych odcinkach będzie jak najmniejsza (i zrobić to dla każdego z podanych współczynników tarcia).

Zostało nam jedno do spostrzeżenia – koralik startuje na pozycji (0,0) a musi dolecieć do (100,-1). Co oczywiste, jeśli nie ma prędkości początkowej, to musi po prostu spaść metr w dół, aby nabrać prędkość do przemieszczenia się 100 metrów dalej. Dlatego odrzucam ujemne współczynniki, bo wtedy koralik musiałby już na początku wzlecieć w górę, co jest niemożliwe.

Teraz, skoro już wiemy to wszystko, przejdźmy do programu.

Kod programu

Program zaczynam od zapisania stałych podanych w zadaniu, dla czytelności kodu, a także zainicjalizowania co ważniejszych zmiennych:

program1

Warto zwrócić uwagę, że w funkcji zapisującej najkrótszy czas, przyrównuję wartość aktualnego czasu z wartością najmniejszego czasu odnalezionego do tej pory. Jeśli aktualny czas jest mniejszy niż najmniejszy zapamiętany do tej pory czas, to zapisuję go do zmiennej najmniejszy czas. Dlatego też na sam start programu zapisuję do zmiennej najmniejszy_czas maksymalną wartość jaką można zapisać w typie double – aby warunek ten był spełniony przynajmniej raz.

Następnie przyjmuję kilka kluczowych stałych od użytkownika. Nie ma tu zbyt wiele finezji:
inputPo przyjęciu danych, przechodzę do pętli która iteruje od współczynnika początkowego do końcowego, dodając przy każdym przejściu bardzo małą deltę – 0.001. Dobieram następnie do otrzymanego tak współczynnika ‘a’ pozostałe współczynniki (współczynnik c jest zawsze zerowy).  Warte podkreślenia jest, że sprawdzam, czy mam do czynienia z funkcją liniową (a = 0) nie poprzez operator porównania, a dopisaną przeze mnie funkcją – robię to, ze względu na to, że komputery mają kłopoty z reprezentowaniem ułamków binarnie (binarny to w ogóle słaby system na ułamki), odsyłam zaciekawionych poniżej:

https://docs.python.org/3/tutorial/floatingpoint.html

a także do:

http://fulmanski.pl/news/materials/fpn.pdf

Za każdym przejściem pętli uruchamiam również funkcję obliczającą czas przejścia dla zadanej paraboli.

petla whileWspomniana pętla while.

iszero

Wspomniana funkcja isZero.

W tym momencie przechodzimy do wisienki na torcie – funkcji obliczającej czas przejścia. Jest tu dużo matematyki, a w zasadzie zero wartych odnotowania sztuczek programistycznych. Zainteresowani mogą zajrzeć w kod (jest w odnośnikach) i rozwiązanie które wysłałem.

Warte odnotowania jest natomiast to, jak dużo obliczeń wykonuje program, aby znaleźć ten najlepszy wynik.

Powiedzmy, że na start programu podaliśmy współczynnik początkowy a = 0 i końcowy a = 2. Ponieważ nasza delta a jest równa 0.001, to do zbadania mamy 2000 funkcji kwadratowych. Musimy więc 2000 razy obliczyć współczynniki funkcji kwadratowej i pochodną. Dla każdej z tych 2000 funkcji, mamy do przejścia od x początkowego = 0 do x końcowego = 1, ale delta x jest równa z kolei 0.0001f, czyli do przejścia mamy 10000 punktów, a dla każdego z nich liczymy wartość funkcji, równanie energetyczne, prędkość, odcinek drogi i na końcu – czas przejścia przez tę drogę.

Po włączeniu programu, podaniu ‘a’ początkowego = 0 i ‘a’ końcowego = 1 oraz także tarcia beta 1, obliczenie współczynnika ‘a’ paraboli najkrótszego czasu zajęło prawie 60 sekund (przy podanych wcześniej w poście deltach).

Teraz wyobraźcie sobie zrobienie tego wszystkiego ręcznie, na papierze.

Odnośniki:

PDF z fizycznym spojrzeniem na problem i omówieniem wyników programu, który załączyłem do zgłoszenia do OF:

T4-Daniel-Zalega-OF66-I-283-nowe

Repozytorium z kodem, instrukcją uruchomienia i jarem, który wysłałem do OF:

https://bitbucket.org/dbeef/66-olimpiada-fizyczna

Moje rozwiązania zadań doświadczalnych dla drugiego zestawu zadań wraz z punktacją (żeby wiedzieć na ile można się sugerować moją odpowiedzią), być może komuś się przyda:

D3-Daniel-Zalega-OF66-I-283   10/40

Zadanie D1 Daniel Zalega OF66-I-283   24/40


 

dsp2017-1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s