【问题标题】:Variable placeholder in mystic constraints神秘约束中的变量占位符
【发布时间】:2021-02-28 00:18:01
【问题描述】:

有没有办法在神秘约束中使用变量名?

equations = '''
abs(x0 - init_velocity) <= acceleration_constraint
abs(x1 - init_heading) <= turning_constraint
'''

以上导致此错误:

Traceback (most recent call last):

  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3418, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-68-254fb3031193>", line 14, in <module>
    eqn = simplify(equations, all=True)

  File "<string>", line 120, in simplify

  File "<string>", line 93, in _simplify

  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/mystic/symbolic.py", line 381, in equals
    after, before = eval(after,{},locals_), eval(before,{},locals_)

  File "<string>", line unknown
    
    ^
SyntaxError: unexpected EOF while parsing

编辑:

下面使用的代码试图最小化当前本地点 (x_0, y_0) 和下一个本地点 (x_1, y_1) 之间的 l2 范数,同时遵循约束(物理加​​速度和转弯半径)。这个距离在速度和航向方面被最小化了。

def formulate_objective(curr_x, curr_y, desired_x, desired_y):
    def objective(x):
        next_x = curr_x + x[0] * np.cos(np.radians(x[1]))
        next_y = curr_y + x[0] * np.sin(np.radians(x[1]))
        return np.linalg.norm(np.vstack([desired_x - next_x, desired_y - next_y]), ord=2)
    return objective

objective = formulate_objective(init_x, init_y, desired_x, desired_y)

equations = '''
abs(x0 - iv) <= ac
abs(x1 - ih) <= tc
'''
var_dict = dict(iv=init_velocity, ih=init_heading, 
                ac=acceleration_constraint, tc=turning_constraint)
eqn = simplify(equations, locals=var_dict)
cf = generate_constraint(generate_conditions(eqn, nvars=2), join=and_)

x0 = [init_velocity, init_heading]
fmin(objective, x0=x0, constraint=cf)

【问题讨论】:

  • 编辑后,我认为问题很可能是由于abs,简化没有在 LHS 上隔离 x0x1。至少这是我在测试时看到的。您可能想尝试手动简化方程,Mystic 可以获取方程的元组,然后将元组中的方程与 and_or_ 组合以形成单个约束。对于abs,这可以在这里工作。您可能还想在 mystic 的 GitHub 上报告关于 abs 的问题/提出功能请求。

标签: python optimization constraints mystic


【解决方案1】:

您应该能够使用 locals 关键字来替换不是优化变量名称的名称。

>>> import mystic.symbolic as ms
>>> equations = '''
... x0 + x1 = A
... x1 * x0 = B
... '''
>>> 
>>> eqn = ms.simplify(equations, locals=dict(A=7,B=12))
>>> print(eqn)
x0 = 7 - x1
x0 != 0
x1 = 12/x0
>>>

【讨论】:

  • 这行得通,但似乎求解器中没有遵循约束。任何线索为什么会这样?
  • 最常见的问题:(1)个别约束不能独立应用,你可以在上面看到x0在LHS上两次。 simplify 中有一个关键字,要求按照指定的顺序在 LHS 上进行隔离; (2) 约束不是同时求解的,除非你在约束函数生成器中使用join=and; (3) 最后,如果解空间非常狭窄,您可能需要将一个或多个约束方程移动到一个罚分上,这将使求解器更灵活地找到一个解。
  • 我在原始问题中发布了我的代码。你能检查我是否做得正确吗?我尝试了你所有的解释,但似乎没有一个能解决约束/惩罚后求解器的问题
【解决方案2】:

您可以使用所谓的 Python f-Strings:

https://realpython.com/python-f-strings/

示例:

k = 'x0'
i = 'init_velocity'
a = 'acceleration_constraint'
b = 'turning_constraint'
equations = f'''
abs({k} - {i}) <= {a}
abs({k} - {i}) <= {b}
'''
print(equations)

给我这个输出:

abs(x0 - init_velocity) <= acceleration_constraint
abs(x0 - init_velocity) <= turning_constraint

【讨论】:

  • 你能在那个等式上打电话给simplify吗?我仍然收到解析错误。问题是代码仍然在不调用简化的情况下运行,但是由于某种原因求解器没有遵循约束,也许我做错了什么。
猜你喜欢
  • 1970-01-01
  • 2019-04-15
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多