求解不可行的不等式系统

solving a system of inequalities where the solution is infeasible

我正在尝试解决附加的非线性优化问题。我想试试 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 成功终止不可行问题 here 的基本问题。不幸的是,我需要用 python 解决这个特定问题,这就是为什么我再次在这里试试运气。

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

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

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

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

>>> 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 种可能性——其中一些是 "good",有些不是——取决于变量的值。您可以将 all_eqn 代入 cf = generate_constraint(generate_solvers(all_eqn)),然后 mystic 将尽最大努力找到使所有可能的简化方程式最小化的解决方案。这通常有效 ok... 我敢肯定可能会失败。随着最大化,情况变得更糟,更重要的是,您正在寻找的解决方案是不可行的。

我要说这是一个积极发展的领域,mystic 可以使用一些改进来更好地处理这种情况。

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

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

哪个应该更好地确保遵守所有约束。