- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想最小化实现一组给定的非负整数值 b 的成本,这些非负整数值 b 是从 GEKKO 中的两组非负整数变量 x、y 线性计算出来的。
如果以某种方式说明了我的问题,则 b 是 x 和 y 的约束。我的成本函数是非线性的:使用条件/最小值的二次方。除了这些标准约束之外,我还有一个约束,它要求 x 中非零元素的数量至少与 x 中的最大元素一样大(例如,L0 范数等于 LInifity 范数)。
我现在的困难是双重的,因为我对优化还很陌生,而且是 GEKKO 的新手。
from gekko import GEKKO
import numpy as np
# Setup gekko (taken from their MINLP tutorial with more iterations).
m = GEKKO()
m.options.SOLVER = 1 # APOPT is an MINLP solver
m.solver_options = ('minlp_maximum_iterations 500',
'minlp_max_iter_with_int_sol 10',
'minlp_as_nlp 0',
'nlp_maximum_iterations 50',
'minlp_branch_method 1',
'minlp_integer_tol 0.05',
'minlp_gap_tol 0.01')
# Define variables as arrays.
y = m.Array(m.Var, (7), value=1, lb=1, ub=12, integer=True)
x = m.Array(m.Var, (18), value=0, lb=0, ub=8, integer=True)
# Example of the user-defined target values b as constraints (actually input args).
m.Equation(x[2] + y[1] == 7)
m.Equation(x[12] + y[2] == 5)
# This is the L0 constraint.
# I thought using m.Array would make this a nice definition like
# m.Equation(np.count_nonzero(x) >= np.max(x))
# but it didn't, since these numpy functions are not supported in GEKKO.
# So I defined the following , which feels wrong:
m.Equation(m.sum([int(x_i.value > 0) for x_i in x]) >= max(x_i.value for x_i in x))
# Finally, the objective function (intermediates for readability).
k = np.array([m.min2(y_i, 3) for y_i in y])
x_cost = m.Intermediate(m.sum(x * (x + 1)))
y_cost = m.Intermediate(m.sum((k - 1) * (k + 2) + 2.5 * (y - k) * (y + k - 3)))
m.Obj(x_cost + y_cost)
# Solve.
m.solve(disp=True, debug=True)
最佳答案
Gekko 使用基于梯度的求解器,因此方程不应随迭代而改变。有一种方法可以获得与基于梯度的求解器兼容的非零变量的计数。这是另一种形式,可为您提供 x
的计数和最大值。向量。这使用 if3
, max3
, 和 min3
如在 documentation on Model Building Functions with logical conditions 中找到的.
from gekko import GEKKO
import numpy as np
# Setup gekko (taken from their MINLP tutorial with more iterations).
m = GEKKO(remote=False)
# Define variables as arrays.
y = m.Array(m.Var, (7), value=1, lb=1, ub=12, integer=True)
x = m.Array(m.Var, (18), value=0, lb=0, ub=8, integer=True)
# Example of the user-defined target values b as constraints (actually input args).
m.Equation(x[2] + y[1] == 7)
m.Equation(x[12] + y[2] == 5)
# This is the L0 constraint.
# m.Equation(np.count_nonzero(x) >= np.max(x))
eps = 0.05 # decision point for a "zero" value
count = m.sum([m.if3(x_i-eps,0,1) for x_i in x])
max_x = 0
for x_i in x:
max_x = m.Intermediate(m.max3(max_x,x_i))
m.Equation(count >= max_x)
# Finally, the objective function (intermediates for readability).
k = np.array([m.min3(y_i, 3) for y_i in y])
x_cost = m.Intermediate(m.sum(x * (x + 1)))
y_cost = m.Intermediate(m.sum((k - 1) * (k + 2) + 2.5 * (y - k) * (y + k - 3)))
m.Minimize(x_cost + y_cost)
# Solve.
m.options.SOLVER = 3 # Initialize with IPOPT
m.solve(disp=True)
m.options.SOLVER = 1 # APOPT is an MINLP solver
m.solver_options = ('minlp_maximum_iterations 500',
'minlp_max_iter_with_int_sol 10',
'minlp_as_nlp 0',
'nlp_maximum_iterations 50',
'minlp_branch_method 1',
'minlp_integer_tol 0.05',
'minlp_gap_tol 0.01')
m.solve(disp=True)
我使用IPOPT给出初始化的非整数解,然后使用APOPT找到最佳整数解。这种方法产生了一个成功的解决方案 x
>>> x
array([[0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0],
[0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]],
dtype=object)
和
>>> y
array([[1.0], [7.0], [5.0], [1.0], [1.0], [1.0], [1.0]], dtype=object)
您可能不打算为
x
提供零解决方案因此您可能需要添加约束,例如
m.Equation(count>=n)
或更改
eps=0.05
找到一个非零值或在局部最小值处将求解器推离零。与
m.Equation(count>=n)
和
eps=0.5
它找到了更好的解决方案:
n=3, obj=63
n=5, obj=52
这是
x
的解决方案和
y
当
obj=52
(找到最佳解决方案)。
>>> x
array([[0.0], [1.0], [4.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0],
[0.0], [1.0], [0.0], [2.0], [0.0], [0.0], [0.0], [1.0], [0.0]],
dtype=object)
>>> y
array([[1.0], [3.0], [3.0], [1.0], [1.0], [1.0], [1.0]], dtype=object)
您可能需要调整
eps
用于
if3
当一个值被计为非零时进行调整或调整
minlp_integer_tol 0.05
这是确定整数容差的求解器选项。这是带有附加不等式约束的最终脚本,可提供最佳解决方案。
from gekko import GEKKO
import numpy as np
# Setup gekko (taken from their MINLP tutorial with more iterations).
m = GEKKO(remote=False)
# Define variables as arrays.
y = m.Array(m.Var, (7), value=1, lb=1, ub=12, integer=True)
x = m.Array(m.Var, (18), value=0, lb=0, ub=8, integer=True)
# Example of the user-defined target values b as constraints (actually input args).
m.Equation(x[2] + y[1] == 7)
m.Equation(x[12] + y[2] == 5)
# This is the L0 constraint.
# m.Equation(np.count_nonzero(x) >= np.max(x))
eps = 0.5 # threshold for a "zero" value
count = m.sum([m.if3(x_i-eps,0,1) for x_i in x])
max_x = 0
for x_i in x:
max_x = m.Intermediate(m.max3(max_x,x_i))
m.Equation(count >= max_x)
# Finally, the objective function (intermediates for readability).
k = np.array([m.min3(y_i, 3) for y_i in y])
x_cost = m.Intermediate(m.sum(x * (x + 1)))
y_cost = m.Intermediate(m.sum((k - 1) * (k + 2) + 2.5 * (y - k) * (y + k - 3)))
m.Minimize(x_cost + y_cost)
m.Equation(count>=5)
# Solve.
m.options.SOLVER = 3 # Initialize with IPOPT
m.solve(disp=True)
m.options.SOLVER = 1 # APOPT is an MINLP solver
m.solver_options = ('minlp_maximum_iterations 500',
'minlp_max_iter_with_int_sol 10',
'minlp_as_nlp 0',
'nlp_maximum_iterations 50',
'minlp_branch_method 1',
'minlp_integer_tol 0.05',
'minlp_gap_tol 0.01')
m.solve(disp=True)
您也许可以调整
n
或一些求解器选项以获得更好的解决方案。我希望这有助于为您指明正确的方向。
关于python - 通过 L0 范数/GEKKO 中非零元素的数量约束混合整数非线性优化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65863807/
与在 SVM 的相同成本函数中使用 2-范数权重相比,我们如何通过在成本函数中使用 1-范数权重来提高稀疏性。 对于 1-范数:成本函数 - 最小化 ||w||_1 对于 2-范数:成本函数 - 最小
我有几个与 l1 规范相关的问题。和TV(Total Variation)一样吗?如何在matlab中计算图像的L1范数?我确实阅读了电视的 wiki 页面,但它对我来说太复杂了。 最佳答案 L1范数
我想最小化实现一组给定的非负整数值 b 的成本,这些非负整数值 b 是从 GEKKO 中的两组非负整数变量 x、y 线性计算出来的。 如果以某种方式说明了我的问题,则 b 是 x 和 y 的约束。我的
我有一个 TensorFlow 占位符,它有 4 个维度,代表一批图像。每个图像为 32 x 32 像素,每个像素有 3 个颜色 channel 。第一个维度表示图像的数量。 X = tf.place
我想取变量列表的 2-范数。如何将序列转换为 CVXPY 兼容的变量“列表”?有办法处理这个问题吗?提前致谢。例如, test_a=cvxpy.Variable(1) test_b=c
我想知道 Python 中是否有一个函数可以完成与 scipy.linalg.lstsq 相同的工作,但使用“最小绝对偏差”回归而不是“最小二乘”回归 (OLS)。我想使用 L1 规范,而不是 L2
如何在 Python 中计算两个向量的差的 1-范数 ||a - b||_1 = sum(|a_i - b_i|)? a = [1,2,3,4] b = [2,3,4,5] ||a - b||_1
我有一个矢量 e <- c(0.1, -0.1, 0.1)我想计算 L1 和 L2 范数。我正在使用 norm(e, type="2")这适用于 L2 规范,但当我将其更改为 norm(e, type
我正在尝试将 Boost.Units 与 Eigen 3.3.1 一起使用,但在遵循说明后 here , 和一些信息 found around ,我仍然不知道如何使 norm() 工作。 这是我到目前
在 Eigen 库中,我知道有 visitors 和 reductions 用于密集的 Eigen::Matrix 类,我可以有效地使用它们来计算他们的 1-norm, inf-norm, etc.
我有一个矩阵 X,它在 d 维空间中有 n 列数据 vector 。给定一个 vector xj,v[j]是它的l1范数(所有abs(xji)的总和), w[j] 是它的 l2 范数的平方(所有 xj
我是一名优秀的程序员,十分优秀!