Решение
Вот полный рабочий пример для точек крепления вида (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)