如何增加CPLEX解的数量?及解池输出优化技术问询
问题2:仅输出解池中值为1的二进制变量
你当前用sol.display()会打印所有变量,咱们可以自定义打印逻辑,只筛选值为1的变量。这里有两种实用方案:
方案1:修改打印循环(直接在输出时过滤)
不需要改动generate_soln_pool函数,只修改打印部分的代码即可:
bm = CModel() pool = generate_soln_pool(bm) for s, sol in enumerate(pool, start=1): print(f"this is solution #{s} of the pool") # 遍历所有变量,仅输出值为1的(考虑浮点精度误差) for var in bm.iter_variables(): val = sol.get_var_value(var) if abs(val - 1) < 1e-6: # 二进制变量可能存在微小浮点误差,用精度判断更稳妥 print(f"{var.name} = 1")
方案2:优化解池存储(仅保存值为1的变量)
如果解池规模很大,提前筛选值为1的变量能节省内存。修改generate_soln_pool函数:
def generate_soln_pool(mdl): cpx = mdl.get_cplex() # 补充关键参数设置(参考问题1的建议) cpx.parameters.mip.pool.mode.set(1) cpx.parameters.mip.pool.capacity.set(10000) cpx.solnpoolintensity = 4 cpx.solnpoolagap = 0 cpx.populatelim = 100000 try: cpx.populate_solution_pool() except CplexSolverError: print("Exception raised during populate") return [] numsol = cpx.solution.pool.get_num() print(numsol) nb_vars = mdl.number_of_variables sol_pool = [] for i in range(numsol): x_i = cpx.solution.pool.get_values(i) assert len(x_i) == nb_vars # 仅收集值为1的变量名 selected_vars = [] for k in range(nb_vars): if abs(x_i[k] - 1) < 1e-6: vk = mdl.get_var_by_index(k) selected_vars.append(vk.name) sol_pool.append(selected_vars) return sol_pool # 打印部分 bm = CModel() pool = generate_soln_pool(bm) for s, selected_vars in enumerate(pool, start=1): print(f"this is solution #{s} of the pool") for var_name in selected_vars: print(f"{var_name} = 1")
为什么用abs(val - 1) < 1e-6?因为CPLEX在求解时可能会因为浮点精度问题,把二进制变量的值返回为0.999999999或1.000000001,用精度判断能避免漏掉正确的1值。
内容的提问来源于stack exchange,提问作者Sana.Nz
相关产品推荐
相关产品推荐

