1

我正在尝试解决附加的非线性优化问题。我想尝试一下 mystic,因为 SciPy.optimize 不能按预期工作(下面有更多详细信息)。

优化问题表述

因为c_1 = 3,所以问题不可行。这是因为 (p_1 - 3 - 0.22) / p_1 < 0.05 意味着 p_1 必须大于 3.22,这将与 p_1 / 2.2 <= 0.65 冲突。

这里存在一个解决的问题,解决了 SciPy 成功终止不可行问题的基本问题。不幸的是,我需要用 python 解决这个特定的问题,这就是我再次在这里碰运气的原因。

当我使用 SciPy.optimize 时,程序也成功终止,打破了约束而没有引发问题(即使设置 keep_feasible=True)。我的问题更大,也无法满足其他约束。因此,SciPy 似乎不适合这项工作。

我的第一个问题:我做错了什么吗?如果没有:是否有 SciPy.optimize 的替代品?我也一直在研究神秘主义,但根本无法让它发挥作用。

我知道这是一个相当具体的问题,所以我感谢所有想要参与的人。最后,如果我因问题的可能不正确的表述冒犯了任何数学家,我深表歉意。

4

1 回答 1

1

这是一个有点困难的问题,因为它需要求解一个带有分母的符号不等式方程组。带有分母的不等式的符号求解很棘手,因为乘以分母可以翻转不等式的符号,具体取决于未知变量的值。单独解决其中一个问题是很困难的……但再加上解决方案不可行,情况会变得更糟。所以,请记住,以下内容有点不稳定......但这可能是您可以直接解决此问题的最佳方法。

>>> def objective(x):
...   x0,x1,x2 = x
...   return (x0 - 3 - .23)/x0 + (x1 - 1.17 - .23)/x1 + (x2 - 0.71 - .23)/x2
...
>>> def cost(x): # maximize
...   return -objective(x)
...
>>> bounds = [(None,.65*2.2),(None,.65*2.9),(None,.65*1.91)]
>>>
>>> equations = '''
... (x0 - 3.00 - .23)/(38000 * x0) >= .05
... (x1 - 1.17 - .23)/(33000 * x1) >= .05
... (x2 - 0.71 - .23)/(29000 * x2) >= .05
... (38000 * x0 + 33000 * x1 + 29000 * x2) / (38000 * (2.2 - x0) + 33000 * (2.9 - x1) + 29000 * (1.91 - x2)) <= -0.5
... (38000 * (2.2 - x0) + 33000 * (2.9 - x1) + 29000 * (1.91 - x2)) / (38000 * x0 + 33000 * x1 + 29000 * x2) >= 0.18
... '''
>>> from mystic.solvers import diffev2
>>> from mystic.symbolic import generate_constraint, generate_solvers, simplify

这应该是问题的根源......现在到了棘手的部分。简化方程,然后求解。

>>> eqn = simplify(equations)
>>> cf = generate_constraint(generate_solvers(eqn))
>>> result = diffev2(cost, x0=bounds, bounds=bounds, constraints=cf, npop=40, gtol=50, disp=True, full_output=True)
Warning: Maximum number of iterations has been exceeded
>>> print(result[1])
inf

我们看到我们得到inf,这表明mystic正在遇到一个不可行的解决方案。但是,我正在掩盖上面的一些东西,实际上有点幸运。让我们看一下简化的方程。

>>> print(eqn)
x0 > 0
x0 > -0.868421052631579*x1 - 0.763157894736842*x2 + 6.17605263157895
x2 >= -0.000648723257418910
x1 >= -0.000848999393571862
x0 >= -0.868421052631579*x1 - 0.763157894736842*x2 - 6.17605263157895
x2 < 0
x1 < 0
x0 < -33*x1/38 - 29*x2/38
x0 <= -0.00170089520800421
x0 >= -0.868421052631579*x1 - 0.763157894736842*x2 + 5.23394290811775

如上所述,由于分母和不等式,这只是几个简化方程中的一种可能……它恰好是正确的。我们可以得到所有候选简化方程,如下:

>>> all_eqn = simplify(equations, all=True)
>>> len(all_eqn)
32

请注意,我们有 32 种可能性——其中一些是“好”的,而另一些不是——取决于变量的值。您可以插入all_eqncf = generate_constraint(generate_solvers(all_eqn))然后mystic将尽最大努力找到使所有可能的简化方程最小化的解决方案。这通常可以正常工作......而且我确信可能会失败。随着最大化,情况会变得更糟,更重要的是,您正在寻找的解决方案是不可行的。

我要说这是一个积极发展的领域,mystic可以通过一些改进来更好地处理这样的案例。

编辑:在上面的解决方案中,我忘了使用关键字join。默认值是join=None按顺序应用每个方程。虽然这更快,但如果存在冲突的方程式,这不是您想要的。我可能应该使用:

>>> from mystic.constraints import and_
>>> cf = generate_constraint(generate_solvers(eqn), join=and_)

这应该更好地确保所有约束都得到尊重。

于 2019-01-02T19:06:47.103 回答