Feladat:

Adott az S halmaz, amely a sík n pontját tartalmazza. Keressük meg azt a három pontot az S halmazból, amelyek a legkisebb területű háromszöget alkotják.

 

Naiv megoldás (brute – force) :

A feladat megoldható úgy, hogy minden ponthármas által alkotott háromszög területét kiszámítjuk és ezek közül választjuk ki a legkisebbet. Ennek az algoritmusnak létezik egy gyorsabb változata is, melyben minden pi pj pontpárra az S-ből kiszámoljuk a d(k,i,j) távolságot a pk ponttól a pi és pj által meghatározott egyenesig, minden pk eleme S-{pi, pj }-re. Mivel a pk, pi és pj által alkotott háromszög területe egyenlő a d(k,i,j)*|pipj| szorzat felével, így megkapjuk az összes olyan háromszög területét, melynek pipj oldala. Ezt elvégezve minden pontpárra az S-ből, megkapjuk az összes olyan háromszög területét melynek csúcspontjai az S halmazhoz taroznak. Ezekből kell kiválasztanunk a legkisebb területűt. A fenti algoritmus gyorsabb ugyan, de bonyolultság szintén O(n3).

 

 

 

Értelmezés:

Legyen p egy pont és l egy egyenes. A függőleges távolsága p-nek l-től a p pont és a p-ben húzott függőleges egyenes l egyenessel való metszéspontja között lévő távolság. Ezt dv(p,l)-el jelöljük.

 

Megjegyzés:

A legtöbb esetben egy pont távolsága egy egyenestől nem esik egybe a pont függőleges távolságával az egyenestől.

 

Jelölés:

Legyen dv(k,i,j) a pk pont függőleges távolsága a pi és pj által alkotott egyenestől. Az egyszerűség kedvéért,  szintén dv(k,i,j)-el jelöljük a a pk pont függőleges távolságát a pi pj  szakasztól.

 

1. Lemma:

Rögzítsük a pi és pj pontokat az S-ből. Legyen li,j a pi és pj pontok által meghatározott egyenes. Ekkor egy pk pont S-{pi, pipk }-ből legkisebb d(k,i,j) távolságra van li,j-től, akkor és csakis akkor ha pk van a legkisebb dv(k,i,j) függőleges távolságra li,j-től.

 


Bizonyítás:

Legyen lv az a függőleges egyenes, amely áthalad a pk ponton és metszi az li,j egyenest q pontban. Jelölje θ az li,j és lv által alkotott szöget. A dv(k,i,j) függőleges távolság ekkor egyenlő a pkq szakasz hosszával és könnyű belátni, hogy hossza ׀pkq׀*sin θ. Következik, hogy dv(pk,li,j) és d(pk,li,j) arányosak. Így a lemma nyilvánvalóan igaz.

 

A legkisebb háromszög megkeresésekor a pi és pj S-beli pontpárok esetén csak az olyan pk pontokat kell tekintenünk, melyek az S-{pi, pj }-ből vannak és dv(k,i,j) a legkisebb.

Először egy T1 transzformációt hajtunk végre S pontjain. A T1 egy pk pontot az S-ből egy T1(pk) egyenesbe visz át, míg a pi-n és pj-n áthaladó li,j egyenest a T1(li,j) pontba, mely egybeesik a T1(pi) és T1(pj) egyenesek metszéspontjával. Ezen transzformáció egy hasznos tulajdonságát bizonyítjuk a következő  lemmában.

 

2. Lemma:

A függőleges távolsága pk-nak li,j -től dv(k,i,j) egyenlő a függőleges távolságával T1(li,j)-nek T1(pk)-tól dv(T1(pk),T1(li,j)).

dv(k,i,j)= dv(T1(pk),T1(li,j))

 

Bizonyítás:

Legyen pi két koordinátája ai és bi, pj-nek aj és bj, pk-nak ak és bk.

Ekkor az li,j egyenlete a következő:


 

