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
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.