lunes, 13 de julio de 2026

Vértice de un n-paralelepípedo más cercano a un punto. Algoritmo de Babai.

 En una entrada anterior planteé el siguiente problema:

 Sea $\mathcal{F}$ un n-paralelepípedo (sólido) generado por el conjunto de vectores linealmente independientes $B = \{\vec{b}_1,...,\vec{b}_n\}$. Sea $P\in\mathcal{F}$ un punto de dicho n-paralelepípedo. ¿Cuál es el vértice del n-paralelepípedo más cercano a $P$?

Expliqué y ejemplifiqué una posible estrategia consistente en el método exhaustivo, es decir, comprobar todos los posibles vértices. Concluí la entrada con la observación de que el número de vértices crece de manera exponencial con la dimensión y esto supone un problema de coste computacional en dimensiones grandes.

En esta entrada vamos a trabajar otra posible estrategia, basada en el algoritmo de Babai, desarrollado por el matemático húngaro László Babai.

El fundamento detrás del procedimiento es relativamente sencillo.

Si $P\in\mathcal{F}$ entonces $P$ se puede escribir como combinación lineal de la base $B$:

$$P = \sum_{i=1}^{n}{a_i·\vec{b}_i}$$

Lo que hacemos es redondear al entero los coeficientes $0 \leq a_i \leq 1$ de la combinación lineal:

$$z_i = redondear(a_i)$$

Entonces, el vértice del n-paralelepípedo más próximo a $P$ viene dado por:

$$V = \sum_{i=1}^{n}{z_i·\vec{b}_i}$$

 

Ejemplo: Hagamos este método con el mismo ejemplo que utilizamos en el método exhaustivo, en $\mathbb{R}^2$.

$B=\{(30, 3), (5, 0)\}$ y el punto del paralelogramo $Q=(25.5, 2.5)$. Queremos hallar el vértice del paralelogramo más cercano a $Q$.

 Primero calcularemos la combinación lineal de la base $B$ que da el punto $Q$:

$$\vec{a} = B^{-1} · \overrightarrow{OQ} =\begin{pmatrix}30 & 5\\3 & 0\end{pmatrix}^{-1} · \begin{pmatrix}25.5 \\ 2.5\end{pmatrix} \simeq \begin{pmatrix}0.8333333333333333 \\ 0.10000000000000053\end{pmatrix}$$

Ahora redondeamos los coeficientes obtenidos:

$$\vec{z} = \begin{pmatrix}1 \\ 0\end{pmatrix}$$

Y calculamos a qué vértice corresponde dicha combinación lineal:

$$\overrightarrow{OV} = B · \vec{z} = \begin{pmatrix}30 & 5\\3 & 0\end{pmatrix} · \begin{pmatrix}1 \\ 0\end{pmatrix} = \begin{pmatrix}30 \\ 3\end{pmatrix}$$

Es decir, el vértice más cercano al punto $Q$ es (30, 3). (Coincide con el obtenido por el método exhaustivo)

Los cálculos del ejemplo han sido realizados con wxMaxima:

 

Desde un punto de vista geométrico e informal podríamos decir que el procedimiento anterior es equivalente a dividir con "hiperplanos medianeros" el n-paralelepípedo y seleccionar el vértice del "trozo" en el que queda el punto.

 

 El algoritmo de Babai rebaja considerablemente el coste computacional, dado que no necesita recorrer todos los vértices del n-paralelepípedo y se basa en operaciones bastante rápidas desde el punto de vista del cálculo computacional.

Sin embargo, el algoritmo de Babai presenta un gran problema: solo en determinadas condiciones la solución que devuelve es la correcta.

Veamos esto con un ejemplo. Seguimos utilizando la misma base que en el ejemplo anterior, pero cambiamos el punto a "aproximar" (encontrar el vértice más cercano) por $R=(30, 2.7)$.

Los cálculos del algoritmo devuelven el vértice $(35, 3)$ como el más cercano al punto $R$.

 

Sin embargo, esto no es cierto. El vértice más cercano es claramente el $(30, 3)$. 

 

