【问题标题】:solving a system of inequalities where the solution is infeasible求解不可行的不等式系统
【发布时间】:2019-01-06 03:58:20
【问题描述】:

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

因为 c_1 = 3,所以问题不可行。这是因为 (p_1 - 3 - 0.22) / p_1

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

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

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

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

【问题讨论】:

  • 我是mystic 作者。我相信mystic 应该能够为您解决这个问题。稍后我会尝试在下面发布一些内容,除非有人击败我。但是,我确实将答案发布到the question you referred to,然后我可以将您指向an example in mystic for infeasible solutions。
  • 抱歉耽搁了...我正在修复与此问题相关的错误...因此,您需要从 GitHub 获取最新的 mystic 才能看到相同的结果.
  • 在我看来就像一个小的线性规划 (LP) 问题。有很多求解器(它们会检测不可行的模型)。
  • @ErwinKalvelagen:请随时提出一些可行的建议,并发布解决方案……例如,使用 CONOPT 和 IPOPT。
  • 抱歉,看起来像带有线性约束的非线性 obj。

标签: python optimization scipy nonlinear-optimization mystic


【解决方案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_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_)

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

【讨论】:

  • 哇,迈克,mystic 比目前的 SciPy 处理这个问题要好得多。这看起来和我要找的完全一样!非常感谢!
猜你喜欢
  • 2017-03-09
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
相关资源
最近更新 更多