Estoy trabajando en una lógica vectorial, por lo que pregunto: ¿puedo ahorrar tiempo en el procesador al simplificar esta desigualdad?
distance(vector1, vector2) < distance(vector1, vector3)
Veo que vector1
se repite en ambos casos.
Estoy trabajando en una lógica vectorial, por lo que pregunto: ¿puedo ahorrar tiempo en el procesador al simplificar esta desigualdad?
distance(vector1, vector2) < distance(vector1, vector3)
Veo que vector1
se repite en ambos casos.
Respuestas:
Sí , puedes simplificar esto. Primero, deja de llamarlos vectores. Son puntos. Llamémosles A
, B
y C
.
Entonces, quieres esto:
dist(A, B) < dist(A, C)
Reemplazar distancias con distancias al cuadrado, luego con productos de punto (de la definición de la longitud euclidiana . Reemplazar AC
con AB + BC
(ahora estos son vectores reales). Expandir, simplificar, factorizar:
dist(A, B)² < dist(A, C)²
dot(AB, AB) < dot(AC, AC)
dot(AB, AB) < dot(AB + BC, AB + BC)
dot(AB, AB) < dot(AB, AB) + dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC + 2 AB, BC)
Ahí tienes:
dot(AB + AC, BC) > 0
Con su notación vectorial:
dot(v2 - v1 + v3 - v1, v3 - v2) > 0
Esas son algunas adiciones y un producto de punto en lugar de los dos productos de punto anteriores.
dist(A, B)²
es igual dot(AB, AB)
, proviene de la definición misma de la longitud euclidiana .
Si. Suponiendo que su distance
función usa una raíz cuadrada, puede simplificar esto quitando la raíz cuadrada.
Cuando se trata de encontrar la distancia más grande (o más pequeña), x^2 > y^2
sigue siendo válido para x > y
.
Sin embargo, otros intentos de simplificar matemáticamente la ecuación probablemente no tengan sentido. La distancia entre vector1
y vector2
no es la misma que la distancia entre vector1
y vector3
. Si bien la ecuación se puede simplificar matemáticamente como muestra la respuesta de Sam , la forma en que se encuentra actualmente es tan simple como la que se obtiene desde la perspectiva del uso del procesador.
Algunas matemáticas podrían ayudar.
Lo que estás tratando de hacer es:
<v1, v2> < <v1, v3> =>
sqrt((y2-y1)^2+(x2-x1)^2) < sqrt((y3-y1)^2+(x3-x1)^2) =>
y2^2 - 2*y2y1 + y1^2 + x2^2 - 2*x2x1 + x1^2 < y3^2 - 2*y3y1 + y1^2 + x3^2 - 2*x3x1 + x1^2
De lo que puede eliminar variables repetidas y agrupar algunas otras. La operación que debe verificar es:
y3^2 - y2^2 - 2*y1(y3-y2) + x3^2 - x2^2 - 2*x1(x3-x2) > 0
Espero eso ayude.
La verdadera pregunta parece ser cómo reducir el cálculo para determinar el objeto más cercano.
La optimización de esto a menudo se realiza en los juegos, aunque con todas las optimizaciones debe guiarse por el perfil y, a menudo, no simplifica las cosas.
La forma de evitar cálculos de distancia innecesarios para determinar la cosa más cercana, o todas las cosas dentro de un cierto rango, es usar un índice espacial, por ejemplo, un octree .
Esto solo vale la pena si hay una gran cantidad de objetos. Por solo tres objetos, es poco probable que valga la pena y ciertamente no simplifica el código.
depende de cuál es la salida de distancia (v1, v2)
Si es un decimal (flotante o doble) sobre un vector, es probable que la distancia al cuadrado sea mucho más rápida
float
tiene que ver eso con nada.