#python #optimization #scipy #constraints
Вопрос:
У меня следующая проблема: я пытаюсь создать матрицу , которая будет отображать точку a_i -> b_i
, одновременно гарантируя, что все остальные точки из пространства A
будут сопоставлены с точками внутри пространства B
. Сложность в том, что я использую функцию linprog, чтобы проверить, находится ли точка в пространстве, и это возвращает логическое значение, поэтому я не уверен, как использовать это в качестве ограничения при оптимизации.
Вот мои соответствующие функции, очищенные:
def x_to_matrix(x):
n = round(np.sqrt(len(x)))
return np.array(x).reshape((n, n))
def matrix_to_vector(M):
return M.flatten()
def check_point_within_polytope(point, polytope_points):
"""Uses linprog to check if a point can be decomposed as a convex sum of other points. The `c` vector is null, and `A` gives the basis points together with the requirement that `x` sums to 1"""
number_of_points = len(polytope_points)
dim = len(polytope_points[0])
c = np.zeros(number_of_points)
A = np.r_[np.array(polytope_points).T, np.ones((1, number_of_points))]
b = np.r_[point, np.ones(1)]
lp = linprog(c, A_eq=A, b_eq=b)
return lp.success
def make_T(local_points, target_points):
"""Challenge here is as follows. We want to create a matrix which maps a particular local point to a particular target point. At the same time, we want to make sure that the matrix maps all other points from the local space into the target space.
The difficulty in creating this in enacting these constraints. The way we check that a point is within a space is using linprog, which returns a Boolean rather than numerical result. """
target_space = target_points local_points
target_point = target_points[0]
local_point = local_points[0]
def function_for_T(x):
M = x_to_matrix(x)
new_point = np.dot(M, local_point)
return np.linalg.norm(target_point - new_point)
def check_local_point_happy(x, local_point):
M = x_to_matrix(x)
new_point = np.dot(M, local_point)
return check_point_within_polytope(new_point, target_space)
nonlinear_constraints = []
for local_point in local_points:
fun_here = lambda x: check_local_point_happy(x, local_point)
nonlinear_constraints = NonlinearConstraint(fun_here, )
X0 = matrix_to_vector(np.eye(len(target_point)))
sol = minimize(function_for_T, method='SLSQP', x0=X0, constraints=nonlinear_constraints)
return sol
Есть ли какой-то способ использовать мою check_point_within_polytope
функцию в качестве нелинейного ограничения? Или, в качестве альтернативы, есть какой-то гораздо лучший способ сделать это? Такое ощущение, что так и должно быть, поскольку ограничения, в конечном счете, линейны.
Любая помощь очень ценится!
Комментарии:
1. Я бы добавил это линейное ограничение непосредственно в NLP вместо использования отдельного LP. У хороших решателей НЛП нет проблем с линейными ограничениями. (У Scipy нет хороших решателей НЛП с ограничениями: я никогда, никогда не использую его ни для чего, кроме проблем с игрушками).
2. @ErwinKalvelagen можете ли вы порекомендовать решатель NLP для python?
3. Кроме того, я бы не знал, как закодировать их как линейные ограничения для решателя НЛП. Ограничения заключаются в том, что матрица, сформированная путем
x
отправки каждого элемента набора точек в подпространство, образованное выпуклой оболочкой другого набора точек. Я думаю, что для проверки этого требуется своя проблема оптимизации, которая у меня есть с linprog. Мне не хватает более простого способа сделать это?4. Я, может быть, ошибаюсь, но если B является константой, а b (новая точка) является переменной, то мы должны обеспечить это
b[j] = sum(i, w[i]*B[i,j])
w
между 0 и 1 и суммировать до 1. Это может быть добавлено в качестве линейных ограничений к исходному НЛП. Вполне возможно, что я здесь ошибаюсь. Я бы начал с написания правильной математической модели. Это может помочь в рассуждениях об этом. Ваша идея вызвать решатель LP изнутри не кажется мне осуществимым подходом (для этого потребуется правильная схема декомпозиции).