OpenMDAO的compute()中用if/else规避除零是否合规?求替代方案
处理OpenMDAO中离散输入导致的除零问题的推荐方案
方案1:从设计变量层面规避无效组合
既然D和d是离散输入,且物理逻辑上必然要求D > d(弹簧直径不可能等于或小于簧丝直径),直接在定义设计变量时排除D=d的情况:
- 若D、d为带上下界的离散值:给d设置上限为「D的下限 - 最小离散步长」,从根源上避免无效解生成。示例代码:
self.add_input('D', val=10.0, discrete=True, lower=5.0) self.add_input('d', val=2.0, discrete=True, upper=4.0) # 确保d上限小于D下限 - 若使用自定义离散选项列表:预先筛选出所有满足D>d的合法组合,再传递给优化驱动:
valid_D = [6,7,8] valid_d = [1,2,3] # 仅保留合法组合 valid_combinations = [(D,d) for D in valid_D for d in valid_d if D>d]
方案2:用物理相关的极小值替代零
如果无法完全从输入阶段规避,替换0的数值要贴合物理场景,而非用随意的1e-10。比如取簧丝直径最小可能值的1%,让替换后的结果更符合设计逻辑,减少对优化收敛的干扰:
def compute(self, inputs, outputs): D = inputs['D'] d = inputs['d'] output_c = D - d # 基于d的极小值设置替代值,避免极端情况 eps = max(1e-6, 0.01 * d) if d != 0 else 1e-6 outputs['output_a'] = outputs['output_b'] / (output_c if output_c != 0 else eps)
方案3:添加约束或惩罚项引导优化
给优化问题添加约束,强制D - d >= 极小阈值(阈值根据离散步长调整,比如1e-3),SimpleGADriver会自动规避违反约束的个体:
prob.model.add_constraint('D - d', lower=1e-3)
如果GA对约束处理不够严格,可在目标函数中加入惩罚项——当D-d <=0时,给目标值加一个极大的惩罚,让GA自动淘汰这类无效解:
def compute_objectives(self, inputs, outputs): D = inputs['D'] d = inputs['d'] penalty = 1e9 if (D - d) <= 0 else 0 outputs['obj1'] = original_obj1 + penalty outputs['obj2'] = original_obj2 + penalty
方案4:捕获异常并记录日志
可以在compute方法中捕获除零异常,返回合理默认值的同时记录日志,方便后续排查无效解的生成原因:
import logging def compute(self, inputs, outputs): try: output_c = inputs['D'] - inputs['d'] outputs['output_a'] = outputs['output_b'] / output_c except ZeroDivisionError: logging.warning(f"无效组合:D={inputs['D']}, d={inputs['d']},已使用 fallback 值") outputs['output_a'] = outputs['output_b'] / 1e-6
内容的提问来源于stack exchange,提问作者Guan Yu
相关产品推荐
相关产品推荐

