向 mystic 提供 inequalities/constraints 的向量
Supplying a vector of inequalities/constraints to mystic
我正在尝试为一个函数最小化提供约束,迄今为止我一直使用通过 scipy (scipy.optimize.fmin_l_bfgs_b()
) 提供的无约束算法成功执行该函数。
阅读(例如,参见 Python constrained non-linear optimization),我发现了一个名为 mystic
的最小化包,它似乎正是我所需要的。我的情况如下。我有一个 3N
变量的函数(代表 N
节点的 xyz 位置坐标),我想提供一个约束列表,使得每个节点 z/x = const.
。这使得总共有 N
个约束。我如何最有效地为 mystic()
执行 define/supply 这些约束? scipy.optimize.slsqp()
也可以使用相同的约束对象吗?由于我的约束是线性的,这应该也是一个可行的选择。
我尝试了以下方法,但它使我的计算机崩溃:
import mystic.symbolic as ms
ieqns = ''
for p in range(N):
ieqns += 'x'+str(p+2) +'/x'+str(p) +" <= 2"
cf = ms.generate_constraint(ms.generate_solvers(ms.simplify(ieqns)))
pf = ms.generate_penalty(ms.generate_conditions(ieqns), k=1e12)
我是 mystic
作者。我相信你想要做的是这样的:
>>> import mystic.symbolic as ms
>>> ieqns = ''
>>> for p in range(10):
... ieqns += 'x{0} <= 2*x{1}\n'.format(p+2,p)
...
>>> cf = ms.generate_constraint(ms.generate_solvers(ieqns))
>>>
>>> # test that it applies the constraints
>>> cf([1.,3.,5.,7.,9.,11.,13.,15.,17.,19.,21.,23.,25.])
[1.0, 3.0, 2.0, 6.0, 4.0, 11.0, 8.0, 15.0, 16.0, 19.0, 21.0, 23.0, 25.0]
然后我们可以在应用约束的同时最小化(但是,在下面的情况下约束基本上是无关紧要的):
>>> # get an objective
>>> import mystic.models as mm
>>> rosen = mm.dejong.Rosenbrock(12).function
>>>
>>> # get an optimizer
>>> import mystic.solvers as my
>>> result = my.diffev2(rosen, x0=bounds, bounds=bounds, constrints=cf, npop=40, disp=False, full_output=True, gtol=100)
>>>
>>> # get the solution
>>> result[0]
array([0.99997179, 1.00005506, 1.00012367, 0.99998539, 0.99984306,
0.99981495, 0.999951 , 0.99996505, 0.99971107, 0.99925239,
0.99846259, 0.99692293])
>>> # and the final 'cost'
>>> result[1]
2.2385442425350018e-05
>>>
我正在尝试为一个函数最小化提供约束,迄今为止我一直使用通过 scipy (scipy.optimize.fmin_l_bfgs_b()
) 提供的无约束算法成功执行该函数。
阅读(例如,参见 Python constrained non-linear optimization),我发现了一个名为 mystic
的最小化包,它似乎正是我所需要的。我的情况如下。我有一个 3N
变量的函数(代表 N
节点的 xyz 位置坐标),我想提供一个约束列表,使得每个节点 z/x = const.
。这使得总共有 N
个约束。我如何最有效地为 mystic()
执行 define/supply 这些约束? scipy.optimize.slsqp()
也可以使用相同的约束对象吗?由于我的约束是线性的,这应该也是一个可行的选择。
我尝试了以下方法,但它使我的计算机崩溃:
import mystic.symbolic as ms
ieqns = ''
for p in range(N):
ieqns += 'x'+str(p+2) +'/x'+str(p) +" <= 2"
cf = ms.generate_constraint(ms.generate_solvers(ms.simplify(ieqns)))
pf = ms.generate_penalty(ms.generate_conditions(ieqns), k=1e12)
我是 mystic
作者。我相信你想要做的是这样的:
>>> import mystic.symbolic as ms
>>> ieqns = ''
>>> for p in range(10):
... ieqns += 'x{0} <= 2*x{1}\n'.format(p+2,p)
...
>>> cf = ms.generate_constraint(ms.generate_solvers(ieqns))
>>>
>>> # test that it applies the constraints
>>> cf([1.,3.,5.,7.,9.,11.,13.,15.,17.,19.,21.,23.,25.])
[1.0, 3.0, 2.0, 6.0, 4.0, 11.0, 8.0, 15.0, 16.0, 19.0, 21.0, 23.0, 25.0]
然后我们可以在应用约束的同时最小化(但是,在下面的情况下约束基本上是无关紧要的):
>>> # get an objective
>>> import mystic.models as mm
>>> rosen = mm.dejong.Rosenbrock(12).function
>>>
>>> # get an optimizer
>>> import mystic.solvers as my
>>> result = my.diffev2(rosen, x0=bounds, bounds=bounds, constrints=cf, npop=40, disp=False, full_output=True, gtol=100)
>>>
>>> # get the solution
>>> result[0]
array([0.99997179, 1.00005506, 1.00012367, 0.99998539, 0.99984306,
0.99981495, 0.999951 , 0.99996505, 0.99971107, 0.99925239,
0.99846259, 0.99692293])
>>> # and the final 'cost'
>>> result[1]
2.2385442425350018e-05
>>>