Нахождение минимального пространственного расстояния
Задача состоит в том, чтобы найти такую точку с координатами (x,0), чтобы расстояние от нее до наиболее удаленной точки от исходного набора (евклидово расстояние) было минимальным. Моя идея - найти минимум функции, которая находит евклидово расстояние, например:
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
from scipy.optimize import minimize
def function_3(points_x, points_y):
dots = np.array([points_x,points_y])
ans = minimize(cdist(dots,points1),x0=0)
return(ans)
Но похоже, что я делаю что-то не так... Может кто-нибудь дать совет?
1 ответ
Решение
Вот полный рабочий пример для примерочных точек формы (x, 0)
:
from scipy.spatial.distance import cdist
from scipy.optimize import minimize
# set up a test set of 100 points to fit against
n = 100
xyTestset = np.random.rand(n,2)*10
def fun(x, xycomp):
# x is a vector, assumed to be of size 1
# cdist expects a 2D array, so we reshape xy into a 1x2 array
xy = np.array((x[0], 0)).reshape(1, -1)
return cdist(xy, xycomp).max()
fit = minimize(fun, x0=0, args=xyTestset)
print(fit.x)
какие выводы:
[5.06807808]
Это означает, грубо говоря, что минимизация находит центр тяжести множества случайных контрольных точек, как и ожидалось. Если вы хотите сделать подгонку 2D к точкам формы (x, y)
вместо этого вы можете сделать:
from scipy.spatial.distance import cdist
from scipy.optimize import minimize
# set up a test set of 100 points to fit against
n = 100
xyTestset = np.random.rand(n,2)*10
def fun(x, xycomp):
# x is a vector, assumed to be of size 2
return cdist(x.reshape(1, -1), xycomp).max()
fit = minimize(fun, x0=(0, 0), args=xyTestset)
print(fit.x)
какие выводы:
[5.21292828 5.01491085]
что, опять же, примерно в центре тяжести из 100 случайных точек в xyTestset
, как и следовало ожидать.
Полное объяснение
Проблема, с которой вы сталкиваетесь, заключается в том, что scipy.optimize.minimize
имеет очень конкретные ожидания относительно формы своего первого аргумента fun
, fun
должна быть функция, которая принимает x
в качестве первого аргумента, где x
является одномерным вектором значений, которые будут минимизированы. fun
также могут принимать дополнительные аргументы. Они должны быть сведены к минимуму через args
параметр, и их значения постоянны (т.е. они не изменятся в течение минимизации).
Кроме того, вы должны знать, что ваш случай подгонки (x, 0)
можно упростить По сути, это одномерная задача, поэтому все, что вам нужно сделать, - это рассчитать x-расстояние между точками. Вы можете полностью игнорировать расстояния y и при этом получить те же результаты.
Кроме того, вам не нужна минимизация для решения указанной вами проблемы. Точка, которая минимизирует расстояние до самой дальней точки (то же самое, что сказать "минимизация расстояния до всех точек"), является центроидом. Координаты центроида являются средними значениями каждой координаты в вашем наборе точек, поэтому, если ваши точки хранятся в массиве Nx2 xydata
Вы можете рассчитать центроид, просто выполнив:
xydata.mean(axis=1)