PDDL 2.1 Metric FF中z赋值x/y报非线性错误的原因
问题根因
- 该报错和运行时除零错误无关,是MetricFF对数值表达式的硬性静态检查规则导致的:MetricFF仅支持符合线性约束的PDDL2.1数值建模,所有涉及数值fluent的运算,仅允许「fluent与fluent的加减」、「fluent与非零常量的乘除」两类操作,一旦在同一个运算项里出现两个独立数值fluent的乘/除,整个表达式就属于非线性范畴,会被直接判定为不支持的任务类型。即使你在动作前置条件里添加了y不等于0的校验,依然不会通过检查——MetricFF的线性判定是纯语法层面的,不会分析动作前置的逻辑约束。
- 你测试通过的
(assign (z) (/ (x) 2 ))、(assign (z) (/ (y) 2 ))之所以能正常运行,是因为表达式里仅存在fluent和常量2的除法,完全符合线性要求。而报错的(assign (z) (/ (x) (y) ))是两个数值fluent x、y做除法,属于非线性运算,在建模静态解析阶段就会被拦截,根本不会进入到动作运行时的除数非零校验环节,和你确认执行时x、y不为0没有关系。
可行解决路径
- 若必须保留两个fluent直接求商的逻辑,直接替换支持非线性数值PDDL的规划器即可(如ENHSP、Optic),MetricFF从架构设计上就不支持非线性任务域,无论怎么调整前置条件、加防除零校验,都无法通过它的静态检查。
- 若必须使用MetricFF完成求解,可通过场景逻辑拆解绕开非线性运算:
- 若场景中y的取值是固定步长的常量变化(即y的数值不会随多个动作的执行随机浮动),可直接把除法表达式改写为fluent乘对应常量的形式,比如当y稳定取值为3时,原
(/ (x) (y))等价于(* (x) 0.3333),属于合法线性表达式,可被MetricFF识别。 - 若y是随动作动态变化的fluent,可在设计动作时,将z的更新逻辑和x、y的固定增量绑定,把z的赋值拆分为多个仅涉及单fluent和常量运算的线性子步骤,避免出现两个fluent直接乘除的语法结构。
- 若场景中y的取值是固定步长的常量变化(即y的数值不会随多个动作的执行随机浮动),可直接把除法表达式改写为fluent乘对应常量的形式,比如当y稳定取值为3时,原
内容的提问来源于stack exchange,提问作者algo_learner
相关产品推荐
相关产品推荐

