Kirkpatrick-Seidel-algoritmus
Kiejtés
- IPA: [ ˈkirkpɒtrit͡skʃɛjidɛlɒlɡoritmuʃ]
Főnév
A Kirkpatrick-Seidel-algoritmus egy hatékony algoritmus a kétdimenziós sík konvex burkának meghatározására. Az algoritmus a “QuickHull” vagy a “Delaunay-háromszögezés” alternatívájaként ismert, és gyakran nevezik “szalag algoritmusnak” (“Divide and Conquer”) a megközelítése miatt. Ez a módszer különösen hatékony, mivel időbonyolultsága (O(n n)).
Probléma definiálása
Adott (n) darab pont a kétdimenziós síkon, cél a pontok konvex burkának meghatározása. A konvex burok az a legkisebb konvex sokszög, amely tartalmazza az összes pontot.
Algoritmus működése
Az algoritmus a “divide and conquer” (oszd meg és uralkodj) stratégiát alkalmazza: 1. Rendezés: - Először a pontokat növekvő sorrendbe rendezi az (x)-koordináták szerint. 2. Felbontás: - Az algoritmus először meghatározza a konvex burok felső részét. - Majd külön az alsó részt számolja ki. 3. Felső konvex rész meghatározása: - Az (x)-tengely mentén felosztja a síkot egy középpontra (median). - Az alhalmazokból iteratív módon kiválasztja azokat a pontokat, amelyek hozzájárulnak a konvex burokhoz. 4. Összeállítás: - A felső és az alsó részt összeilleszti, így megkapjuk a teljes konvex burkot.
Az algoritmus hatékonysága abban rejlik, hogy a részek összeállítása lineáris időben történik.
Pszeudokód
function KirkpatrickSeidel(points): Rendezd a pontokat növekvő sorrendbe az x-koordinájuk alapján. oszd meg a pontokat bal és jobb alhalmazokra a medián alapján. Felső_burok = Meghatározza a konvex burok felső részét: - Kiválasztja a legfelső pontot, majd iteratív módon azokat a pontokat, amelyek kívül esnek az aktuális konvex burokon. Alsó_burok = Meghatározza a konvex burok alsó részét: - Hasonló eljárás az alsó rész kiszámítására. Térj vissza Felső_burok + Alsó_burok
Python implementáció
def cross_product(o, a, b):
"""Kereszttermék a pontok között: o a középpont."""
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
def kirkpatrick_seidel(points):
# Rendezés x-koordináták szerint
points = sorted(points)
# Felső konvex burok meghatározása
upper = []
for p in points:
while len(upper) >= 2 and cross_product(upper[-2], upper[-1], p) <= 0:
upper.pop()
upper.append(p)
# Alsó konvex burok meghatározása
lower = []
for p in reversed(points):
while len(lower) >= 2 and cross_product(lower[-2], lower[-1], p) <= 0:
lower.pop()
lower.append(p)
# A teljes konvex burok (az utolsó pontokat ne ismételjük meg)
return upper[:-1] + lower[:-1]
# Példa használat
points = [(0, 0), (1, 1), (2, 2), (3, 0), (0, 3), (3, 3)]
convex_hull = kirkpatrick_seidel(points)
print("Konvex burok pontjai:", convex_hull)
C++ implementáció
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
int x, y;
bool operator<(const Point& other) const {
return x < other.x || (x == other.x && y < other.y);
}
};
// Kereszttermék számítása
int crossProduct(Point o, Point a, Point b) {
return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}
// Kirkpatrick-Seidel algoritmus
vector<Point> kirkpatrickSeidel(vector<Point>& points) {
sort(points.begin(), points.end()); // Rendezés x szerint
// Felső konvex burok
vector<Point> upper;
for (const auto& p : points) {
while (upper.size() >= 2 && crossProduct(upper[upper.size() - 2], upper.back(), p) <= 0) {
upper.pop_back();
}
upper.push_back(p);
}
// Alsó konvex burok
vector<Point> lower;
for (auto it = points.rbegin(); it != points.rend(); ++it) {
while (lower.size() >= 2 && crossProduct(lower[lower.size() - 2], lower.back(), *it) <= 0) {
lower.pop_back();
}
lower.push_back(*it);
}
// Összesítés, az utolsó pontokat ne ismételjük meg
upper.pop_back();
lower.pop_back();
upper.insert(upper.end(), lower.begin(), lower.end());
return upper;
}
int main() {
vector<Point> points = {{0, 0}, {1, 1}, {2, 2}, {3, 0}, {0, 3}, {3, 3}};
vector<Point> convexHull = kirkpatrickSeidel(points);
cout << "Konvex burok pontjai:" << endl;
for (const auto& p : convexHull) {
cout << "(" << p.x << ", " << p.y << ")" << endl;
}
return 0;
}
Példa bemenet és kimenet
Bemenet
Pontok: ((0,0), (1,1), (2,2), (3,0), (0,3), (3,3))
Kimenet
Konvex burok pontjai: - Python: [(0, 0), (3, 0), (3, 3), (0, 3)]
- C++: (0, 0), (3, 0), (3, 3), (0, 3)
Összegzés
A Kirkpatrick-Seidel algoritmus előnye a hatékonysága ((O(n n))), valamint az egyszerű és logikus oszd-meg-és-uralkodj megközelítés. Ez különösen hasznos nagyobb pontkészletek esetén, például térinformatikai vagy számítógépes grafikai alkalmazásokban.
Fordítások
- Kirkpatrick-Seidel-algoritmus - Értelmező szótár (MEK)
- Kirkpatrick-Seidel-algoritmus - Etimológiai szótár (UMIL)
- Kirkpatrick-Seidel-algoritmus - Szótár.net (hu-hu)
- Kirkpatrick-Seidel-algoritmus - DeepL (hu-de)
- Kirkpatrick-Seidel-algoritmus - Яндекс (hu-ru)
- Kirkpatrick-Seidel-algoritmus - Google (hu-en)
- Kirkpatrick-Seidel-algoritmus - Helyesírási szótár (MTA)
- Kirkpatrick-Seidel-algoritmus - Wikidata
- Kirkpatrick-Seidel-algoritmus - Wikipédia (magyar)