python - 使用 CVXPY 的解决方案不一致
问题描述
请考虑以下优化问题。具体来说,x
和b
是(1,n)
向量,C
是(n,n)
对称矩阵,k
是任意常数并且i
是 1 的(1,n)
向量。
请同时考虑以下等效优化问题。在这种情况下,k
在优化过程中确定,因此无需按比例缩放值x
来获得解y
。
请同时考虑以下代码来解决cvxpy
.
import cvxpy as cp
import numpy as np
def problem_1(C):
n, t = np.shape(C)
x = cp.Variable(n)
b = np.array([1 / n] * n)
obj = cp.quad_form(x, C)
constraints = [b.T @ cp.log(x)>=0.5, x >= 0]
cp.Problem(cp.Minimize(obj), constraints).solve()
return (x.value / (np.ones(n).T @ x.value))
def problem_2(C):
n, t = np.shape(C)
y = cp.Variable(n)
k = cp.Variable()
b = np.array([1 / n] * n)
obj = cp.quad_form(y, C)
constraints = [b.T @ cp.log(y)>=k, np.ones(n)@y.T==1, y >= 0]
cp.Problem(cp.Minimize(obj), constraints).solve()
return y.value
虽然第一个函数确实为我正在使用的一组数据样本提供了正确的解决方案,但第二个函数却没有。具体来说,在y
使用第二个函数时,其中一些值为零(这不可能,因为所有值b
都是正数且大于零)。我想知道第二个函数是否也最小化k
。它的值不应该被最小化,相反,它应该在优化问题期间被确定为导致目标函数最小化的解决方案。
更新_1
我刚刚发现,我用问题的第二个公式得到的解等于用以下方程和函数得出的解。似乎k
忽略了对数障碍和变量的约束。
def problem_3(C):
n, t = np.shape(C)
y = cp.Variable(n)
k = cp.Variable()
b = np.array([1 / n] * n)
obj = cp.quad_form(y, C)
constraints = [np.ones(n)@y.T==1, y >= 0]
cp.Problem(cp.Minimize(obj), constraints).solve()
return y.value
更新_2
这是示例输入的链接C
- https://www.dropbox.com/s/kaa7voufzk5k9qt/matrix_.csv?dl=0。在这种情况下,两者的正确输出problem_1
和problem_2
大约等于,[0.0659 0.068 0.0371 0.1188 0.1647 0.3387 0.1315 0.0311 0.0441]
因为它们在定义上是等效的。我只能通过求解来获得正确的输出problem_1
。解决problem_2
哪个[0.0227 0. 0. 0.3095 0.3392 0.3286 0. 0. 0. ]
是错误的,因为它恰好是problem_3
.
更新_3
需要明确的是,根据定义,problem_2
解等于problem_3
参数k
变为负无穷大时的解。
UPDATE_4
problem_1
请考虑以下使用 SciPy Optimize 代替 CVXPY求解的代码。通过施加k=9
正确的最优解仍然可以达到与problem_1
参数无关的一致。
import scipy.optimize as opt
def obj(x, C):
return x.T @ C @ x
def problem_1_1(C):
n, t = np.shape(C)
b = np.array([1 / n] * n)
constraints = [{"type": "eq", "fun": lambda x: (b * np.log(x)).sum() - 9}]
res = opt.minimize(
obj,
x0 = np.array([1 / n] * n),
args = (C),
bounds = ((0, None),) * n,
constraints = constraints
)
return (res['x'] / (np.ones(n).T @ res['x']))
UPDATE_5
通过考虑 UPDATE_4 中的代码,只要k
设置为 10,仍然可以实现正确的解决方案,但是会出现以下警告。我想这是由于优化过程中可能出现的舍入误差。
Untitled.py:56: RuntimeWarning: divide by zero encountered in
log {"type": "eq", "fun": lambda x: (b * np.log(x)).sum() - 10}
我想知道是否有办法对 CVXPY 施加严格的不等式约束或在对数参数上应用条件。请考虑以下修改后的代码problem_1_1
。
import scipy.optimize as opt
def obj(x, C):
return x.T @ C @ x
def problem_1_1(C):
n, t = np.shape(C)
b = np.array([1 / n] * n)
constraints = [{"type": "eq", "fun": lambda x: (b * np.log(x if x.all() > 0 else 1e-100)).sum() - 10}]
res = opt.minimize(
obj,
x0 = np.array([1 / n] * n),
args = (C),
bounds = ((0, None),) * n,
constraints = constraints
)
return (res['x'] / (np.ones(n).T @ res['x']))
UPDATE_6
彻底地说,最佳值的正确值k
是近似的-2.4827186402337564
。
解决方案
如果您让任意,那么您基本上是在说 大于或等于某个任意数字,这是微不足道的,因此约束变得无关紧要。
我相信你应该通过确定maximizing和minimize 之间的权衡来解决这个问题或将这个问题变成一个minimax 问题。
推荐阅读
- c - 如何通过C编程实时获取本地监听端口?
- google-sheets - 如何创建一个运行总计公式,当新行添加到我的电子表格时自动扩展
- azure - 是否可以在 Azure 仪表板中嵌入 PowerBi 报告
- sql - 多列连接成一列 SQL
- c# - 在 C# 中使用套接字
- c# - 从 4 个球体中获取 X、Y、Z 位置
- facebook-graph-api - 使用 Facebook Instagram API business_discovery 获取特定媒体的 like_count 和 comments_count
- python - 具有固定域的整数非线性优化(重新编辑)
- sql-server - 用于备份数据库的 sql server SSMS 与 ODBC 的不同行为
- caching - 如何在没有构造函数的 Asp.Net core 2 中使用内存缓存