[英]How to use the LazyConstraintCallback in the CPLEX Python API to solve a MILP problem through Benders' decomposition
我有二進制和連續變量的MILP問題。 我想使用Benders的分解算法來解決它。 我正在關注此演示文稿: http : //www.iems.ucf.edu/qzheng/grpmbr/seminar/Yuping_Intro_to_BendersDecomp.pdf
我將問題分解為由離散變量組成的主問題和具有連續變量的從問題。
我正在使用基於ATSP示例的CPLEX Python API來解決此問題: https : //github.com/cswaroop/cplex-samples/blob/master/bendersatsp.py
在此示例中,我創建了主設備問題和從設備的對偶。
我使用BendersLazyConsCallback
,但是不確定我是否完全理解。 請幫助我。
當獲得當前的主解時,將調用separate
函數,然后更新對偶目標函數,並重新解決對偶問題。
如果對偶是無界的,則將射線添加到主要問題約束中,例如self.add(constraint = workerLP.cutLhs, sense = "L", rhs = workerLP.cutRhs)
,這發生在BendersLazyConsCallback
類中。
但是當對偶最優時,該示例不包括代碼。 因此,當對偶最優時,我添加一個相似的調用,並基於對偶解將約束添加到主問題。
但是,如果我嘗試打印主要問題約束,例如problem.linear_constraints.get_rows()
,則看不到新包含的約束。 似乎self.add(constraint = workerLP.cutLhs, sense = "L", rhs = workerLP.cutRhs)
命令不會將其推送到主約束,而是將其保留為LazyConstraintCallback
類的成員。 這個對嗎? 我如何才能看到實際上添加了這些新約束?
另外,算法如何停止? 在傳統的Benders算法中,問題的下界和上限是根據對偶解和主解進行更新的,當它們相等時,我們便具有收斂性。 在ATSP示例中,我看不到發生了什么。 BendersLazyConsCallback
何時確切觸發,它如何知道何時停止?
您上面鏈接的示例來自CPLEX 12.6。 到目前為止,這已經很舊了(當前最新版本是12.9 )。 如果您尚未更新到最新版本,那么這樣做可能是一個好主意。 更新的原因之一是,使用CPLEX 12.7支持自動Benders分解 。 在CPLEX 12.8中,有一個新的通用回調 (以及一個新的bendersatsp2.py
示例來演示)。
話雖如此,我將嘗試回答您的其他一些問題。
首先,描述在這里 ,如果你寫出來的模型,其將不包括已在回調動態添加懶惰的約束。 您可以自己輕松地在回調中將它們打印出來(例如, print("LC:", workerLP.cutLhs, "G", workerLP.cutRhs)
。您可以通過消息的存在來確定是否已應用約束。在引擎日志的末尾,例如:
應用的用戶削減:3
關於您對惰性約束如何工作的最終疑問,請參見《 CPLEX用戶手冊》中有關舊式回調的部分。 此外,還有關於MIP優化器終止條件的部分。 每當CPLEX找到整數可行的解決方案時,就會調用惰性約束回調(有關更多信息,請參閱IBM developerWorks論壇上的該線程)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.