我试图用神秘来最小化线性约束下的非线性函数。
作为一个简单的例子,我有以下几点:
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))在尝试运行代码时,我执行以下操作:
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()当我运行上述操作时,错误发生在
print(constraint_solver[0](np.ones(2)))或者,如果我评论一下,
solver.Solve(basic_objective)唯一明显的区别是调用堆栈的大小。
我得到的错误是
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代码并遇到语法错误的结果,但我不知道如何解决这个问题。
发布于 2021-08-28 16:04:45
我是mystic的作者。您缺少了一个关键函数,还有一个在这种情况下不需要的第二个函数,但通常是。
如果您为您的约束解决程序打印文档,您将看到它们的格式不太好。
>>> 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。
>>> 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.]
>>> 现在,您的代码按照预期工作。
不过,我通常会做另一项修改。
>>> 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_和其他更复杂的组合,但默认情况是假定独立。
这两个点都是微妙的,我相信,在文档中,它应该声明约束求解者需要符号方程,在左边需要一个单独的变量。然而,这可能并不明显,因为这经常被忽略。
https://stackoverflow.com/questions/68912349
复制相似问题