¿Cuál es la lógica detrás del algoritmo de escaneo de Graham para casco convexo?

Para comprender la lógica de Graham Scan, debemos entender qué es Convex Hull:

¿Qué es el casco convexo?

Si tiene algunas uñas pegadas en un escritorio al azar y toma una banda elástica y se estira sobre todas las uñas. El límite formado naturalmente será un límite convexo. (El ángulo interno en cualquier punto no excede [matemática] 180 ° [/ matemática]).

La propiedad de este límite será que tendrá todos los demás puntos en el límite o dentro del límite.

Más formalmente,

Un casco convexo de un conjunto de puntos [matemática] X_ {i} \ en Q [/ matemática], de modo que es el conjunto convexo más pequeño que contiene [matemática] Q [/ matemática].

Algoritmo de escaneo de Graham

El algoritmo de escaneo de Graham primero elige un punto. Principalmente es un punto que tiene el valor más bajo del eje Y en el plano cartesiano (en caso de empate, elegimos el que tenga el valor más bajo del eje X.

La pregunta es ¿por qué? Por qué elegir un punto que es más bajo en el eje Y La razón es que este punto es seguro que estará en el límite (ver la imagen nuevamente).

Entonces, más formalmente, el escaneo Graham comienza con un punto que está en el límite del casco. Llamemos a este punto [matemáticas] P [/ matemáticas].

Este paso toma [matemáticas] O (n) [/ matemáticas], donde [matemáticas] n [/ matemáticas] es el número de puntos en cuestión.

Luego, el conjunto de puntos debe ordenarse en orden creciente del ángulo que ellos y el punto [matemático] P [/ matemático] forman con el eje x. Cualquier algoritmo de clasificación de propósito general es apropiado para esto, por ejemplo, heapsort (que es [math] O (n log n) [/ math]).

La pregunta aquí es ¿por qué estamos ordenando los puntos de acuerdo con el ángulo? Esto está oculto en el hecho de que elegimos el punto más bajo y el más a la izquierda. Entonces, cuando los puntos se ordenan según el ángulo con el eje x. Mientras escaneamos, pasaremos por cada punto y determinaremos si el punto puede estar en el límite o no.

La clasificación en orden de ángulo no requiere calcular el ángulo. Es posible utilizar cualquier función del ángulo que sea monotónica en el intervalo [matemática] [0, Ï €] {\ displaystyle [0, \ pi]} [/ matemática]. El coseno se calcula fácilmente usando el producto de puntos, o se puede usar la pendiente de la línea. Si la precisión numérica está en juego, la función de comparación utilizada por el algoritmo de clasificación puede usar el signo del producto cruzado para determinar los ángulos relativos.

El algoritmo procede considerando cada uno de los puntos en la matriz ordenada en secuencia. Para cada punto, primero se determina si viajar desde los dos puntos inmediatamente anteriores a este punto constituye un giro a la izquierda o un giro a la derecha. Si gira a la derecha, el penúltimo punto no forma parte del casco convexo y se encuentra “dentro” de él.

Fig: 2 [1] Como se puede ver, PAB y ABC son en sentido antihorario, pero BCD no. El algoritmo detecta esta situación y descarta los segmentos previamente elegidos hasta que el turno tomado sea en sentido antihorario (ABD en este caso).

Luego se hace la misma determinación para el conjunto del último punto y los dos puntos que preceden inmediatamente al punto encontrado dentro del casco, y se repite hasta que se encuentra un conjunto de “giro a la izquierda”, momento en el cual el algoritmo se mueve al siguiente punto en el conjunto de puntos en la matriz ordenada menos cualquier punto que se encuentre dentro del casco; no hay necesidad de considerar estos puntos nuevamente.

Esta es la intuición detrás del Graham Scan. A continuación se muestra un pseudocódigo para el mismo: [2]

Entrada: un conjunto de puntos S = {P = (Px, Py)}

Seleccione el punto más bajo más a la derecha P0 en S
Ordenar S radialmente (ccw) sobre P0 como centro
{
Utilice las comparaciones isLeft ()
Para los empates, descarte los puntos más cercanos
}
Sea P [N] el conjunto ordenado de puntos con P [0] = P0

Empuje P [0] y P [1] en una pila

mientras yo <N
{
Deje PT1 = el punto superior en
If (PT1 == P [0]) {
Presione P [i] en
i ++ // incremento i
}
Deje PT2 = el segundo punto superior en
Si (P [i] queda estrictamente a la izquierda de la línea PT2 a PT1) {
Presione P [i] en
i ++ // incremento i
}
más
Saque el punto superior PT1 de la pila
}

Salida: O = el casco convexo de S.

Espero que ayude.

Salud.

Notas al pie

[1] Archivo: Graham Scan.svg – Wikipedia

[2] El casco convexo de un conjunto de puntos planos

La exploración de Graham es un método para encontrar el casco convexo de un conjunto finito de puntos en el plano con complejidad temporal O ( n log n ). Lleva el nombre de Ronald Graham, quien publicó el algoritmo original en 1972.

El algoritmo encuentra todos los vértices del casco convexo ordenados a lo largo de su límite. Utiliza una pila para detectar y eliminar concavidades en el límite de manera eficiente.

Algoritmo

Como se puede ver, PAB y ABC son en sentido antihorario, pero BCD no. El algoritmo detecta esta situación y descarta los segmentos previamente elegidos hasta que el turno tomado sea en sentido antihorario (ABD en este caso).

El primer paso en este algoritmo es encontrar el punto con la coordenada y más baja. Si la coordenada y más baja existe en más de un punto del conjunto, se debe elegir el punto con la coordenada x más baja de los candidatos. Llame a este punto P. Este paso toma O ( n ), donde n es el número de puntos en cuestión.

A continuación, el conjunto de puntos debe ordenarse en orden creciente del ángulo que ellos y el punto P forman con el eje x. Cualquier algoritmo de clasificación de propósito general es apropiado para esto, por ejemplo, heapsort (que es O ( n log n )).

La clasificación en orden de ángulo no requiere calcular el ángulo. Es posible utilizar cualquier función del ángulo que sea monotónica en el intervalo [matemática] {\ displaystyle [0, \ pi]} [/ matemática]. El coseno se calcula fácilmente usando el producto de puntos, o se puede usar la pendiente de la línea. Si la precisión numérica está en juego, la función de comparación utilizada por el algoritmo de clasificación puede usar el signo del producto cruzado para determinar los ángulos relativos.

El algoritmo procede considerando cada uno de los puntos en la matriz ordenada en secuencia. Para cada punto, primero se determina si viajar desde los dos puntos inmediatamente anteriores a este punto constituye un giro a la izquierda o un giro a la derecha. Si gira a la derecha, el penúltimo punto no forma parte del casco convexo y se encuentra “dentro” de él. Luego se hace la misma determinación para el conjunto del último punto y los dos puntos que preceden inmediatamente al punto encontrado dentro del casco, y se repite hasta que se encuentra un conjunto de “giro a la izquierda”, momento en el cual el algoritmo se mueve al siguiente punto en el conjunto de puntos en la matriz ordenada menos cualquier punto que se encuentre dentro del casco; no hay necesidad de considerar estos puntos nuevamente. (Si en algún momento los tres puntos son colineales, uno puede optar por descartarlo o informarlo, ya que en algunas aplicaciones se requiere encontrar todos los puntos en el límite del casco convexo).

Nuevamente, determinar si tres puntos constituyen un “giro a la izquierda” o un “giro a la derecha” no requiere calcular el ángulo real entre los dos segmentos de línea, y en realidad solo se puede lograr con la aritmética simple. Por tres puntos [matemáticas] {\ displaystyle P_ {1} = (x_ {1}, y_ {1})} [/ matemáticas], [matemáticas] {\ displaystyle P_ {2} = (x_ {2}, y_ { 2})} [/ math] y [math] {\ displaystyle P_ {3} = (x_ {3}, y_ {3})} [/ math], calcula la coordenada z del producto cruzado de los dos vectores [matemática] {\ displaystyle {\ overrightarrow {P_ {1} P_ {2}}}} [/ math] y [math] {\ displaystyle {\ overrightarrow {P_ {1} P_ {3}}}} [/ math ], que viene dada por la expresión [matemáticas] {\ displaystyle (x_ {2} -x_ {1}) (y_ {3} -y_ {1}) – (y_ {2} -y_ {1}) (x_ {3} -x_ {1})} [/ matemáticas]. Si el resultado es 0, los puntos son colineales; si es positivo, los tres puntos constituyen un “giro a la izquierda” u orientación en sentido antihorario, de lo contrario un “giro a la derecha” u orientación en sentido horario (para puntos numerados en sentido antihorario).

Este proceso finalmente regresará al punto en el que comenzó, en ese punto el algoritmo se completa y la pila ahora contiene los puntos en el casco convexo en el sentido contrario a las agujas del reloj.