Graham útja

A számítástechnika és a számítógépes geometria , a Graham útvonal (más néven Graham algoritmus ) egy algoritmus számára kiszámítására konvex burok egy ponthalmaz a síkon. Fő érdeke annak algoritmikus komplexitása az O (n log n) , ahol n a pontok számát. Ez az algoritmus Ronald Graham nevéhez fűződik , aki 1972-ben publikálta az eredeti algoritmust .

Algoritmus

Az algoritmus bemenetként egy tömb pontot vesz fel , az alábbi ábra szerint:

A forgáspont kiszámítása

Ennek az algoritmusnak az első lépése a legkisebb ordinátával rendelkező pont megtalálása , amelyet pivotnak hívunk . Ha több pontnak ugyanaz a legkisebb ordinátája van, akkor az algoritmus kiválasztja közülük a legkisebb abszissza pontját . Amint az a következő ábrán látható, a csukló a bal oldali legalacsonyabb pont. Az elforgatás most 1. pont lesz.

Pontok rendezése

Ezután a pontok halmaza (a forgást is beleértve) rendezésre kerül annak a szögnek megfelelően, amelyet mindegyikük az x tengellyel a forgáshoz viszonyítva megad. Erre bármilyen összehasonlító rendezési algoritmus alkalmas, például halom rendezés vagy egyesítés rendezés (amelyek optimálisak és O (n log n) összetettségűek ). Ehhez nem szükséges kiszámítani a valós szöget; korlátozódhat az érintők összehasonlítására, vagy akár a koordináták kereszttermékével megismerheti a pontok relatív helyzetét. Ennek a lépésnek a végén van egy T tömb, amely az így rendezett pontokat tartalmazza. Az alábbi ábra azokat a pontokat mutatja, amelyeket a rendezési sorrend betartása érdekében újraszámoztunk.

Iterációk

Az algoritmus iteratív módon konstruálja a konvex burkot (a következő ábrán zöld színnel). A forgatással kezdjük. Ezután a pontokat a rendezett tömb sorrendjében vizsgáljuk meg (a vizsgálandó pontot feketével mutatjuk be). Minden lépésnél megnézzük, hogy van-e "bal kanyar" (mint az ábrán bemutatott példánál a 2., 5., 13., 15. lépésnél) vagy "jobb kanyar" (mint a 10., 17., 18. lépésnél). a példa).

A végén (19. lépés, majd 20. lépés) az algoritmus kiszámította a konvex borítékot.

Annak megállapításához, hogy három pont "balra" vagy "jobbra" képez-e, nincs szükség a két szegmens közötti tényleges szög kiszámítására , és ezt egyszerű számtannal lehet elérni. Három pontra (x 1 , y 1 ), (x 2 , y 2 ) és (x 3 , y 3 ) elegendő kiszámítani a pontok által definiált két vektor kereszttermékének irányát (x 1 , y 1 ), (x 2 , y 2 ) és (x 1 , y 1 ), (x 3 , y 3 ), az (x 2 - x 1 ) (y 3 - y 1 ) - ( y 2 - y 1 ) (x 3 - x 1 ). Ha az eredmény nulla, a pontok egymáshoz igazodnak. Ha pozitív, akkor a három pont "balra fordulást" jelent. Ellenkező esetben ez egy „jobb kanyar”.

Ez a folyamat végül visszatér arra a pontra, ahol elkezdődött, ebben az esetben az algoritmus megszűnik, és a konvex burkot képező pontokat az óramutató járásával ellentétes sorrendben adja vissza. A példánál az 1., 2., 3., 6. és 9. pont.

Algoritmikus összetettség

A forgásválasztás időbeli összetettsége Θ (n) -ben van, n a halmaz pontjainak száma. A válogatás a pontokat lehet tenni egy ideig összetettsége a O (n log n) . A fő hurok bonyolultsága úgy tűnhet, hogy n (n 2 ), mivel az algoritmus minden ponton visszamegy, hogy felmérje, hogy az előző pontok bármelyike ​​„jobb-e”. De valójában O (n) -nél van, mert minden pontot csak egyszer veszünk figyelembe. Így minden elemzett pont vagy befejezi az alhurkot, vagy eltávolításra kerül a T-ből, ezért soha többé nem veszi figyelembe. Az algoritmus teljes komplexitása tehát O (n log n) -ben van , mivel a rendezés bonyolultsága uralja a konvex burok hatékony számításának bonyolultságát.

Álkód

Legyen T a vizsgálandó pontok halmaza, amely egyből indexelt tömb formájában jelenik meg. Az algoritmus során a szerkesztendő sokszöget veremben tároljuk .

