劃建模與MATLAB求解:從數(shù)學(xué)原理到工程實(shí)踐)
1. 從一道題開始為什么線性規(guī)劃是數(shù)學(xué)建模的“萬金油”如果你參加過數(shù)學(xué)建模競(jìng)賽或者處理過任何涉及資源分配、成本優(yōu)化、生產(chǎn)計(jì)劃的問題大概率會(huì)聽過“線性規(guī)劃”這個(gè)名字。它聽起來有點(diǎn)學(xué)術(shù)但本質(zhì)上它是一種幫你做“最優(yōu)選擇”的數(shù)學(xué)工具。想象一下你是一個(gè)工廠的廠長(zhǎng)手頭有有限的原料、機(jī)器工時(shí)和人力需要生產(chǎn)幾種產(chǎn)品來最大化利潤(rùn)。每種產(chǎn)品消耗的原料、工時(shí)不同帶來的利潤(rùn)也不同。你怎么安排生產(chǎn)計(jì)劃才能在現(xiàn)有條件下賺到最多的錢線性規(guī)劃就是解決這類問題的標(biāo)準(zhǔn)答案。在數(shù)學(xué)建模中線性規(guī)劃之所以被稱為“萬金油”是因?yàn)樗膽?yīng)用場(chǎng)景實(shí)在太廣泛了。從剛才提到的生產(chǎn)調(diào)度、物流運(yùn)輸如何安排車輛路線使總運(yùn)費(fèi)最低到金融投資如何在風(fēng)險(xiǎn)約束下最大化收益再到能源分配、甚至廣告投放預(yù)算的優(yōu)化其核心都可以抽象為一個(gè)線性規(guī)劃模型。它的強(qiáng)大之處在于只要你的目標(biāo)比如利潤(rùn)、成本和所有限制條件比如資源上限、需求下限都能用線性關(guān)系即一次方程或不等式來描述那么理論上就存在一個(gè)高效、確定的算法幫你找到那個(gè)最優(yōu)解。而MATLAB作為工程和科學(xué)計(jì)算領(lǐng)域的標(biāo)桿工具內(nèi)置了強(qiáng)大且易用的線性規(guī)劃求解器。它把復(fù)雜的算法封裝成簡(jiǎn)單的函數(shù)調(diào)用讓你能專注于問題建模本身而不是算法的實(shí)現(xiàn)細(xì)節(jié)。這就像你有了一個(gè)頂級(jí)的賽車引擎只需要學(xué)會(huì)踩油門和打方向盤就能跑出驚人的速度。本文的目的就是帶你從零開始理解線性規(guī)劃的核心思想并掌握用MATLAB將其落地解決實(shí)際問題的完整流程。無論你是備戰(zhàn)數(shù)學(xué)建模競(jìng)賽的學(xué)生還是工作中需要處理優(yōu)化問題的工程師這篇內(nèi)容都將提供一條清晰的路徑。2. 線性規(guī)劃模型拆解三要素與標(biāo)準(zhǔn)型在動(dòng)手寫代碼之前我們必須把問題“翻譯”成數(shù)學(xué)語言。一個(gè)完整的線性規(guī)劃模型包含三個(gè)核心要素決策變量、目標(biāo)函數(shù)和約束條件。2.1 決策變量你要決定什么決策變量就是你能夠控制、需要求解的未知數(shù)。在工廠例子中就是你決定生產(chǎn)每種產(chǎn)品的數(shù)量。我們通常用 ( x_1, x_2, ..., x_n ) 來表示。例如( x_1 ) 代表產(chǎn)品A的產(chǎn)量( x_2 ) 代表產(chǎn)品B的產(chǎn)量。這些變量必須是連續(xù)且非負(fù)的在標(biāo)準(zhǔn)線性規(guī)劃中因?yàn)槟悴荒苌a(chǎn)負(fù)數(shù)量的產(chǎn)品。2.2 目標(biāo)函數(shù)你要優(yōu)化什么目標(biāo)函數(shù)就是你希望最大化或最小化的那個(gè)量。它必須是決策變量的線性函數(shù)。在最大化利潤(rùn)的例子中如果生產(chǎn)一件產(chǎn)品A利潤(rùn)是3元產(chǎn)品B利潤(rùn)是5元那么總利潤(rùn) ( Z 3x_1 5x_2 )。我們的目標(biāo)就是最大化 ( Z )寫作 ( \max Z 3x_1 5x_2 )。如果是成本最小化問題目標(biāo)函數(shù)就是 ( \min Z c_1x_1 c_2x_2 ... )。2.3 約束條件你受到哪些限制約束條件描述了決策變量必須遵守的規(guī)則同樣用線性等式或不等式表示。繼續(xù)工廠的例子原料約束生產(chǎn)一件A耗料2kg一件B耗料4kg總原料只有100kg。那么約束為( 2x_1 4x_2 \leq 100 )。工時(shí)約束生產(chǎn)一件A需1小時(shí)一件B需3小時(shí)總工時(shí)只有80小時(shí)。那么約束為( 1x_1 3x_2 \leq 80 )。非負(fù)約束產(chǎn)量不能為負(fù)即 ( x_1 \geq 0, x_2 \geq 0 )。2.4 線性規(guī)劃的標(biāo)準(zhǔn)形式為了便于算法求解我們通常將模型轉(zhuǎn)化為標(biāo)準(zhǔn)形式。MATLAB的求解器也要求輸入標(biāo)準(zhǔn)形式。標(biāo)準(zhǔn)形式規(guī)定如下目標(biāo)函數(shù)為最小化Minimize。所有約束條件均為等式Equality。所有決策變量非負(fù)。因此對(duì)于任何線性規(guī)劃問題我們都需要做如下轉(zhuǎn)換最大化轉(zhuǎn)最小化如果原問題是 ( \max Z c^Tx )等價(jià)于 ( \min -Z -c^Tx )。求出最小化問題的解后目標(biāo)函數(shù)值取反即可。不等式轉(zhuǎn)等式對(duì)于“小于等于”約束 ( Ax \leq b )我們引入松弛變量( s )同樣非負(fù)將其變?yōu)?( Ax s b )。對(duì)于“大于等于”約束 ( Ax \geq b )則引入剩余變量( s )變?yōu)?( Ax - s b )。例如我們的工廠問題標(biāo)準(zhǔn)形式為 [ \begin{aligned} \min \quad -Z -3x_1 - 5x_2 \ \text{s.t.} \quad 2x_1 4x_2 s_1 100 \ 1x_1 3x_2 s_2 80 \ x_1, x_2, s_1, s_2 \geq 0 \end{aligned} ] 其中 ( s_1, s_2 ) 是松弛變量分別代表剩余的原料和工時(shí)。理解這個(gè)標(biāo)準(zhǔn)形式是使用MATLAB求解器的關(guān)鍵。3. MATLAB求解實(shí)戰(zhàn)linprog函數(shù)深度解析MATLAB解決線性規(guī)劃的核心函數(shù)是linprog。它的語法直接對(duì)應(yīng)線性規(guī)劃的標(biāo)準(zhǔn)形式。我們以上面的工廠問題為例演示從建模到求解的全過程。3.1 問題回顧與參數(shù)準(zhǔn)備原問題最大化利潤(rùn) ( Z 3x_1 5x_2 ) 約束 [ \begin{cases} 2x_1 4x_2 \leq 100 \ x_1 3x_2 \leq 80 \ x_1, x_2 \geq 0 \end{cases} ]轉(zhuǎn)換為linprog所需的標(biāo)準(zhǔn)最小化形式目標(biāo)函數(shù)系數(shù)向量f: 原最大化系數(shù)取負(fù)即f [-3; -5]。不等式約束矩陣A和向量b: 對(duì)應(yīng) ( Ax \leq b )即A [2, 4; 1, 3],b [100; 80]。變量下界lb: 非負(fù)約束即lb [0; 0]。上界ub默認(rèn)為無窮大 (Inf)無需指定。等式約束Aeq,beq本例沒有等式約束留空 ([])。3.2linprog基礎(chǔ)調(diào)用與結(jié)果解讀% 定義參數(shù) f [-3; -5]; % 目標(biāo)函數(shù)系數(shù)注意負(fù)號(hào) A [2, 4; 1, 3]; b [100; 80]; lb [0; 0]; % 調(diào)用linprog求解 options optimoptions(linprog, Display, iter); % 顯示迭代過程 [x, fval, exitflag, output] linprog(f, A, b, [], [], lb, [], options); % 輸出結(jié)果 disp(最優(yōu)生產(chǎn)計(jì)劃); disp([產(chǎn)品A產(chǎn)量 x1 , num2str(x(1))]); disp([產(chǎn)品B產(chǎn)量 x2 , num2str(x(2))]); disp([最大利潤(rùn) Z , num2str(-fval)]); % 注意fval是最小化目標(biāo)值取負(fù)得最大利潤(rùn) disp([求解器狀態(tài) exitflag , num2str(exitflag)]); disp(output.message);運(yùn)行這段代碼MATLAB會(huì)輸出類似以下結(jié)果最優(yōu)生產(chǎn)計(jì)劃 產(chǎn)品A產(chǎn)量 x1 20 產(chǎn)品B產(chǎn)量 x2 20 最大利潤(rùn) Z 160 求解器狀態(tài) exitflag 1 Optimization terminated.注意exitflag是理解求解是否成功的關(guān)鍵。exitflag 1表示算法收斂到了最優(yōu)解。其他常見值有0迭代次數(shù)超限可能未收斂-2無可行解約束矛盾-3問題無界目標(biāo)函數(shù)值可無限優(yōu)化。務(wù)必檢查此標(biāo)志位3.3 處理等式約束與變量邊界如果問題中包含等式約束或者變量有特定上下界就需要用到Aeq,beq和ub。 假設(shè)問題增加一個(gè)約束兩種產(chǎn)品的總產(chǎn)量必須恰好為50件等式約束且產(chǎn)品A的產(chǎn)量不能超過30件上界約束。 模型變?yōu)?[ \begin{aligned} \max \quad Z 3x_1 5x_2 \ \text{s.t.} \quad 2x_1 4x_2 \leq 100 \ x_1 3x_2 \leq 80 \ x_1 x_2 50 \quad \text{(新增等式約束)} \ 0 \leq x_1 \leq 30 \quad \text{(新增上界)} \ x_2 \geq 0 \end{aligned} ]對(duì)應(yīng)MATLAB代碼f [-3; -5]; A [2, 4; 1, 3]; b [100; 80]; Aeq [1, 1]; % 等式約束系數(shù)矩陣 beq [50]; % 等式約束右端項(xiàng) lb [0; 0]; ub [30; Inf]; % 變量上界向量 [x, fval] linprog(f, A, b, Aeq, beq, lb, ub); disp([x1, num2str(x(1)), , x2, num2str(x(2)), , 最大利潤(rùn), num2str(-fval)]);3.4 算法選擇與選項(xiàng)設(shè)置linprog默認(rèn)使用“對(duì)偶單純形法”。對(duì)于不同規(guī)模變量和約束數(shù)量和特性稀疏性的問題選擇合適的算法能提升求解效率和穩(wěn)定性??梢酝ㄟ^optimoptions設(shè)置。options optimoptions(linprog, Algorithm, interior-point, ... % 使用內(nèi)點(diǎn)法 OptimalityTolerance, 1e-8, ... % 優(yōu)化容忍度 ConstraintTolerance, 1e-6, ... % 約束容忍度 Display, final); % 顯示最終結(jié)果 [x, fval] linprog(f, A, b, Aeq, beq, lb, ub, options);dual-simplex默認(rèn)對(duì)偶單純形法。對(duì)于重新求解或約束條件增減后的熱啟動(dòng)非常高效尤其適合中等規(guī)模、需要頻繁修改的問題。interior-point內(nèi)點(diǎn)法。對(duì)于大規(guī)模、稀疏的問題通常更快內(nèi)存消耗更可控。但它給出的解可能在邊界附近嚴(yán)格意義上不是“基本可行解”。interior-point-legacy舊版內(nèi)點(diǎn)法穩(wěn)定性可能更好。實(shí)操心得對(duì)于數(shù)學(xué)建模競(jìng)賽中的問題規(guī)模通常不大用默認(rèn)算法即可。如果遇到求解速度慢或數(shù)值不穩(wěn)定比如exitflag不是1可以嘗試切換算法或調(diào)整容忍度。一個(gè)常見技巧是如果問題可行但求解器報(bào)告無解可以嘗試稍微放松ConstraintTolerance如從1e-6調(diào)到1e-4這可能是由于數(shù)值精度導(dǎo)致的“假性不可行”。4. 建模競(jìng)賽中的典型應(yīng)用場(chǎng)景與建模技巧在數(shù)學(xué)建模競(jìng)賽中直接給出線性規(guī)劃形式的問題較少更多是需要你將一個(gè)現(xiàn)實(shí)問題抽象成線性規(guī)劃模型。這考驗(yàn)的是建模能力。4.1 資源分配問題這是最經(jīng)典的場(chǎng)景。例如2026年亞太杯數(shù)學(xué)建模A題可能涉及水資源、電力或計(jì)算資源的分配。關(guān)鍵步驟定義決策變量變量通常直接對(duì)應(yīng)分配量如 ( x_{ij} ) 表示從資源點(diǎn) ( i ) 分配到用戶 ( j ) 的量。目標(biāo)函數(shù)最小化總成本或總運(yùn)輸距離或最大化總效益。成本/效益系數(shù)需要根據(jù)題意確定。約束條件供應(yīng)約束每個(gè)資源點(diǎn)的輸出總量不超過其能力。( \sum_j x_{ij} \leq Supply_i )。需求約束每個(gè)用戶的需求必須被滿足。( \sum_i x_{ij} \geq Demand_j )。非負(fù)約束( x_{ij} \geq 0 )。4.2 生產(chǎn)計(jì)劃與庫(kù)存管理例如國(guó)賽2019年C題“機(jī)場(chǎng)出租車調(diào)度”可以部分抽象為生產(chǎn)計(jì)劃問題將出租車視為“產(chǎn)品”將不同等待區(qū)的乘客視為“需求”。決策變量每個(gè)時(shí)段生產(chǎn)或調(diào)度的數(shù)量。目標(biāo)函數(shù)最小化總成本生產(chǎn)成本庫(kù)存持有成本缺貨成本。約束條件生產(chǎn)能力約束、庫(kù)存平衡方程本期庫(kù)存上期庫(kù)存本期產(chǎn)量-本期需求、服務(wù)水平約束缺貨率上限。4.3 投資組合優(yōu)化簡(jiǎn)化版在金融背景下馬科維茨的均值-方差模型在固定預(yù)期收益下最小化風(fēng)險(xiǎn)其核心是一個(gè)二次規(guī)劃。但如果對(duì)資產(chǎn)配置比例有線性約束如單只股票持倉(cāng)上限、行業(yè)配置比例范圍或者目標(biāo)是最小化交易成本與交易量線性相關(guān)那么這部分可以構(gòu)成線性規(guī)劃問題。決策變量投資于各資產(chǎn)的比例 ( w_i ) 或金額。目標(biāo)函數(shù)最小化總交易費(fèi)用 ( \sum c_i |\Delta w_i| )。注意絕對(duì)值需要線性化處理引入兩個(gè)非負(fù)變量分別代表買入和賣出。約束條件預(yù)算約束 ( \sum w_i 1 )預(yù)期收益率約束 ( \sum (w_i * r_i) \geq R_{target} )以及各類線性比例約束。4.4 多階段決策與動(dòng)態(tài)規(guī)劃的聯(lián)系有些問題看似是動(dòng)態(tài)的如多期生產(chǎn)但若各期之間耦合不緊密或可以引入輔助變量如庫(kù)存來連接仍可轉(zhuǎn)化為一個(gè)大型的線性規(guī)劃問題。此時(shí)決策變量會(huì)帶上時(shí)間下標(biāo) ( x_t )約束條件會(huì)包含跨時(shí)期的平衡方程。雖然變量增多但linprog依然可以求解。這比編寫動(dòng)態(tài)規(guī)劃代碼更通用尤其當(dāng)狀態(tài)空間連續(xù)時(shí)。建模技巧當(dāng)遇到“如果...那么...”的邏輯條件時(shí)線性規(guī)劃無法直接處理。這時(shí)需要引入0-1整數(shù)變量將問題轉(zhuǎn)化為混合整數(shù)線性規(guī)劃需要使用intlinprog函數(shù)。這是線性規(guī)劃的重要擴(kuò)展。例如“如果開設(shè)倉(cāng)庫(kù)A則必須至少向5個(gè)客戶供貨”這種固定成本或邏輯依賴關(guān)系就必須引入整數(shù)變量。5. 代碼調(diào)試與結(jié)果分析從“跑通”到“讀懂”把代碼跑出結(jié)果只是第一步更重要的是驗(yàn)證結(jié)果的正確性和分析其含義。5.1 模型正確性驗(yàn)證可行性檢查將求得的解x代回所有約束條件手動(dòng)計(jì)算是否滿足。可以寫一小段代碼自動(dòng)驗(yàn)證% 驗(yàn)證不等式約束 Ax b constraint_violation A * x - b; if any(constraint_violation 1e-6) % 考慮數(shù)值誤差 disp(警告不等式約束可能未滿足); disp(constraint_violation); end % 驗(yàn)證等式約束 Aeq*x beq if ~isempty(Aeq) eq_violation abs(Aeq * x - beq); if any(eq_violation 1e-6) disp(警告等式約束可能未滿足); disp(eq_violation); end end敏感性分析影子價(jià)格linprog可以輸出拉格朗日乘子lambda它反映了約束條件的“稀缺性”或“價(jià)值”。[x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub); disp(不等式約束的影子價(jià)格對(duì)偶變量); disp(lambda.ineqlin); disp(等式約束的影子價(jià)格); disp(lambda.eqlin); disp(變量下界的影子價(jià)格); disp(lambda.lower);lambda.ineqlin(i)的含義是第i個(gè)不等式約束的右端項(xiàng)b(i)每增加一個(gè)微小單位最優(yōu)目標(biāo)函數(shù)值在最小化問題中能改善多少。在工廠例子中如果原料約束的影子價(jià)格是0.5意味著每增加1kg原料最大利潤(rùn)能增加0.5元。這為資源采購(gòu)決策提供了量化依據(jù)。5.2 結(jié)果可視化與解釋對(duì)于二維或三維問題畫圖能直觀理解解的位置。% 針對(duì)最初的工廠問題二維 % 繪制約束區(qū)域 [x1, x2] meshgrid(0:1:50, 0:1:40); cond1 2*x1 4*x2 100; cond2 x1 3*x2 80; feasible cond1 cond2; figure; hold on; % 繪制可行域 scatter(x1(feasible), x2(feasible), 5, blue, filled, DisplayName, 可行域); % 繪制約束線 fplot((x) (100 - 2*x)/4, [0, 50], r-, LineWidth, 2, DisplayName, 2x14x2100); fplot((x) (80 - x)/3, [0, 50], g-, LineWidth, 2, DisplayName, x13x280); % 繪制目標(biāo)函數(shù)等值線及最優(yōu)解點(diǎn) contour(x1, x2, 3*x15*x2, 30, k:, ShowText,off); plot(20, 20, rp, MarkerSize, 15, MarkerFaceColor, red, DisplayName, 最優(yōu)解 (20,20)); xlabel(產(chǎn)品A產(chǎn)量 x1); ylabel(產(chǎn)品B產(chǎn)量 x2); title(線性規(guī)劃問題可行域與最優(yōu)解); legend(Location, best); grid on; hold off;通過圖形你可以清晰地看到由約束圍成的可行域多邊形目標(biāo)函數(shù)的等值線平行直線以及最優(yōu)解出現(xiàn)在可行域的一個(gè)頂點(diǎn)上。這正是線性規(guī)劃的一個(gè)基本定理最優(yōu)解如果存在必定在可行域的某個(gè)頂點(diǎn)取得。5.3 常見錯(cuò)誤與排查No feasible solution found問題不可行。檢查約束條件是否互相矛盾。例如要求 ( x1 x2 10 ) 同時(shí)又要求 ( x1 3, x2 4 )。仔細(xì)檢查建模時(shí)的等號(hào)與不等號(hào)方向以及數(shù)據(jù)單位是否統(tǒng)一。Problem is unbounded問題無界。通常是因?yàn)槿鄙俦匾募s束使得目標(biāo)函數(shù)可以無限優(yōu)化。例如在最大化利潤(rùn)時(shí)如果沒有資源約束產(chǎn)量可以無限大。檢查是否遺漏了關(guān)鍵的限制條件。數(shù)值不穩(wěn)定結(jié)果異??赡苡捎谙禂?shù)數(shù)量級(jí)差異巨大如一個(gè)系數(shù)是1e6另一個(gè)是1e-6導(dǎo)致。嘗試對(duì)模型進(jìn)行縮放即將決策變量或約束進(jìn)行線性變換使系數(shù)范圍集中在1附近。例如如果x1代表以“萬噸”為單位的量可以改為以“噸”為單位系數(shù)相應(yīng)調(diào)整。求解速度慢對(duì)于大規(guī)模問題嘗試使用interior-point算法。檢查模型是否包含大量稀疏矩陣并利用MATLAB的稀疏矩陣格式sparse來存儲(chǔ)A和Aeq可以極大節(jié)省內(nèi)存和計(jì)算時(shí)間。6. 從線性規(guī)劃到混合整數(shù)規(guī)劃intlinprog入門當(dāng)問題中部分變量必須取整數(shù)值如物品數(shù)量、是否選擇的0-1決策時(shí)就需要用到混合整數(shù)線性規(guī)劃。MATLAB中的intlinprog函數(shù)是linprog的自然延伸。6.1 0-1變量建模實(shí)例考慮一個(gè)簡(jiǎn)單的背包問題有若干物品每個(gè)有重量和價(jià)值背包容量有限如何選擇物品使總價(jià)值最大設(shè)物品i的重量為w_i價(jià)值為v_i背包容量為W。決策變量( x_i \in {0, 1} )1表示選擇物品i0表示不選。目標(biāo)函數(shù)最大化總價(jià)值 ( \max \sum v_i x_i )。約束條件總重量不超過容量 ( \sum w_i x_i \leq W )。6.2intlinprog求解intlinprog語法與linprog類似但多了一個(gè)intcon參數(shù)用于指定哪些變量是整數(shù)變量。% 示例數(shù)據(jù) v [10, 20, 15, 7, 5]; % 價(jià)值 w [3, 5, 4, 2, 1]; % 重量 W 10; % 背包容量 f -v; % 轉(zhuǎn)為最小化目標(biāo)取負(fù) A w; b W; lb zeros(5,1); ub ones(5,1); % 0-1變量上界為1 intcon 1:5; % 所有5個(gè)變量都是整數(shù)變量 [x, fval] intlinprog(f, intcon, A, b, [], [], lb, ub); disp(選擇的物品索引); disp(find(x 0.5)); % 由于數(shù)值解判斷大于0.5即為1 disp([最大總價(jià)值, num2str(-fval)]);6.3 復(fù)雜邏輯約束的線性化這是混合整數(shù)規(guī)劃建模的核心技巧。例如“如果選擇項(xiàng)目Ax_A1則必須同時(shí)選擇項(xiàng)目Bx_B1”。這可以表示為線性約束( x_A - x_B \leq 0 )。因?yàn)楫?dāng) ( x_A1 ) 時(shí)此式強(qiáng)制 ( x_B \geq 1 )而 ( x_B ) 是0-1變量所以 ( x_B ) 必須為1。類似地“項(xiàng)目C和項(xiàng)目D最多只能選一個(gè)”可以表示為( x_C x_D \leq 1 )。掌握這些基本約束的轉(zhuǎn)化能讓你用線性規(guī)劃框架處理大量離散決策問題。踩坑實(shí)錄整數(shù)規(guī)劃求解時(shí)間可能隨問題規(guī)模指數(shù)增長(zhǎng)。對(duì)于競(jìng)賽如果變量不多幾十個(gè)intlinprog通常能在可接受時(shí)間內(nèi)求解。如果超時(shí)可以嘗試設(shè)置MaxTime選項(xiàng)限制求解時(shí)間或調(diào)整Heuristics和CutGeneration選項(xiàng)來加速。有時(shí)放松整數(shù)要求先求線性規(guī)劃松弛解能提供一個(gè)最優(yōu)值的上界對(duì)于最大化問題有助于評(píng)估整數(shù)解的質(zhì)量。7. 實(shí)戰(zhàn)進(jìn)階將模型、求解與可視化封裝為函數(shù)在數(shù)學(xué)建模競(jìng)賽中清晰、可復(fù)用的代碼結(jié)構(gòu)至關(guān)重要。建議將整個(gè)建模求解過程封裝成函數(shù)或腳本模塊。function [opt_x, opt_val, exit_flag, lambda] solve_production_plan(profit, resource_cons, resource_limit, eq_cons, eq_limit, lb, ub) % 求解生產(chǎn)計(jì)劃線性規(guī)劃問題 % 輸入 % profit: 產(chǎn)品利潤(rùn)系數(shù)向量 [n x 1] % resource_cons: 資源消耗系數(shù)矩陣 [m x n] % resource_limit: 資源上限向量 [m x 1] % eq_cons: 等式約束矩陣 [p x n] (可選) % eq_limit: 等式約束右端項(xiàng) [p x 1] (可選) % lb, ub: 變量上下界 [n x 1] (可選) % 輸出 % opt_x: 最優(yōu)生產(chǎn)計(jì)劃 % opt_val: 最優(yōu)利潤(rùn)值 % exit_flag: 求解狀態(tài) % lambda: 影子價(jià)格等信息 % 設(shè)置默認(rèn)值 if nargin 7, ub []; end if nargin 6, lb zeros(size(profit)); end if nargin 5, eq_limit []; end if nargin 4, eq_cons []; end % 轉(zhuǎn)換為最小化問題 f -profit; % 求解 options optimoptions(linprog, Display, off, Algorithm, dual-simplex); [opt_x, fval, exit_flag, ~, lambda] linprog(f, resource_cons, resource_limit, ... eq_cons, eq_limit, lb, ub, [], options); % 計(jì)算最大利潤(rùn) opt_val -fval; % 輸出報(bào)告 if exit_flag 1 fprintf(求解成功\n); fprintf(最優(yōu)利潤(rùn)%.2f\n, opt_val); fprintf(生產(chǎn)計(jì)劃\n); for i 1:length(opt_x) fprintf( 產(chǎn)品%d%.2f 單位\n, i, opt_x(i)); end % 分析影子價(jià)格 if ~isempty(lambda.ineqlin) fprintf(\n資源影子價(jià)格分析\n); for i 1:length(lambda.ineqlin) if abs(lambda.ineqlin(i)) 1e-6 fprintf( 資源%d每增加1單位利潤(rùn)可增加%.4f\n, i, lambda.ineqlin(i)); end end end else fprintf(求解未達(dá)到最優(yōu)。ExitFlag %d\n, exit_flag); end end這樣的函數(shù)不僅使主程序簡(jiǎn)潔也便于進(jìn)行參數(shù)敏感性分析。例如你可以寫一個(gè)循環(huán)逐漸增加某種資源的數(shù)量resource_limit(i)觀察最優(yōu)利潤(rùn)的變化從而繪制出該資源的邊際價(jià)值曲線這在論文分析中是非常有說服力的部分。線性規(guī)劃是優(yōu)化領(lǐng)域的基石。掌握它不僅意味著你能解決一大類實(shí)際問題更意味著你擁有了將模糊的現(xiàn)實(shí)需求轉(zhuǎn)化為精確數(shù)學(xué)模型的能力。在MATLAB的輔助下這種能力的實(shí)踐門檻被大大降低。真正的挑戰(zhàn)和樂趣在于如何將一個(gè)復(fù)雜、凌亂的實(shí)際問題巧妙地提煉和表達(dá)成那簡(jiǎn)潔的“目標(biāo)函數(shù)”和“約束條件”。這個(gè)過程就是數(shù)學(xué)建模的精髓所在。