Puede observarse en la representación gráfica que, tras trazar las medianas, el punto cae en el "trozo" del vértice $(35, 3)$ y por eso es la respuesta que devuelve el algoritmo de Babai. Pero no es el vértice más cercano.

Llegados a este punto lo razonable es descartar por completo este algoritmo porque ni tan siquiera devuelve la solución correcta.

Sin embargo, el algoritmo sí funciona con fiabilidad cuando la base es ortogonal (o "cerca" de ser ortogonal).

¿Y esto tiene alguna utilidad práctica? Habrá que esperar a las siguientes entradas para averiguarlo. 

Razón de ortogonalidad de Hadamard con Python

 En una entrada anterior hablé sobre la razón de ortogonalidad de Hadamard:

$$H(B) = \sqrt[n]{\frac{|det(B)|}{\prod_{i=1}^{n}\|\vec{b}_i\|}} $$

Podemos realizar un script en Python para calcular dicha razón, utilizando la librería NumPy:

import numpy as np

def razon_hadamard(B):
    # Calculamos el valor absoluto del determinante de la matriz
    det = np.abs(np.linalg.det(B))
    # Si el determinante es 0 la matriz no es una base y la función devuelve 0
    if not det:
        return 0
    n = len(B)
    # Definimos una variable prod_norm que calcula el producto de la norma de cada vector (columna)
    prod_norm = np.prod(np.linalg.norm(B, axis=0))
    # Devolvemos la razón
    return (det / prod_norm) ** (1/n) 

 

By www.python.org - www.python.org, GPL,

 https://commons.wikimedia.org/w/index.php?curid=34991651


 

domingo, 12 de julio de 2026

Vértice de un n-paralelepípedo más cercano a un punto. Método exhaustivo.

 

Sea $\mathcal{F}$ un n-paralelepípedo (sólido) generado por el conjunto de vectores linealmente independientes $B = \{\vec{b}_1,...,\vec{b}_n\}$. Sea $P\in\mathcal{F}$ un punto de dicho n-paralelepípedo. ¿Cuál es el vértice del n-paralelepípedo más cercano a $P$?

 Estrategia 1. Método exhaustivo.

Podemos calcular las coordenadas de todos los vértices del n-paralelepípedo.

Por ejemplo, en $\mathbb{R}^3$, los 8 vértices del paralelepípedo son:

$V_1 = \vec{0} = (0,0,0)$

$V_2 = \vec{b}_1$

$V_3 = \vec{b}_2$

$V_4 = \vec{b}_3$

$V_5 = \vec{b}_1 + \vec{b}_2$

$V_6 = \vec{b}_1 + \vec{b}_3$

$V_7 = \vec{b}_2 + \vec{b}_3$

$V_8 = \vec{b}_1 + \vec{b}_2 + \vec{b}_3$ 

Después calculamos la distancia de cada uno de ellos al punto $P$

$$d_i = \|P-V_i\|$$ 

 Y nos quedamos con el que tenga menor distancia (puede haber más de uno).

 

Ejemplo: Hagamos este método con un caso muy sencillo en $\mathbb{R}^2$.

$B=\{(30, 3), (5, 0)\}$ y el punto del paralelogramo $Q=(25.5, 2.5)$. Queremos hallar el vértice del paralelogramo más cercano a $Q$.

Los vértices del paralelogramo son:

$V_1=(0, 0); V_2=(30, 3); V_3=(5, 0); V_4=(35, 3)$

Y las correspondientes distancias al punto $Q$:

$d_1 \simeq 25.622255950637914$

$d_2 \simeq 4.527692569068709$

$d_3 \simeq 20.65187642806338$

$d_4 \simeq 9.513148795220223$ 

Por tanto, el vértice con menor distancia al punto $Q$ es $V_2=(30, 3)$.

 

Los cálculos han sido realizados con wxMaxima:

 

Contras del método exhaustivo.

Para dimensiones pequeñas el método exhaustivo es rápido y muy eficiente, pero para dimensiones grandes el coste computacional se incrementa exponencialmente, dado que el número de vértices de un n-paralelogramo es $2^n$.

Por ejemplo, en $\mathbb{R}^{100}$ tenemos $2^{100} = 1267650600228229401496703205376$ vértices.