【數(shù)學建模算法】(5)整數(shù)規(guī)劃應用實例:生產(chǎn)與銷售計劃問題

之前的幾篇番外,我們介紹了運籌學軟件Lingo的用法,之后對于規(guī)劃問題的處理,如無特殊說明,均視為采用Lingo求解。

例1 生產(chǎn)與銷售問題
某公司用兩種原油( A 和 B )混合加工成兩種汽油(甲和乙)。甲、乙兩種汽油含原油的最低比例分別為 50%和 60%,每噸售價分別為 4800 元和 5600 元。該公司現(xiàn)有原油 A 和 B 的庫存量分別為 500 噸和 1000 噸,還可以從市場上買到不超過 1500噸的原油 A 。原油 A 的市場價為:購買量不超過 500 噸時的單價為 10000 元/噸;購買量超過 500 噸單不超過 1000 噸時,超過 500 噸的部分 8000 元/噸;購買量超過 1000 噸時,超過 1000 噸的部分 6000 元/噸。該公司應如何安排原油的采購和加工。

1.問題分析

安排原油采購、加工的目標是利潤最大,題目中給出的是兩種汽油的售價和原油 A的采購價,利潤為銷售汽油的收入與購買原油 A 的支出之差。這里的難點在于原油 A 的采購價與購買量的關系比較復雜,是分段函數(shù)關系,能否及如何用線性規(guī)劃、整數(shù)規(guī)劃模型加以處理是關鍵所在。

2.模型建立

設原油A的購買量為x(單位:噸)。根據(jù)題目所給數(shù)據(jù),采購的支出c(x)可表示為如下的分段線性函數(shù)(以下價格以千元/噸為單位)
c(x)=\left\{\begin{array}{cc}{10 x,} & {0 \leq x \leq 500} \\ {1000+8 x,} & {500 \leq x \leq 1000} \\ {3000+6 x,} & {1000 \leq x \leq 1500}\end{array}\right.
設原油A用于生產(chǎn)甲,乙兩種汽油的數(shù)量分別為x_{1 1}x_{1 2},原油B用來生產(chǎn)兩種汽油的數(shù)量分別是x_{2 1}x_{2 2},則總的輸入為4.8\left(x_{11}+x_{21}\right)+5.6\left(x_{12}+x_{22}\right)(千元)。于是本例的目標函數(shù)(利潤)為:
\max \quad z=4.8\left(x_{11}+x_{21}\right)+5.6\left(x_{12}+x_{22}\right)-c(x)
(此處c(x)代表一個非線性分段函數(shù))
約束條件包括兩種汽油用的原油A,B的庫存限制,原油A購買量的限制,原油A的比例限制。

x_{11}+x_{12} \leq 500+x
x_{21}+x_{22} \leq 1000
x \leq 1500
\frac{x_{11}}{x_{11}+x_{21}} \geq 0.5
\frac{x_{12}}{x_{12}+x_{22}} \geq 0.6
x_{11}, x_{12}, x_{21}, x_{22}, x \geq 0
現(xiàn)在問題在于,目標函數(shù)中的c(x)是一個非線性函數(shù)

3.模型求解

下面介紹三種解法:
(1)解法一:
一個自然的想法是將原油A采購量的x分為三個量,用x_{1},x_{2},x_{3}分別表示10千元每噸,8千元每噸,6千元每噸采購的原油A的噸數(shù),總支出為

c(x)=10 x_{1}+8 x_{2}+6 x_{3}

且:

x=x_{1}+x_{2}+x_{3}

此時目標函數(shù)變?yōu)榫€性函數(shù):

\max z=4.8\left(x_{11}+x_{21}\right)+5.6\left(x_{12}+x_{22}\right)-\left(10 x_{1}+8 x_{2}+6 x_{3}\right)

如何把分段的限制條件加入呢?
注意到,只有當以10千元每噸的價格購買x_{1}=500噸時,才能以8千元/噸的價格購買x_{2},這個條件可以表示為:

\left(x_{1}-500\right) x_{2}=0

同理,用同樣的條件來限制x_{2}x_{3}

\left(x_{2}-500\right) x_{3}=0

此外,還有x_{1}, x_{2}, x_{3}本身的取值范圍:

0 \leq x_{1}, x_{2}, x_{3} \leq 500

綜合以上所有條件,得到最終的程序:

