Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo minimizar la suma de distancias de un punto a otros dos puntos en el plano

Cómo minimizar la suma de distancias de un punto a otros dos puntos en el plano

¿Cómo "minimizar la suma de distancias desde un punto a todos los demás puntos del espacio"? Primero formalice el problema:

?Código de fórmula:

min f(x, y) = \min \sum_i \sqrt {(x - x_i)^2 (y - y_i ) ^2}

De lo que estamos hablando aquí es de la suma de distancias, no de la suma de cuadrados. El criterio de evaluación en el agrupamiento de kmeans es la suma de cuadrados. Si solo hay un centro de clase, entonces la derivada parcial se puede tomar directamente y el punto que minimiza la suma de cuadrados es el centro. Este punto es el centro. El problema aquí es diferente a la solución de la suma de cuadrados. Por ejemplo, el punto del triángulo con la suma más corta de las distancias entre los tres vértices es el punto de Fermat.

Esto se puede resolver utilizando la "búsqueda" en los métodos de optimización, incluido el descenso de gradiente, el método de Newton y el método de gradiente conjugado. En este caso, se utiliza el descenso de gradiente. El descenso de gradiente es el más fácil de usar aquí y puedo ver por qué es el método más utilizado en la práctica. En comparación con el método de descenso de gradiente, el método de Newton requiere una matriz de Hesse y es mucho más engorroso. El paso de búsqueda del método de descenso de gradiente es avanzar un paso (variable) en la dirección opuesta a la derivada de la variable independiente, donde la dirección de la derivada es

Fórmula código:

abla f(x, y) =

izquierda[

begin{array} {lcr}

\ displaystyle \ suma_i \frac{x - x_i} {sqrt{(x - x_i)^2 (y - y_i)^2pan gt;}}\

\displaystyle \sum_i \frac{y - y_i}{sqrt {(x - x_i)^2 (y - y_i)^2pan 2}}

\end{array}

\right]

El descenso de gradiente puede También se puede utilizar en lugares más difíciles, es decir, es difícil elegir el tamaño del paso, y los ejemplos dados en los libros de texto generalmente se presentan para cálculos de pasos variables con expresiones más simples. En este problema, el tamaño del paso se toma como un valor fijo por simplicidad.

Todo se implementó en Python 3 (al principio quería hacerlo en R, pero R no pudo depurar... todo se reduce a falta de habilidades), combinando los paquetes scipy y matplotlib, y los resultados parecen sólidos:

Finalmente, adjunte el código fuente:

Lenguaje Python 3: código resaltado proporcionado por germination.com

de scipy import *

importar pylab

def f(p, pts):

return sum(sum((p - pts) ** 2, eje=1) ** 0.5)

def fd(p, pts):

dx = suma((p[0] - pts[:, 0]) / suma((p - pts) ** 2, eje= 1 ) ** 0.5)

dy = suma((p[1] - pts[:, 1]) / suma((p - pts) ** 2, eje=1) ** 0.5)

s = (dx ** 2 dy ** 2) ** 0.5

brgt; dx /= s

dy /= s

return array([dx, dy])

pts = rand(10, 2)

x = array([0, 0])

t = 0,1

xpaso = x

para k en el rango(100):

y = f(x, pts)

xk = x - t * fd(x, pts)

yk = f(xk, pts)

si y - yk gt; >x = xk

y = yk

elif yk - y gt 1e-8:

t *= 0.5

else; :

romper

xstep = vstack((xstep, x))

imprimir(x, y)

pylab.plot ( pts[:, 0], pts[:, 1], 'bo')

pylab.plot(xstep[:, 0], xstep[:, 1], 'ro')

p>

pylab.plot(xstep[:, 0], xstep[:, 1], 'k- ')

pylab.xlabel('iter = d, Min = .3f, p = (.3f, .3f), t = f' (k, y, x[0], x[1], t))

pylab.show()