A pi, pj és pk pontokat a transzformáció a következő egyenesekké alakítja:

 

T1(pi): y=aix+bi

T1(pj): y=ajx+bj

T1(pk): y=akx+bk

 


Az li,j pont pedig:

 

Az li,j és a pk-n áthaladó függőleges egyenes metszéspontja:


 


Ekképpen a pk függőleges távolsága li,j -től a következő szám abszolút értéke lesz:

 

Hasonlóképpen a T1(pk) egyenes és T1(li,j)-n áthaladó függőleges egyenes metszéspontja:


Ugyanakkor a függőleges távolsága T1(pk) egyenesnek a T1(li,j) ponttól a következő szám abszolút értéke:




Ez tehát bizonyítja a lemmát.

 

De miben is segít ez a lemma? Előbb alakítsunk át T1 transzformációval minden pi pontot az S-ből T1(pi) egyenessé, minden i=1,…,n -re. Így egy  n darab egyenesből álló halmazt kapunk.

 

T1(S)=  {T1(p1),T1(p2),…,T1(pn)}

 

A T1(S) halmaz, amely n egyenest tartalmaz T1(pi), i = 1,…,n, egy síkgráfot alkot, ha minden két vonal metszetét T1(S)-ből a gráf csúcspontjának tekintjük. Legyen li,j a pi és pj által meghatározott egyenes S-ben. Ahhoz, hogy megtaláljuk azt a pontot az S-ből, amelynek a legkisebb a függőleges távolsága az li,j egyenestől, minden csúcspontot meg kell vizsgáljunk S-{pi, pj }-ből . Ahhoz, hogy megtaláljuk a T1(pk) vonalat T1(S)-ből úgy, hogy  a T1(li,j) pontnak legyen a legkisebb függőleges távolsága T1(pk)-tól, csak a T1(S)-ben a rögtön T1(li,j) felett és alatt lévő egyeneseket szükséges ellenőrizni. Ezért, ha megfelelően kezeljük a T1(S) síkgráfját, hatékonyan tudjuk megtalálni azt a T1(pk) egyenest T1(S)-{T1(pi),T1(pj)}-ből, melyre a T1(li,j) ponttól való függőleges távolsága a legkisebb lesz. A két ismertetett lemmából következik, hogy a pk pont távolsága a legkisebb minden S-{pi, pj }pont közül az li,j -től, ami miatt a Δ(pk,pi,pj) háromszög a legkisebb területű azok közül, melyeknek egyik éle a pipj szakasz. Minden pi és pj pontpárra S halmazból végrehajtjuk a fentieket és megkapjuk a legkisebb területű háromszöget.

Lássuk hogyan kell megkeresni azt az egyenest amely legközelebb van a T1(li,j) ponthoz T1(S)-ből. Végrehajtunk egy síksöprést a T1(S) síkgráfján balról jobbra egy L egyenessel. A T1(S)-beli egyeneseket egy A 2-3 fában tároljuk az L-en való metszéspontjuk szerint rendezve. Mivel T1(S)-ben pontosan n darab egyenes van az A 2-3 fának n levele van és mélységét O(log n) határolja. Feltételezzük, hogy egy adott pillanatban az L egyenes egy T1(li,j) csomóponton halad át; ekkor könnyű belátni, hogy a T1(pi) és T1(pj) egyenesek kivételével, melyek T1(li,j)-ben metszik egymást, T1(S) minden egyenese fenntartja egymással szembeni relatív pozícióját az A 2-3 fában. Másfelől pedig T1(pi) és T1(pj) egyenesek helyet cserélnek az A 2-3 fában. Másképpen fogalmazva, ha a T1(pi) egyenes a T1(pj) egyenes fölött található a T1(li,j) pont bal felén, akkor a T1(pi) a T1(pj) egyenes alatt kell elhelyezkedjen a T1(li,j) pont jobb felén, és fordítva. Legyen a rögtön T1(li,j) csomópont fölött és a rögtön alatta lévő két egyenes az S síkgráfjában T1(pk) illetve T1(ph). Ekkor T1(pk) és T1(ph) is O(log n) idő alatt érhető el az A 2-3 fában. Hogy egy T1(li,j) csúcspont relatív helyét az A 2-3 fában megtaláljuk, egy keresést indítunk a fában az y koordináta szerint és közben rögzítjük minden egyenes x koordinátáját A-ban a T1(li,j) x koordináta értékére.