model:
sets:
var1/1..4/:y; !這里y(1)=x11,y(2)=x21,y(3)=x12,y(4)=x22;
var2/1..3/:x,c;
endsets
max=4.8*(y(1)+y(2))+5.6*(y(3)+y(4))-@sum(var2:c*x);
y(1)+y(3)<@sum(var2:x)+500;
y(2)+y(4)<1000;
0.5*(y(1)-y(2))>0;
0.4*y(3)-0.6*y(4)>0;
(x(1)-500)*x(2)=0;
(x(2)-500)*x(3)=0;
@for(var2:@bnd(0,x,500));
data:
c=10 8 6;
enddata
end

運行得到全局最優(yōu)解:購買1000噸原油A,與庫存的500噸原油A與1000噸原油B一起,共產(chǎn)生2500噸汽油乙,利潤為5000(千元)。

(2)解法二
引入0-1變量z_{1},z_{2},z_{3}

500 z_{2} \leq x_{1} \leq 500 z_{1}
500 z_{3} \leq x_{2} \leq 500 z_{2}
x_{3} \leq 500 z_{3}
z_{1}, z_{2}, z_{3}=0或1

model:
sets:
var1/1..4/:y; !這里y(1)=x11,y(2)=x21,y(3)=x12,y(4)=x22;
var2/1..3/:x,z,c;
endsets
max=4.8*(y(1)+y(2))+5.6*(y(3)+y(4))-@sum(var2:c*x);
y(1)+y(3)<@sum(var2:x)+500;
y(2)+y(4)<1000;
0.5*(y(1)-y(2))>0;
0.4*y(3)-0.6*y(4)>0;
@for(var1(i)|i #lt# 3:500*z(i+1)<x(i);x(i)<500*z(i));
x(3)<500*z(3);
@for(var2:@bin(z));
@for(var2:@bnd(0,x,500));
data:
c=10 8 6;
enddata
end

(3)解法三
直接處理分段線性函數(shù)c(x)。
記分斷點
b_{1}=0, b_{2}=500, \quad b_{3}=1000
x處于第一個小區(qū)間\left[b_{1}, b_{2}\right],記x=w_{1} b_{1}+w_{2} b_{2},w_{1}+w_{2}=1, \quad w_{1}, w_{2} \geq 0因為c(x)\left[b_{1}, b_{2}\right]上是線性的。
c(x)=w_{1} c\left(b_{1}\right)+w_{2} c\left(b_{2}\right)

分段函數(shù)

同理,當處于第二個小區(qū)間時,
,,

x處于第三個小區(qū)間\left[b_{3}, b_{4}\right]x=w_{3} b_{3}+w_{4} b_{4}, \quad w_{3}+w_{4}=1, \quad w_{3}, w_{4} \geq 0c(x)=w_{3} c\left(b_{3}\right)+w_{4} c\left(b_{4}\right)

為了表示x在哪個區(qū)間內(nèi),引入0-1變量z_{k}(k=1,2,3),當x在第k個小區(qū)間時,z_{k}=1,否則,z_{k}=0,這樣w_{1}, w_{2}, w_{3}, w_{4}, z_{1}, z_{2}, z_{3}應滿足:
w_{1} \leq z_{1}, \quad w_{2} \leq z_{1}+z_{2}, \quad w_{3} \leq z_{2}+z_{3}, \quad w_{4} \leq z_{3}
w_{1}+w_{2}+w_{3}+w_{4}=1, \quad w_{k} \geq 0 \quad(k=1,2,3,4)
z_{1}+z_{2}+z_{3}=1, z_{1}, z_{2}, z_{3}=0或1

此時可將c(x)和x統(tǒng)一表示。
x=w_{1} b_{1}+w_{2} b_{2}+w_{3} b_{3}+w_{4} b_{4}=500 w_{2}+1000 w_{3}+1500 w_{4}
\begin{aligned} c(x) &=w_{1} c\left(b_{1}\right)+w_{2} c\left(b_{2}\right)+w_{3} c\left(b_{3}\right)+w_{4} c\left(b_{4}\right) \\ &=5000 w_{2}+9000 w_{3}+12000 w_{4} \end{aligned}
此時又是一個線性規(guī)劃模型。

endsets
data:
b=0,500,1000,1500;
c=0,5000,9000,12000;
z=,,,0; !增加的虛擬變量z(4)=0;
enddata
max=4.8*(y(1)+y(2))+5.6*(y(3)+y(4))-@sum(var:c*w);
y(1)+y(3)<@sum(var:b*w)+500;
y(2)+y(4)<1000;
0.5*(y(1)-y(2))>0;
0.4*y(3)-0.6*y(4)>0;
w(1)<z(1);
@for(var(i)|i #ne# 1:w(i)<z(i-1)+z(i));
@sum(var:z)=1;
@sum(var:w)=1;
@for(var:@bin(z));
End
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容