首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用神秘中的线性符号不等式创建约束?

如何使用神秘中的线性符号不等式创建约束?
EN

Stack Overflow用户
提问于 2021-08-24 18:24:17
回答 1查看 125关注 0票数 2

我试图用神秘来最小化线性约束下的非线性函数。

作为一个简单的例子,我有以下几点:

代码语言:javascript
复制
import numpy as np
import mystic.symbolic as ms
from mystic.symbolic import generate_constraint
from mystic.symbolic import generate_solvers
from mystic.symbolic import linear_symbolic
from mystic.monitors import Monitor
from mystic.solvers import LatticeSolver
from mystic.solvers import NelderMeadSimplexSolver
from mystic.termination import CandidateRelativeTolerance as CRT

# diamond-shaped constraint
# same format as output of mystic.linear_symbolic()
basic_constraint = '''
1.0*x0 + 1.0*x1 <= 5
1.0*x0 - 1.0*x1 >= -5
1.0*x0 + 1.0*x1 >= -5
1.0*x0 - 1.0*x1 <= 5
'''[1:]

def basic_objective(x, *args):
    v1 = x[0] * x[1] / (1 + np.abs(x[0] + x[1]))
    v2 = np.min(x)
    return v1 + v2/(1+np.abs(v1))

在尝试运行代码时,我执行以下操作:

代码语言:javascript
复制
def test_basic():
    stepmon=Monitor()
    nbins = [6,6,]
    solver = LatticeSolver(len(nbins), nbins)
    solver.SetNestedSolver(NelderMeadSimplexSolver)
    print('Generating Solvers')
    constraint_solver = generate_solvers(
        basic_constraint,
        nvars=2
    )
    print(constraint_solver)
    # HERE IS ISSUE, IF COMMENTED ISSUE BELOW
    print(constraint_solver[0](np.ones(2)))
    print('Setting Constraints')
    solver.SetConstraints(
        generate_constraint(constraint_solver)
    )
    solver.SetGenerationMonitor(stepmon)
    solver.SetTermination(CRT())
    print('Solving...')
    # ISSUE APPEARS HERE IF print(constraint_solver[0]...)
    # IS COMMENTED OUT
    solver.Solve(basic_objective)
    solution = solver.Solution()
    print(solution)
    return solution

test_basic()

当我运行上述操作时,错误发生在

代码语言:javascript
复制
print(constraint_solver[0](np.ones(2)))

或者,如果我评论一下,

代码语言:javascript
复制
solver.Solve(basic_objective)

唯一明显的区别是调用堆栈的大小。

我得到的错误是

代码语言:javascript
复制
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 12, in test_basic
  File "<string>", line 4, in solver_139632515562208
  File "<string>", line 1
SyntaxError: cannot assign to operator

这是神秘试图从字符串编译Python代码并遇到语法错误的结果,但我不知道如何解决这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-28 16:04:45

我是mystic的作者。您缺少了一个关键函数,还有一个在这种情况下不需要的第二个函数,但通常是。

如果您为您的约束解决程序打印文档,您将看到它们的格式不太好。

代码语言:javascript
复制
>>> constraint_solver = generate_solvers(basic_constraint, nvars=2)
>>> print(constraint_solver[0].__doc__)
1.0*x[0] - 1.0*x[1] = min(5 - (_tol(5,tol,rel) * any(equal(5,[]))), 1.0*x[0] - 1.0*x[1])
>>> 

您需要在左侧隔离一个变量。因此,我们要么需要solve,要么需要simplify。对于不等式,simplify工作得更好,对于等式,solve通常起作用。我不确定说明这一点的文档水平。总之,我在构建约束之前使用了simplify

代码语言:javascript
复制
>>> from mystic.symbolic import simplify
>>> constraint_solver = generate_solvers(simplify(basic_constraint), nvars=2)
>>> print(constraint_solver[0].__doc__)
x[0] = max(1.0*x[1] - 5.0 + (_tol(1.0*x[1] - 5.0,tol,rel) * any(equal(1.0*x[1] - 5.0,[]))), x[0])
>>> 
>>> print(constraint_solver[0](np.ones(2)))
[1. 1.]
>>> 

现在,您的代码按照预期工作。

不过,我通常会做另一项修改。

代码语言:javascript
复制
>>> from mystic.constraints import and_
>>> c = generate_constraint(constraint_solver, join=and_)
>>> c(np.ones(2)*5)
[0.0, 5.0]
>>> print(c.__doc__)
inner: x[0] = max(1.0*x[1] - 5.0 + (_tol(1.0*x[1] - 5.0,tol,rel) * any(equal(1.0*x[1] - 5.0,[]))), x[0])
inner: x[0] = min(1.0*x[1] + 5.0 - (_tol(1.0*x[1] + 5.0,tol,rel) * any(equal(1.0*x[1] + 5.0,[]))), x[0])
inner: x[0] = min(5.0 - 1.0*x[1] - (_tol(5.0 - 1.0*x[1],tol,rel) * any(equal(5.0 - 1.0*x[1],[]))), x[0])
inner: x[0] = max(-1.0*x[1] - 5.0 + (_tol(-1.0*x[1] - 5.0,tol,rel) * any(equal(-1.0*x[1] - 5.0,[]))), x[0])

没有join=and_,您的代码仍然可以工作。不同之处在于,如果没有显式的join语句,则假设约束是彼此的独立的,并且可以一次解决一个问题。使用join=and_强制同时解决约束,这是比较慢的。在构建约束方面还有or_和其他更复杂的组合,但默认情况是假定独立。

这两个点都是微妙的,我相信,在文档中,它应该声明约束求解者需要符号方程,在左边需要一个单独的变量。然而,这可能并不明显,因为这经常被忽略。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68912349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档