Konveksni omotač (red O(n log (n))) Seminarski rad Konveksni omotač (red O(n log (n))) Stefan Cerovina Djordje Rakonjac Marko Milošević Perica Trajkov
UVOD Značaj I karakteristike: Obrada konveksnih mnogouglova je mnogo lakša Uvek postoji I jedinstven je Postoji mnogo alogritama Problem: ograditi n tačaka najmanjom zatvorenom poligonskom linijom
Direktni pristup (O(n³)) Posmatramo svaki par duži Provera da li se sve ostale tačke nalaze sa iste strane duži Da → duž ulazi u konveksni omotač Ne → duž NE ulazi u konveksni omotač Složenost O(n³)
Direktni pristup (O(n³)) - psedo-kod for i:=1 to n-1 do for j:=i+1 to n do pripada=true; levo=false; desno=false; for z:=1 to n do if z je sa desne strane duzi(i,j) then desno=true; if levo=true then pripada=false; break Else levo=true; if desno=true then pripada=false; break If pripada then dodaj_u_konveksni(i,j)
Grahamov algoritam (O(n logn)) Formira se gornji i donji omotač i spajaju se Koraci formiranja gornjeg (donjeg) omotača: 1. Tačke se sortiraju po x-koordinati, odnosno y, ako su x koordinate jednake 2. Ubacujemo sledeću tačku u skup (inicaijalno ima 2 tačke) 3. Proveravamo desni zaokret poslednje tri tačke 4. Da → predji na korak 2 Ne → predji na sledeći korak 5. Izbacujemo pretposlednju tačku iz skupa. Skačemo na korak 3.
Grahamov algoritam (O(n logn)) - psedo-kod Ulaz: Niz A[i] n sortiranih tačaka, Izlaz: Niz tačaka konveksnog omotača gornji=(A[1], A[2]); k:=2; for i:=3 to n do dodaj_u_gornji(A[i]); k++; while ((k>2) and not desni(gornji[k-2], gornji[k-1], gornji[k])) izbaci_iz_gornjeg(A[k-1]); k- -; donji=(A[n], A[n-1]); l:=2; for i:=n-2 to 1 do dodaj_u_donji(A[i]); k++; while ((l>2) and not desni(gornji[l-2], gornji[l-1], gornji[l])) izbaci_iz_donjeg(A[l-1]); l- -; Spoji (gornji,donji);
Grahamov algoritam (n logn) Složenost n*logn Početno sortiranje O(n*logn), Ostatak algoritma O(n) - svaka tačka se dodaje samo jednom, I eventualno briše samo jednom
Test primeri Za ulaz n=100 (i 10 iteracija istog koda): n*logn: 0 sekundi 188 milisekundi n³ : 3 sekundi 782 milisekundi Za ulaz n=10 (i 100 iteracija istog koda): n*logn: 0 sekundi 171 milisekundi n³: 0 sekundi 15 milisekundi Za ulaz n=1000 (i 100 iteracija istog koda): n*logn: 0 sekundi 344 milisekundi n³: još uvek računa
Test primeri - zaključak Za male ulaze (npr. n=10) n³ radi brže nego n*logn Razlog: veliki konstantni faktor kod Grahamovog algoritma Za velike ulaze, Grahamov algoritam je zantno brži