建模接口
该章节介绍以下内容:
- OPTIMake支持的问题类型
- 如何通过OPTIMake提供的符号化建模接口定义问题
- 如何通过外部C/C++函数定义问题
问题形式
OPTIMake求解以下的优化问题:
该优化问题为一个具有 个stage的优化问题, 该优化问题可能为一个非线性非凸的优化问题. 其中:
- 为优化变量
- 为参数
- 为stage objective
- 为终点处额外的objective
- 为起点等式约束
- 为等式约束
- 为终点等式约束
- 为不等式约束
问题定义
下面为定义问题的例子, 该例子指定了问题的名称为vehicle且具有10个stage:
prob = multi_stage_problem(name='vehicle', N=10)
其中, 函数入参的定义如下:
-
name: str 问题的名称, 该名称会用在生成代码的文件名, 函数名等
-
N: int 问题的stage数目, 必须大于等于1
在完成问题名称和stage数的定义后, 下面说明如何定义优化问题中的参数, 优化变量及约束.
因为上述的优化问题为一个多stage的优化问题, 等式约束与不等式约束的表达式在所有stage上都一致, 所以不需要在每个stage上都单独定义, 只需要定义一次该表达式即可 (参数与优化变量同理) .
parameter定义
parameter为在优化过程中不变的量, 由用户在调用求解前给定, 比如车身长度length, 质量mass.
OPTIMake支持两种类型的parameter: stage-independent parameter与stage-dependent parameter. stage-dependent parameter在不同stage可以有不同的值, 而stage-independent parameter在所有stage的值都一致 (可以节约存储与简化设置) .
下面为定义优化变量的例子:
length = prob.parameter(name='length', stage_dependent=False)
mass = prob.parameter('mass')
xLowerBound = prob.parameter('xLowerBound', stage_dependent=True)
其中, 函数入参的定义如下:
-
name: str parameter的名称
-
stage_dependent: bool, optional parameter是否为stage-dependent. 默认值为True, 表示parameter为stage-dependent
亦或者通过list的方式定义:
length, mass, xLowerBound = prob.parameters(
['length', 'mass', 'xLowerBound'],
stage_dependent=False)
优化变量定义
优化变量为在优化过程中变化的量, 比如车辆的转角控制量delta, 位置状态x, y. 在定义优化变量时, 可以同时定义优化变量的硬边界、软边界以及违反软边界时的惩罚 (见建模接口 > 约束软化了解OPTIMake中的软约束定义) .
下面为定义优化变量的例子:
delta = prob.variable(name='delta', hard_lowerbound=-0.5, hard_upperbound=0.5)
# xLowerBound与xUpperBound为已定义的parameter
x = prob.variable(
name = 'x',
hard_lowerbound=xLowerBound,
hard_upperbound=xUpperBound,
soft_lowerbound=-0.2,
soft_upperbound=0.2,
weight_soft_lowerbound=100.0,
weight_soft_upperbound=100.0,
penalty_type_soft_lowerbound='quadratic',
penalty_type_soft_upperbound='l1')
y = prob.variable('y')
theta = prob.variable('theta')
其中, 函数入参的定义如下:
- name: 优化变量的名称, string类型
- hard_lowerbound (optional): 优化变量的硬下界, 可以为常数或关于参数的表达式, 默认值为-inf, 表示无下界
- hard_upperbound (optional): 优化变量的硬上界, 可以为常数或关于参数的表达式, 默认值为inf, 表示无上界
- soft_lowerbound (optional): 优化变量的软下界, 可以为常数或关于参数的表达式, 默认值为-inf, 表示无下界
- soft_upperbound (optional): 优化变量的软上界, 可以为常数或关于参数的表达式, 默认值为inf, 表示无上界
- weight_soft_lowerbound (optional): 优化变量的软下界的惩罚权重, 必须为非负, 可以为常数或关于参数的表达式, 默认值为0.0, 表示无惩罚
- weight_soft_upperbound (optional): 优化变量的软上界的惩罚权重, 必须为非负, 可以为常数或关于参数的表达式, 默认值为0.0, 表示无惩罚
- penalty_type_soft_lowerbound (optional): 优化变量的软下界的惩罚类型, 可选值为
'quadratic'
或'l1'
, 默认值为'quadratic'
- penalty_type_soft_upperbound (optional): 优 化变量的软上界的惩罚类型, 可选值为
'quadratic'
或'l1'
, 默认值为'quadratic'
objective定义
objective为需要最小化的目标函数. OPTIMake支持以下类型的objective定义:
- general_objective: 通用类型, 通过表达式直接定义
- least_square_objective: least square类型
- external_general_objective: 通用类型, 通过外部C/C++函数定义
在完成objective定义后, 通过以下接口最小化该objective:
prob.objective(obj)
同理, 通过以下接口加入对最后一个点的objective:
prob.end_objective(obj)
- 只能调用一次prob.objective或prob.end_objective设置objective
general_objective
下面为通过表达式直接定义objective的例子:
# wyref, wphi为已定义的parameter
obj = general_objective(wxref * (x * sin(phi) - xref)**2 + wyref * (y - yref)**2 + wphi * phi**2 + 0.01 * delta**2 + 0.1 * v**2)
prob.objective(obj)
least_square_objective
当objective为以下形式时, 可通过least square接口定义, 其中为残差项, 为其对应的权重项.
下面为通过least square接口定义objective的例子:
r = [x * sin(phi) - xref, y - yref, phi, delta, v]
w = [wxref, wyref, wphi, 0.01, 0.1]
obj = least_square_objective(residuals=r, weights=w)
prob.objective(obj)
其中, least_square_objective接口的函数入参的定义如下:
- residuals: 残差项, 对应, 类型为list
- weights (optional): 残差权重, 对应, 可以为常数或关于参数的表达式的list, 其默认值为全为1.0的list
当objective通过least square接口定义时, 其Hessian通过Gauss-Newton方式近似计算.
external_general_objective
通过外部C/C++函数定义的general_objective. 在建模时, 可以指定其Hessian的稀疏性加速运算.
下面为通过external_general_objective接口定义objective的例子:
obj_spy_hess = \
[[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]]
obj = external_general_objective(sparsity_hessian=obj_spy_hess)
prob.objective(obj)
其中, external_general_objective接口的入参如下:
- sparsity_hessian (optional): objective的Hessian的sparsity pattern, 维度为的对称矩阵, 0代表稀疏, 1代表稠密;该参数为optional参数, 其默认值为全1.0