A következő algoritmus a fentiek implementációja egy S halmaz pontjai közül adja meg azt a hármat, amely a legkisebb területű háromszöget alkotja.

 

Algoritmus LEGKISEBB-HÁROMSZÖG (S)

Adott: egy síkbeli pontokat tartalmazó S halmaz

Eredmény: három pont S-ből, amely a legkisebb háromszöget alkotja

BEGIN

1.              Minden pi pontra S-ből, i=1,...,n szerkeszd meg a T1(pi) egyenest.

2.              Mindegyik első lépésben szerkesztett T1(pi) és T1(pj) egyenespárra i,j=1,...,n számítsd ki a metszéspontjukat, a T1(li,j) csúcspontot.

3.             

Rendezz minden T1(li,j) metszési csúcsot, i,j=1,...,n, x koordináta szerint növekvő sorrendbe. Legyen a rendezett lista {v1,…,vm}, ahol

és vi=(xi,yi), i=1,...m.

4.              Építsd fel az A 2-3 fát, amelynek levelei a T1(pi) egyenesek, i=1,...,n, az x=x1-1 egyenesen való metszéspontjuk y koordinátája szerint rendezve.

5.              Minden r=1,...,n esetén végezd el

Feltételezzük, hogy a vr csúcspont a T1(pi) és T1(pj) egyenesek metszési csúcsa és a rögtön felette és rögtön alatta lévő egyenesek T1(pk) és T1(ph). Számítsd ki a Δ(pk,pi,pj) és Δ(ph,pi,pj) háromszögek területét. Cseréld ki a T1(pi) és T1(pj) egyenesek pozícióját az A 2-3 fában.

6.              A háromszög, amelyet az 5. lépésben szerkesztettünk és a területe a legkisebb, lesz a legkisebb területű háromszög.

END

 

Nem tárgyaltuk azt az esetet mikor három egyenes T1(pi), T1(pj) és T1(pk) egy pontban metszi egymást. Ebben az esetben a T1(li,j) metszéspontja T1(pi) és T1(pj) egyeneseknek, függőleges távolsága T1(pk)-tól nulla. A második lemma alapján a pk pont függőleges távolsága li,j -től nulla. Következésképpen pi, pj és pk kollineárisak és a legkisebb területű háromszög területe nulla. Ha találunk tehát három ilyen egyenest azonnal megállunk és visszatérítjük a (pi,pj,pk) hármast, amely nulla területű háromszöget alkot.

 

Az algoritmus bonyolultsága:

1.      Lépés: O(n)

2.      Lépés: O(n2) és létrehoz


metszési csúcsot T1(S)-ben

3.      Lépés: O(n2log n) a második lépésben szerkesztett metszési csúcsok rendezése

4.      Lépés: O(n log n).

5.      Lépés: Minden vr csúcsra O(log n) idő alatt találja meg a vr csúcs pozícióját az A 2-3 fában, frissíti az A 2-3 fát és számítja ki a két háromszög területét. Tehát a szükséges idő: O(m log n) = O(n2 log n).

6.      Lépés: Mivel minden vr csúcspontnak két háromszöget szerkesztünk, a szerkesztett háromszögek számának határa O(m) = O(n2). Következésképpen ez a lépés O(n2) időt vesz igénybe.

A fenti algoritmus bonyolultsága tehát: O(n2 log n)

 

