在自定义分支定界算法中调用CPLEX内置割平面
在自定义分支定界算法中调用CPLEX内置割平面
当然可以!你完全可以调用CPLEX的内置割平面生成器,为自定义分支定界里的LP松弛问题添加有效不等式,而且能明确指定哪些变量需要考虑整数性。我之前做类似自定义分支定界的时候也这么处理过,下面给你详细说下操作步骤和注意事项:
先标记整数变量:不管你当前解的是LP松弛,都要在模型里明确把需要整数的变量定义成
IloIntVar类型,或者给普通IloNumVar设置IloNumVar::Integer属性。这一步很关键——CPLEX需要知道哪些变量是“目标整数变量”,才能针对性地生成对应的割平面(比如Gomory割、覆盖割这类依赖整数变量的不等式)。调整CPLEX参数,避免自动分支:因为你是自己控制分支逻辑,所以要把CPLEX的自动MIP搜索功能关掉,只保留割平面分离的能力。核心参数设置如下:
- 把
IloCplex::Param::MIP::Strategy::Search设为IloCplex::NoSearch,这样CPLEX只会处理割平面和LP求解,不会自己启动分支过程。 - 开启割平面生成:可以全局开启所有割(
IloCplex::Param::MIP::Cuts::All设为IloCplex::On),也可以精细控制特定类型的割(比如单独开启Gomory割IloCplex::Param::MIP::Cuts::Gomory),根据你的问题类型选就行。
- 把
调用割平面生成并求解:有两种方式:
- 自动模式:只要参数设置正确,调用
cplex.solve()时,CPLEX会自动在LP求解过程中分离割平面、添加到模型,然后求解强化后的LP。这种方式最简单,适合不需要手动干预割的场景。 - 手动模式:如果想自己控制割的添加时机和数量,可以用
cplex.generateCuts()方法生成割平面,然后手动添加到当前节点的LP模型中再求解。比如这样:IloRangeArray cuts(env); // 生成所有类型的有效割平面 cplex.generateCuts(cuts, IloCplex::CutAll); // 将割添加到当前节点的模型 model.add(cuts); // 求解强化后的LP cplex.solve();
- 自动模式:只要参数设置正确,调用
一些实用注意点:
- 割平面不是越多越好:过多的割会让LP模型规模变大,求解速度变慢。可以通过
IloCplex::Param::MIP::Cuts::MaxPasses设置割平面的最大迭代次数,或者调整各类割的强度参数(比如IloCplex::Param::MIP::Cuts::Cover设为IloCplex::Aggressive或Moderate)来平衡效果和效率。 - 节点间模型隔离:每个分支节点的LP模型最好是独立的,处理完一个节点后,记得清理添加的割平面,避免影响下一个节点的求解。
- 割平面不是越多越好:过多的割会让LP模型规模变大,求解速度变慢。可以通过
备注:内容来源于stack exchange,提问作者Alberto Guastalla
相关产品推荐
相关产品推荐