fonction parcours_de_Graham(T[1,.., n]) trouver le pivot et le placer en T[1]; trier le tableau T[2..n] par angle croissant par rapport au pivot (les points d'angle égal seront triés par abscisse croissante) pile.empiler(T[1]); pile.empiler(T[2]); pour i = 3 à n tant que (pile.hauteur >= 2) et (T[i] à droite du segment [pile.second, pile.sommet]) pile.dépiler; pile.empiler(T[i]); retourner pile

ahol a verem.második a verem és a verem tetején lévő pont. a második a verem teteje alatt található pont. Annak tesztelésére, hogy egy A pont van-e egy szegmenstől [BC] balra, ellenőrizzük, hogy a kereszttermék negatív-e, azaz ellenőrizzük, hogy a productVector (A, B, C) ≤ 0 ahol a productVector-t a következő határozza meg:

fonction produit_vectoriel(A, B, C) retourner (B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y);

Megjegyzés  : a degenerált esetek kezeléséhez, ahol a domború hajótest háromnál kevesebb ponttal rendelkezik, kezdetben csak egy pontot kell beírni a verembe, és ha valaha a veremnek kevesebb mint két pontja van (mindig lesz legalább egy), akkor a teteje akkor is ki kell húzni, ha az új pont a figyelembe vett pont. Más szavakkal, a "míg" feltételnek a következőnek kell lennie.

pile.hauteur >= 2 et produit_vectoriel(pile.second, pile.sommet, T[i]) <= 0 ou pile.sommet == T[i]

Beszélgetések

Összehasonlítás más algoritmusokkal

A szög szerinti válogatás helyett az abszcissza szerint válogathatunk, majd a konvex borítékot két szakaszban építjük fel: a felső, majd az alsó részbe. Ezt a módosítást Andrew Andrew készítette, és Andrew Monoton Lánc Algoritmusának hívják . Ez az új algoritmus ugyanazokkal a tulajdonságokkal rendelkezik, mint Graham algoritmusa.

A verem használata Graham algoritmusában hasonló az algoritmusban a legközelebbi kisebb értékekkel kapcsolatos problémához . Ezenfelül léteznek párhuzamos algoritmusok erre a problémára, amelyek felhasználhatók a konvex hajótest hatékonyabb kiszámítására.

Digitális robusztusság

A numerikus robusztusság egy algoritmus viselkedését érinti a lebegőpontos számok pontossága szempontjából . Egy 2004-es cikk azt vizsgálja, hogy Graham algoritmusa hogyan és miért viselkedhet rosszul a gyenge pontosság miatt. A cikk megoldást kínál. A Graham-Fortune algoritmusnak nevezett Graham-algoritmus kiterjesztése stabilabb.

Megjegyzések és hivatkozások

(fr) Ez a cikk részben vagy egészben venni a Wikipedia cikket angolul című „  Graham leolvasó  ” ( lásd a szerzők listáját ) .
  1. "  Forráskód az illusztrációk létrehozásához.  "
  2. "  Tanfolyam a Grenoble Egyetemen  "
  3. (in) RL Graham, Hatékony algoritmus a véges sík halmazának domború héjának meghatározásához , Információfeldolgozó levelek, 1972., 1. o.  132-133 .
  4. AM Andrew , „  Egy másik hatékony algoritmus konvex hajótestekhez két dimenzióban  ”, Information Processing Letters , vol.  9, n o  5,1979, P.  216-219 ( DOI  10.1016 / 0020-0190 (79) 90072-3 )
  5. (in) Mark De Berg , Otfried Cheong , Marc Van Kreveld és Mark Overmars , Computational geometria: algoritmusok és alkalmazások , Berlin, Springer ,2008, 2–14  p. ( ISBN  978-3-540-77973-5 , DOI  10.1007 / 978-3-540-77974-2 , online olvasás )
  6. Omer Berkman , Baruch Schieber és Uzi Vishkin , „  Optimális kettős logaritmikus párhuzamos algoritmusok, amelyek az összes legközelebbi kisebb érték megtalálásán alapulnak  ”, Journal of Algorithms , vol.  14, n o  3,1993, P.  344–370 ( DOI  10.1006 / jagm.1993.1018 ).
  7. Lutz Kettner , Kurt Mehlhorn , Sylvain Pion , Stefan Schirra és Chee Yap , „  Tantermi példák robusztussági problémákról a geometriai számításokban  ”, Computational Geometry , vol.  40, n o  1,2008, P.  61–78 ( DOI  10.1016 / j.comgeo.2007.06.003 , online olvasás ) (Egy korábbi verzióról 2004-ben számoltak be az ESA'2004)
  8. D. Jiang és NF Stewart, Visszafelé történő hibaelemzés a számítási geometriában , Számítástudomány és alkalmazásai - ICCSA 2006, 3980. kötet, az Előadási megjegyzések a számítástechnikában című sorozat , 50–59.
  9. Fortune, S. A ponthalmaz háromszögelések stabil fenntartása két dimenzióban. A 30. éves IEEE Szimpózium a számítógépes tudományok alapjairól című kötete. 30, 494-499, 1989.

Lásd is

Kapcsolódó cikkek

Külső linkek