Mivel minden egyenes a T1(S) síkgráfjában megfelel egy pontnak S-ből, az A 2-3 fa pontosan n levelű. Viszont a vr csúcsok tárolására Ω(n2) tárterület szükséges, tehát az algoritmus ennyi helyet igényel.

Hogyan lehet redukálni az algoritmus által igényelt helyet? A fentiek alapján az algoritmusnak szükséges Ω(n2) tárterület az m darab metszési csomópont tárolására. Valójában nem szükséges az egész eltárolt lista. Ami tényleg érdekel, hogy minden lépésben melyik csúcspont következik az aktuális után. Ez a következő a jelenlegi vr jobboldalán lévő és a vr-en áthaladó függőleges egyeneshez a legközelebbi kell legyen. Figyeljük meg, hogy egy ilyen csúcspont a metszéspontja kell legyen két egyenesnek T1(S)-beli egymásutáni levélnek az A 2-3 fában. Ezért ha tárolunk egy B listát az egymásutáni leveleiről az A 2-3 fának, amik a jelenlegi vr csúcspont jobboldalán vannak (legtöbb n-1 ilyen van), akkor a B listában a legközelebb lévő, a jelenlegi vr csúcsponton áthaladó, függőleges egyeneshez, kell legyen a következő csúcspont a fenti algoritmus 5. lépésében.

Ezért, az egész lista létrehozása helyett, egy B 2-3 fát használunk, amelyben az egymásutáni egyenesek metszési csúcsait tároljuk, amelyek jobbra vannak vr-től. B-nek n-nél kevesebb levele van. Ha a jelenlegi csúcspont vr, akkor a következő csúcspont megtalálásához megkeressük azt a vr+1 csúcsot B-ből, aminek legkisebb az x koordinátája. Ekkor vr-t töröljük B-ből. Miután bejártuk vr-t, csak négy szomszédos egyenessel váltózhat a viszonya. Feltételezzük, hogy vr a T1(pi) és T1(pj) egyeneseknek metszéspontja,  a vr csomópont fölött és a rögtön alatta lévő két egyenes T1(pk) illetve T1(ph) és, hogy mielőtt bejártuk a vr csúcspontot a T1(pi) a T1(pj) fölött volt. Miután bejártuk a vr-t T1(pj) a T1(pi) fölött lesz. Ezért mielőtt bejártuk vr-t az egyenesek sorrendje:

   T1(pk)  T1(pi) T1(pj) T1(ph)

az A 2-3 fában, bejárás után az új sorrend:

   T1(pk)  T1(pi) T1(pj) T1(ph)

Ennek megfelelően a 2-3 B fa frissíthető azáltal, hogy töröljük a metszési csúcspontját T1(pk) és T1(pi)-nek és T1(pj) és T1(ph)-nak és beszúrjuk a metszéspontját T1(pk) és T1(pj)-nek és T1(pi) és T1(ph)-nak ha a vr jobboldalán vannak. Mivel a 2-3 B fának n-nél kevesebb levele van, a fenti műveletek O(log n)  idő alatt végezhetőek el. Így az 5. lépésben egy csúcs bejárása O(log n) és a tárterület O(n).

 

Végkövetkeztetések:

Ha a legkisebb háromszög területe nulla, akkor a három csúcspontja kollineáris. Tehát a fenti algoritmus használható arra is, hogy megállapítsuk, létezik-e három kollineáris pont egy ponthalmazon belül. A fenti algoritmus nem a leghatékonyabb. Az eddig ismert leghatékonyabb algoritmus, Edelsbrunner, O'Rourke és Seidel algoritmusa, mely O(n2) idő- és O(n) tárbonyolultságú. Az ismert alsó határ Omega(n log n). A három kollineáris pont létezésére vonatkozó feladat ismert alsó határai szintén O(n2), illetve Omega(n log n). A felső, vagy alsó határok javítása még egy nyílt kérdés a komputacionális geometria tudományán belül.