優(yōu)化問(wèn)題的分治求解之道)
簡(jiǎn)介本資源是一套面向運(yùn)籌學(xué)、管理科學(xué)及工業(yè)優(yōu)化領(lǐng)域研究者與工程師的實(shí)戰(zhàn)型算法實(shí)現(xiàn)聚焦于大規(guī)模兩階段隨機(jī)優(yōu)化問(wèn)題的高效求解。它基于Benders分解框架結(jié)合Gurobi求解器構(gòu)建可擴(kuò)展的迭代求解流程特別適用于電力系統(tǒng)調(diào)度、供應(yīng)鏈魯棒決策等含不確定性參數(shù)的復(fù)雜場(chǎng)景。壓縮包共2000個(gè)文件59.44MB包含63個(gè)核心Python腳本含主算法、子問(wèn)題建模與切割生成邏輯、380個(gè)JSON配置文件定義隨機(jī)場(chǎng)景與參數(shù)分布、133個(gè)XLSX測(cè)試數(shù)據(jù)集覆蓋多規(guī)模算例以及938個(gè)LOG運(yùn)行日志記錄迭代過(guò)程與收斂軌跡結(jié)構(gòu)清晰、即開(kāi)即用。已有309人學(xué)習(xí)下載用戶可直接復(fù)現(xiàn)完整Benders主-子問(wèn)題協(xié)同求解流程驗(yàn)證不同隨機(jī)場(chǎng)景下的策略穩(wěn)健性并基于提供的測(cè)試數(shù)據(jù)快速開(kāi)展參數(shù)調(diào)優(yōu)與性能對(duì)比分析。1. 從“計(jì)劃趕不上變化”說(shuō)起為什么我們需要兩階段隨機(jī)優(yōu)化在供應(yīng)鏈管理、能源調(diào)度或者投資組合這些領(lǐng)域里做規(guī)劃最頭疼的往往不是計(jì)算有多復(fù)雜而是“未來(lái)”充滿了不確定性。比如你是一家電力公司的調(diào)度員今天要決定明天開(kāi)幾臺(tái)發(fā)電機(jī)組第一階段的決策。這個(gè)決策一旦做出成本就鎖定了——開(kāi)機(jī)有固定成本發(fā)電有燃料成本。但問(wèn)題是明天的實(shí)際用電負(fù)荷是多少風(fēng)電和光伏的實(shí)際出力又是多少這些都是隨機(jī)的。如果負(fù)荷低了你多開(kāi)的機(jī)組就浪費(fèi)了如果負(fù)荷高了你沒(méi)開(kāi)的機(jī)組又不夠用只能臨時(shí)啟動(dòng)更昂貴的備用機(jī)組或者從市場(chǎng)上高價(jià)買(mǎi)電第二階段的決策也叫“補(bǔ)救措施”。這種“今天做決定明天看情況補(bǔ)救”的問(wèn)題在數(shù)學(xué)上就被抽象為“兩階段隨機(jī)規(guī)劃”。它的核心思想是我們?cè)谧龅谝浑A段決策時(shí)不能只考慮一種可能的情況而必須考慮所有可能出現(xiàn)的隨機(jī)場(chǎng)景比如高負(fù)荷、中負(fù)荷、低負(fù)荷并為每個(gè)場(chǎng)景都準(zhǔn)備好一個(gè)最優(yōu)的第二階段應(yīng)對(duì)方案。最終的目標(biāo)是找到一個(gè)第一階段決策使得“第一階段的固定成本”加上“所有可能場(chǎng)景下第二階段應(yīng)對(duì)成本的期望值”總和最小。聽(tīng)起來(lái)很合理對(duì)吧但問(wèn)題隨之而來(lái)如果可能的隨機(jī)場(chǎng)景有成千上萬(wàn)個(gè)比如用蒙特卡洛模擬生成那么整個(gè)優(yōu)化模型就會(huì)變得極其龐大變量和約束的數(shù)量爆炸式增長(zhǎng)直接求解幾乎是不可能的。這就好比你要為一座城市的每個(gè)家庭規(guī)劃出行路線如果同時(shí)考慮所有可能的天氣、路況組合計(jì)算量會(huì)大到令人絕望。這時(shí)Benders分解算法就登場(chǎng)了它像一位高超的“分治”指揮官專(zhuān)門(mén)用來(lái)拆解這種大規(guī)模的兩階段隨機(jī)優(yōu)化難題。2. Benders分解化整為零的“分治”藝術(shù)Benders分解算法的精髓在于它巧妙地利用了大規(guī)模兩階段隨機(jī)規(guī)劃問(wèn)題的特殊結(jié)構(gòu)。我們可以把原問(wèn)題想象成這樣一個(gè)畫(huà)面有一個(gè)“主問(wèn)題”負(fù)責(zé)做第一階段的核心決策比如開(kāi)哪些機(jī)組而針對(duì)每一個(gè)隨機(jī)場(chǎng)景都有一個(gè)獨(dú)立的“子問(wèn)題”負(fù)責(zé)計(jì)算在該場(chǎng)景下給定主問(wèn)題的決策后最優(yōu)的第二階段應(yīng)對(duì)方案及其成本。2.1 核心思想主從協(xié)作與割平面Benders分解的核心是迭代求解。它不試圖一口吃掉整個(gè)大模型而是通過(guò)主問(wèn)題和子問(wèn)題之間的反復(fù)“對(duì)話”來(lái)逼近最優(yōu)解。主問(wèn)題 (Master Problem)這是一個(gè)“簡(jiǎn)化版”的模型。它包含了所有第一階段的決策變量和約束但暫時(shí)不知道每個(gè)隨機(jī)場(chǎng)景下的精確成本。最初它假設(shè)第二階段成本是0或者一個(gè)很寬松的下界然后給出一個(gè)第一階段決策的試探解。子問(wèn)題 (Subproblems)針對(duì)每一個(gè)隨機(jī)場(chǎng)景將主問(wèn)題給出的第一階段決策解“固定”下來(lái)然后單獨(dú)求解該場(chǎng)景下的第二階段優(yōu)化問(wèn)題。這個(gè)子問(wèn)題只和當(dāng)前場(chǎng)景的參數(shù)有關(guān)因此通常規(guī)模較小、易于求解。生成“割” (Benders Cut)這是算法的關(guān)鍵。子問(wèn)題求解后會(huì)反饋給主問(wèn)題兩類(lèi)至關(guān)重要的信息可行性割 (Feasibility Cut)如果對(duì)于某個(gè)場(chǎng)景給定的第一階段決策會(huì)導(dǎo)致子問(wèn)題無(wú)解即無(wú)法找到可行的第二階段補(bǔ)救方案那么子問(wèn)題會(huì)生成一個(gè)線性不等式割告訴主問(wèn)題“你剛才給我的那個(gè)決策不行會(huì)導(dǎo)致在某某場(chǎng)景下無(wú)法操作請(qǐng)避免這類(lèi)決策?!边@個(gè)割會(huì)加入到主問(wèn)題的約束中。最優(yōu)性割 (Optimality Cut)如果子問(wèn)題是可行的那么它會(huì)計(jì)算出在該決策和該場(chǎng)景下的最小第二階段成本。更重要的是基于線性規(guī)劃的對(duì)偶理論它能生成一個(gè)關(guān)于第一階段決策變量的線性不等式。這個(gè)不等式的含義是“對(duì)于所有‘類(lèi)似’的第一階段決策你在當(dāng)前場(chǎng)景下的第二階段成本至少是這么多?!边@個(gè)割提供了關(guān)于目標(biāo)函數(shù)更精確的下界信息。主問(wèn)題在吸收了這些來(lái)自所有子問(wèn)題的“割”之后目標(biāo)函數(shù)的下界會(huì)被提升約束也會(huì)更緊。它基于新的信息重新求解得到一個(gè)“更好”的第一階段決策然后再傳遞給子問(wèn)題評(píng)估。如此循環(huán)往復(fù)主問(wèn)題的目標(biāo)函數(shù)值下界和通過(guò)子問(wèn)題計(jì)算得到的實(shí)際期望成本上界會(huì)不斷靠近直到兩者之間的差距小于我們預(yù)設(shè)的容忍精度算法收斂我們就得到了原問(wèn)題的最優(yōu)解。2.2 為什么Benders分解能處理大規(guī)模問(wèn)題它的優(yōu)勢(shì)在于“分解”和“迭代”維度災(zāi)難的破解它將一個(gè)包含海量場(chǎng)景的巨型問(wèn)題分解為一個(gè)主問(wèn)題和許多個(gè)小的、相互獨(dú)立的子問(wèn)題。這些子問(wèn)題可以并行求解極大地利用了計(jì)算資源。避免冗余計(jì)算不是所有場(chǎng)景的信息都對(duì)主問(wèn)題決策有同等影響力。Benders分解通過(guò)“割”的形式只提取那些最關(guān)鍵、最緊的約束信息傳遞給主問(wèn)題避免了處理全部場(chǎng)景細(xì)節(jié)的復(fù)雜度。內(nèi)存友好我們不需要在內(nèi)存中同時(shí)存儲(chǔ)和操作整個(gè)龐大模型的矩陣只需要按需生成和添加割平面這對(duì)處理超大規(guī)模問(wèn)題至關(guān)重要。注意Benders分解的有效性嚴(yán)重依賴(lài)于子問(wèn)題的性質(zhì)。當(dāng)子問(wèn)題是線性規(guī)劃時(shí)生成的割是精確的線性割算法能保證收斂到全局最優(yōu)解。這也是它在兩階段隨機(jī)線性規(guī)劃中應(yīng)用如此廣泛的原因。3. 算法實(shí)現(xiàn)的關(guān)鍵步驟與實(shí)戰(zhàn)細(xì)節(jié)理解了原理我們來(lái)看看如何動(dòng)手實(shí)現(xiàn)一個(gè)基于Benders分解的兩階段隨機(jī)優(yōu)化求解器。這里我們以一個(gè)簡(jiǎn)化的電力機(jī)組組合問(wèn)題為背景進(jìn)行闡述。3.1 問(wèn)題建模將現(xiàn)實(shí)抽象為數(shù)學(xué)首先我們需要用數(shù)學(xué)語(yǔ)言精確描述問(wèn)題。第一階段決策變量x_i(二進(jìn)制變量)表示機(jī)組i是否在日前市場(chǎng)被啟動(dòng)。第一階段成本∑_i (c_i^fix * x_i)即所有開(kāi)機(jī)機(jī)組的固定成本之和。隨機(jī)場(chǎng)景ω ∈ Ω每個(gè)場(chǎng)景代表一種可能的次日負(fù)荷與可再生能源出力組合其發(fā)生概率為p_ω。第二階段決策變量對(duì)于場(chǎng)景ωy_iω(連續(xù)變量)表示機(jī)組i在場(chǎng)景ω下的實(shí)際發(fā)電功率。第二階段成本對(duì)于場(chǎng)景ω∑_i c_i^var * y_iω c^shed * L_shed_ω其中第一項(xiàng)是變動(dòng)發(fā)電成本第二項(xiàng)是負(fù)荷削減的懲罰成本當(dāng)發(fā)電不足時(shí)。約束機(jī)組運(yùn)行約束如果x_i 0則y_iω 0如果x_i 1則P_i_min y_iω P_i_max。功率平衡約束對(duì)于每個(gè)場(chǎng)景ω∑_i y_iω L_shed_ω Demand_ω。網(wǎng)絡(luò)傳輸約束可選考慮線路容量。我們的目標(biāo)是Minimize ∑_i c_i^fix * x_i E_ω [第二階段成本(x, ω)]。3.2 Benders分解算法流程偽代碼實(shí)現(xiàn)下面是一個(gè)高度概括的算法流程框架你可以用Python結(jié)合優(yōu)化求解器如Gurobi, CPLEX來(lái)實(shí)現(xiàn)。import numpy as np from gurobipy import Model, GRB, quicksum def benders_decomposition(scenarios_data, max_iter100, tolerance1e-4): 基于Benders分解求解兩階段隨機(jī)機(jī)組組合問(wèn)題 :param scenarios_data: 列表每個(gè)元素為字典包含場(chǎng)景概率、負(fù)荷、可再生出力等 :param max_iter: 最大迭代次數(shù) :param tolerance: 收斂容忍度 :return: 最優(yōu)第一階段決策x最優(yōu)目標(biāo)值 # ---------------------- 初始化 ---------------------- # 1. 構(gòu)建初始主問(wèn)題MP mp Model(Master_Problem) # 添加第一階段變量 x_i (二進(jìn)制) x mp.addVars(num_units, vtypeGRB.BINARY, namex) # 添加輔助變量 η代表第二階段成本的期望值下界 eta mp.addVar(lb-GRB.INFINITY, nameeta) # 設(shè)置主問(wèn)題目標(biāo)最小化 第一階段成本 η mp.setObjective(quicksum(fixed_cost[i] * x[i] for i in range(num_units)) eta, GRB.MINIMIZE) # 可以添加一些必要的第一階段約束如必須開(kāi)機(jī)的機(jī)組等 UB float(inf) # 全局上界 (Best Known Solution, BKS) LB -float(inf) # 全局下界 iteration 0 cuts_added [] # 存儲(chǔ)已添加的割 # ---------------------- 主迭代循環(huán) ---------------------- while (UB - LB tolerance) and (iteration max_iter): iteration 1 print(f\n--- 迭代 {iteration} ---) # 2. 求解當(dāng)前主問(wèn)題 mp.optimize() if mp.status ! GRB.OPTIMAL: raise Exception(主問(wèn)題不可行或無(wú)界) x_val {i: x[i].X for i in range(num_units)} # 獲取當(dāng)前第一階段解 eta_val eta.X LB mp.ObjVal # 當(dāng)前主問(wèn)題目標(biāo)值即為新的下界 # 3. 固定x_val并行求解所有場(chǎng)景的子問(wèn)題 total_second_stage_cost 0.0 optimality_cuts [] feasibility_cuts [] for idx_omega, scenario in enumerate(scenarios_data): sp_model, sp_vars build_subproblem(scenario, x_val) # 構(gòu)建子問(wèn)題模型 sp_model.optimize() if sp_model.status GRB.OPTIMAL: # 子問(wèn)題可行且最優(yōu) scenario_cost sp_model.ObjVal total_second_stage_cost scenario[probability] * scenario_cost # **關(guān)鍵步驟獲取子問(wèn)題的對(duì)偶變量值用于生成最優(yōu)性割** # 假設(shè)子問(wèn)題中與第一階段決策x耦合的約束是 y_iω P_i_max * x_i_val # 該約束的對(duì)偶變量值為 π_iω (假設(shè)已獲取) # 最優(yōu)性割的一般形式為η ≥ L(x)其中L(x)是一個(gè)關(guān)于x的線性函數(shù)。 # 對(duì)于線性子問(wèn)題這個(gè)線性函數(shù)可以通過(guò)對(duì)偶解構(gòu)造 # η ≥ ∑_ω p_ω * [ sp_obj_const_part ∑_i π_iω * (P_i_max * x_i) ] # 其中 sp_obj_const_part 是子問(wèn)題中與x無(wú)關(guān)部分的目標(biāo)值。 # 這里簡(jiǎn)化表示實(shí)際需根據(jù)對(duì)偶模型推導(dǎo)。 pi ... # 獲取相關(guān)對(duì)偶變量的值 constant_part ... # 計(jì)算常數(shù)部分 cut_coeff {i: pi[i] * P_max[i] for i in range(num_units)} cut_rhs constant_part optimality_cuts.append((cut_coeff, cut_rhs)) elif sp_model.status GRB.INFEASIBLE: # 子問(wèn)題不可行需要生成可行性割 # 同樣需要通過(guò)求解子問(wèn)題的不可行證明Farkas對(duì)偶來(lái)獲得可行性割的系數(shù) # 可行性割形式通常為 ∑_i α_i * x_i ≥ β 要求主問(wèn)題的決策必須滿足此式否則會(huì)導(dǎo)致該場(chǎng)景不可行。 farkas_dual ... # 獲取Farkas對(duì)偶解 alpha {i: farkas_dual[i] for i in range(num_units)} beta ... # 計(jì)算RHS feasibility_cuts.append((alpha, beta)) else: raise Exception(f場(chǎng)景 {idx_omega} 子問(wèn)題求解異常) # 4. 計(jì)算當(dāng)前上界 (UB) current_first_stage_cost sum(fixed_cost[i] * x_val[i] for i in range(num_units)) candidate_UB current_first_stage_cost total_second_stage_cost if candidate_UB UB: UB candidate_UB best_x_solution x_val.copy() # 保存當(dāng)前最優(yōu)解 print(f下界(LB): {LB:.2f}, 上界(UB): {UB:.2f}, 間隙(Gap): {(UB-LB)/UB*100:.2f}%) # 5. 收斂性檢查 if UB - LB tolerance: print(已收斂) break # 6. 向主問(wèn)題添加新生成的割 # 添加最優(yōu)性割 for coeff, rhs in optimality_cuts: # 添加約束: eta constant sum(coeff[i] * x[i] for i in ...) mp.addConstr(eta rhs quicksum(coeff[i] * x[i] for i in range(num_units)), namefOptCut_iter{iteration}) # 添加可行性割 for alpha, beta in feasibility_cuts: mp.addConstr(quicksum(alpha[i] * x[i] for i in range(num_units)) beta, namefFeasCut_iter{iteration}) # ---------------------- 輸出結(jié)果 ---------------------- print(f\n算法終止于迭代 {iteration} 次) print(f最優(yōu)目標(biāo)值范圍: [{LB:.2f}, {UB:.2f}]) print(最優(yōu)第一階段決策開(kāi)機(jī)方案:) for i, val in best_x_solution.items(): if val 0.5: print(f 機(jī)組 {i}: 開(kāi)機(jī)) return best_x_solution, (LB, UB) # 需要獨(dú)立實(shí)現(xiàn)的函數(shù)根據(jù)場(chǎng)景和固定的x構(gòu)建子問(wèn)題模型 def build_subproblem(scenario, x_fixed): sp Model(Subproblem) # 添加第二階段變量 y_i y sp.addVars(num_units, lb0, namey) # 添加負(fù)荷削減變量 l_shed l_shed sp.addVar(lb0, nameload_shed) # 目標(biāo)最小化該場(chǎng)景下的第二階段成本 sp.setObjective(quicksum(var_cost[i] * y[i] for i in range(num_units)) shed_penalty * l_shed, GRB.MINIMIZE) # 約束1發(fā)電上下限約束且與第一階段決策耦合 for i in range(num_units): sp.addConstr(y[i] P_max[i] * x_fixed[i], namefcap_{i}) # x_fixed是傳入的固定值 sp.addConstr(y[i] P_min[i] * x_fixed[i], namefmin_{i}) # 約束2功率平衡 sp.addConstr(quicksum(y[i] for i in range(num_units)) l_shed scenario[demand], namebalance) # ... 其他約束如爬坡、網(wǎng)絡(luò)等 return sp, y3.3 幾個(gè)你必須關(guān)注的實(shí)現(xiàn)難點(diǎn)割的管理與篩選在迭代后期主問(wèn)題中可能會(huì)積累大量割平面導(dǎo)致主問(wèn)題越來(lái)越難解。一個(gè)實(shí)用的技巧是“割池管理”定期移除那些長(zhǎng)期不活躍松馳變量遠(yuǎn)離邊界的割或者只添加“帕累托最優(yōu)”的割以控制主問(wèn)題規(guī)模。初始割與上界啟發(fā)式一個(gè)空的或只有簡(jiǎn)單約束的主問(wèn)題其初始解可能非常差導(dǎo)致前幾次迭代效率低下。我們可以采用“啟發(fā)式”方法快速找到一個(gè)較好的可行第一階段解計(jì)算其對(duì)應(yīng)的上界并生成對(duì)應(yīng)的初始最優(yōu)性割從而加速收斂。并行求解子問(wèn)題這是Benders分解性能提升的關(guān)鍵。所有場(chǎng)景的子問(wèn)題在每次迭代中都是獨(dú)立的完全可以并行求解。使用Python的multiprocessing庫(kù)或joblib可以輕松實(shí)現(xiàn)能將計(jì)算時(shí)間縮短近N倍N為進(jìn)程數(shù)。處理整數(shù)變量如果第一階段決策變量是整數(shù)如我們的例子主問(wèn)題就是一個(gè)混合整數(shù)規(guī)劃。Benders分解仍然適用但收斂理論更為復(fù)雜可能需要更多的迭代。如果第二階段也包含整數(shù)變量如啟動(dòng)備用機(jī)組那么子問(wèn)題就是MIP生成割將不再是簡(jiǎn)單的線性割而需要更復(fù)雜的整數(shù)規(guī)劃對(duì)偶方法難度急劇增加。4. 性能優(yōu)化與高級(jí)技巧讓算法飛起來(lái)基本的Benders分解框架可能收斂較慢尤其是在場(chǎng)景數(shù)眾多、問(wèn)題規(guī)模大時(shí)。以下是一些經(jīng)過(guò)實(shí)踐檢驗(yàn)的加速策略。4.1 多割生成與聚合在每次迭代中每個(gè)場(chǎng)景的子問(wèn)題都會(huì)產(chǎn)生一條割。如果有1000個(gè)場(chǎng)景一次迭代就會(huì)向主問(wèn)題添加1000條割這會(huì)使主問(wèn)題迅速膨脹。有兩種改進(jìn)思路單割聚合將所有場(chǎng)景產(chǎn)生的割按概率加權(quán)平均合并成一條“聚合割”添加到主問(wèn)題。這大幅減少了主問(wèn)題的約束數(shù)量但可能會(huì)損失一些信息導(dǎo)致收斂所需迭代次數(shù)增加。多割這是標(biāo)準(zhǔn)做法即每個(gè)場(chǎng)景的割獨(dú)立添加。為了平衡可以采用“信任域”或“正則化”技術(shù)防止主問(wèn)題的決策在兩次迭代間跳動(dòng)過(guò)大從而穩(wěn)定收斂過(guò)程。4.2 利用問(wèn)題的特殊結(jié)構(gòu)L形算法對(duì)于兩階段隨機(jī)線性規(guī)劃Benders分解有一個(gè)更具體的名稱(chēng)L形算法。這個(gè)名字來(lái)源于其迭代過(guò)程中主問(wèn)題與子問(wèn)題信息交換的框圖看起來(lái)像一個(gè)“L”。深入理解這一點(diǎn)可以幫助我們?cè)O(shè)計(jì)更高效的割生成方式。例如當(dāng)隨機(jī)參數(shù)只出現(xiàn)在約束右端項(xiàng)時(shí)子問(wèn)題的可行域結(jié)構(gòu)對(duì)所有場(chǎng)景是相同的只有目標(biāo)函數(shù)系數(shù)不同。這種情況下可以推導(dǎo)出更緊致的割形式。4.3 現(xiàn)代求解器的回調(diào)函數(shù)應(yīng)用像Gurobi、CPLEX這樣的商業(yè)求解器提供了強(qiáng)大的回調(diào)函數(shù)功能。我們可以實(shí)現(xiàn)一個(gè)“惰性約束回調(diào)”。具體做法是將主問(wèn)題構(gòu)建為一個(gè)混合整數(shù)規(guī)劃模型但不包含任何Benders割。在求解過(guò)程中每當(dāng)求解器找到一個(gè)可行的整數(shù)解候選的第一階段決策就觸發(fā)回調(diào)函數(shù)。在回調(diào)函數(shù)中固定這個(gè)候選解快速求解所有子問(wèn)題或通過(guò)一些方法估計(jì)第二階段成本。如果發(fā)現(xiàn)候選解不可行或目標(biāo)值可以改進(jìn)就當(dāng)場(chǎng)生成相應(yīng)的Benders割作為惰性約束提交給求解器。 這種方法將Benders分解的邏輯深度集成到MIP求解器的分支定界樹(shù)搜索中有時(shí)能獲得比傳統(tǒng)迭代框架更好的性能。4.4 分布式與云計(jì)算實(shí)現(xiàn)對(duì)于國(guó)家級(jí)電網(wǎng)、全球供應(yīng)鏈網(wǎng)絡(luò)等超大規(guī)模問(wèn)題場(chǎng)景數(shù)可能達(dá)到百萬(wàn)級(jí)。此時(shí)單機(jī)內(nèi)存和計(jì)算核心都成為瓶頸。真正的解決方案是分布式計(jì)算。你可以使用類(lèi)似PySpark、Dask這樣的框架將場(chǎng)景集合分布到計(jì)算集群的多個(gè)節(jié)點(diǎn)上。每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分場(chǎng)景的子問(wèn)題求解和局部割的生成然后由一個(gè)協(xié)調(diào)節(jié)點(diǎn)負(fù)責(zé)主問(wèn)題匯總所有割并進(jìn)行聚合。云平臺(tái)如AWS Batch, Azure Batch為這種計(jì)算模式提供了彈性、低成本的基礎(chǔ)設(shè)施。實(shí)操心得在項(xiàng)目初期不要過(guò)度追求高級(jí)優(yōu)化技巧。先用標(biāo)準(zhǔn)Benders分解實(shí)現(xiàn)一個(gè)可工作的原型確保模型正確、割生成無(wú)誤。然后用性能分析工具定位瓶頸。通常80%的時(shí)間可能花在子問(wèn)題求解或主問(wèn)題求解上。如果是子問(wèn)題慢優(yōu)先考慮并行化如果是主問(wèn)題慢再考慮割管理策略。過(guò)早優(yōu)化是萬(wàn)惡之源。本文還有配套的精品資源點(diǎn)擊獲取