我正在尝试解决所附的非线性优化问题。我想尝试一下神秘事物,因为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是否有其他选择?我也一直在研究神秘事物,但根本无法使其发挥作用。
我知道这是一个相当具体的问题,因此,我要感谢所有想参与其中的人。最后,如果我冒犯了任何数学家而提出了可能不正确的问题,我深表歉意。
答案 0 :(得分: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
由于分母和不等式,如上所述,这只是几个简化方程式中的一种。正好是 right 。我们可以得到 all 个候选简化方程,如下所示:
>>> 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_)
这应该更好地确保所有约束都得到遵守。