1

我正在处理一个相当复杂的目标函数,我通过改变 4 个参数来最小化它。不久前,我决定使用 Python 框架Mystic,它无缝地允许我对复杂的不等式使用惩罚(这是我需要的)。

然而,Mystic 有一种不太明显的方式来分配硬约束(不是不等式和非绑定约束,仅参数之间的线性不等式),甚至更不明显的方式来处理它们。

我所有的 4 个参数都有有限的下限和上限。我想添加一个线性不等式作为硬约束,如下所示:

def constraint(x):  # needs to be <= 0
    return x[0] - 3.0*x[2]

但是如果我尝试以这种方式使用 Mystic:

from mystic.solvers import fmin_powell
xopt = fmin_powell(OF, x0=x0, bounds=bounds, constraints=constraint)

然后 Mystic 坚持调用目标函数先解决约束,然后进行实际优化;由于目标函数值对上面定义的约束函数没有影响也没有任何影响,所以我不确定为什么会发生这种情况。上面定义的约束函数只是告诉 Mystic 超参数搜索空间的一个区域应该是禁区。

我已经搜索了 Mystic 文件夹中的几乎所有示例,并且偶然发现了另一种定义硬约束的方法:使用惩罚函数,然后调用魔术方法“as_constraint”将其“转换”为约束。不幸的是,所有这些例子都是这样的:

from mystic.solvers import fmin_powell
from mystic.constraints import as_constraint
from mystic.penalty import quadratic_inequality

def penalty_function(x): # <= 0.0
    return x[0] - 3.0*x[2]

@quadratic_inequality(penalty_function)
def penalty(x):
    return 0.0

solver = as_constraint(penalty)

result = fmin_powell(OF, x0=x0, bounds=bounds, penalty=penalty)

有一条神奇的线:

solver = as_constraint(penalty)

我看不到它在做什么——求解器变量不再使用。

那么,对于这个问题:有没有办法在 Mystic 中定义线性不等式,不涉及昂贵的约束预求解,而只是告诉 Mystic 排除搜索空间的某些区域?

提前感谢您的任何建议。

安德里亚。

4

1 回答 1

1

所做的是映射它搜索的空间,因此您mystic正在优化“内核转换”空间(使用机器学习术语)。如果您知道这意味着,您可以将约束视为应用运算符。因此,y = f(x)在某些约束下x' = c(x)变为y = f(c(x)). 这就是优化器在评估目标之前评估约束的原因。

所以你可以建立一个这样的约束:

>>> import mystic.symbolic as ms
>>> equation = 'x1 - 3*a*x2 <= 0'
>>> eqn = ms.simplify(equation, locals=dict(a=1), all=True)
>>> print(eqn)
x1 <= 3*x2
>>> c = ms.generate_constraint(ms.generate_solvers(eqn, nvars=3))
>>> c([1,2,3])
[1, 2, 3]
>>> c([0,100,-100])
[0, -300.0, -100]

或者,如果您有多个:

>>> equation = '''
... x1 > x2 * x0     
... x0 + x1 < 10
... x1 + x2 > 5
... '''
>>> eqn = ms.simplify(equation, all=True)
>>> print(eqn)
x1 > -x2 + 5
x0 < -x1 + 10
x1 > x0*x2
>>> import mystic.constraints as mc
>>> c = ms.generate_constraint(ms.generate_solvers(eqn), join=mc.and_)
>>> c([1,2,3])
[1, 3.000000000000004, 3]
于 2019-01-05T19:32:09.477 回答