OpenMDAO离散优化:如何定义离散变量的可选取值集合
OpenMDAO离散优化中指定离散变量可选取值集合的实现方法
OpenMDAO没有单独的“离散值集合配置项”,根据你选用的优化器类型,对应实现方式分两类:
搭配原生支持离散变量的优化器使用(例如pyOptSparse下支持离散/整数变量的求解器、框架内置的SimpleGA遗传算法等)
直接在调用add_design_var定义离散设计变量时,传入values参数指定允许选取的取值集合即可,支持数值、字符串等任意可哈希的离散取值类型:import openmdao.api as om prob = om.Problem() # 例1:指定整数型离散值可选集合 prob.model.add_design_var('layer_count', values=[2, 4, 6, 8, 10], var_type=int) # 例2:指定枚举类字符串离散值可选集合 prob.model.add_design_var('material', values=['steel', 'aluminum', 'carbon_fiber'], var_type=str)优化器在迭代过程中只会从你传入的
values列表里挑选取值,不会生成列表外的非法离散值。搭配不支持原生离散变量的连续优化器使用(例如SLSQP、SNOPT等仅支持连续变量的求解器)
这类场景下需要自己加一层索引映射逻辑:预定义好允许的离散取值列表,将设计变量定义为取值范围在[0, 可选值总数-1]的整数变量,在组件内部通过索引映射到实际的离散取值,同时加边界约束避免索引越界:# 预定义所有允许的传动比离散取值 ALLOWED_GEAR_RATIOS = [0.2, 0.5, 0.8, 1.1, 1.4] class GearSelection(om.ExplicitComponent): def setup(self): # 输入为离散索引,取值范围对应可选值列表的下标 self.add_discrete_input('gear_idx', val=0, val_type=int) self.add_output('actual_ratio', val=0.2) def compute(self, inputs, outputs, discrete_inputs, discrete_outputs): idx = discrete_inputs['gear_idx'] # 做边界钳位,避免索引超出可选值范围 idx = max(0, min(idx, len(ALLOWED_GEAR_RATIOS) - 1)) outputs['actual_ratio'] = ALLOWED_GEAR_RATIOS[idx]如果用这类连续优化器求解混合整数问题,注意要对索引变量做整数圆整处理,否则连续求解器输出的浮点索引会导致映射逻辑出错,同时圆整操作可能引入收敛误差,优先选原生支持离散变量的优化器处理这类问题。
注意:不要用连续变量的上下界约束替代离散值集合配置,上下界仅能限制取值的数值范围,无法约束优化器跳过你不允许的中间值。
内容的提问来源于stack exchange,提问作者Quentin Tiefaine
相关产品推荐
相关产品推荐

