多目標規划


  • 多目標規划的模型基礎:
  1. 正負偏差變量
    即d2+,d2-分別表示決策值超過和未達到目標值的部分。且di+,di-均大於0

  2. 剛性約束和目標約束(柔性目標約束具有偏差)
    多目標規划中,剛性約束中保持>=/<=不變。約束需要變換為柔性約束時,需要把>=/<=改成=(因為已經有了d2+,d2-用來表示正負偏差),並且追加上(+di-di+)這里注意!是+di-,-di+,這是因為需要將目標還原回去,使其最接近原來的剛性約束

  3. 優先因子與權系數
    對於若干個目標,分出主次和輕重緩急

  4. 目標規划的目標函數
    是所有偏差變量的加權和。值得注意的是該加權和均取min值。且每個不同的等級需求中,並不一定di+、di-都出現。具體分析需要具體看題目
    舉例如下:
    題目中說設備B既要求充分利用,又盡可能不加班,那么用時間衡量列出的表達式即為:min z=P3(d3- + d3+)之所以這里用+而不是-d3+的原因是:正負偏差不可能同時存在,必有di+di-=0(因為決策值不可能同時大於目標值又小於目標值),又前面是min,所以就取+,讓di+和di-都是正值。故引出如下規則:

  • 最后給出例題,並給出對應的解法:

問題:某企業生產甲、乙兩種產品,需要用到 A, B,C 三種設備,關於產品的贏利與使用設備的工時及限制如下表所示。問該企業應如何安排生產,才能達到下列目標:

( 1)力求使利潤指標不低於 1500 元;
( 2)考慮到市場需求,甲、乙兩種產品的產量比應盡量保持 1:2;
( 3)設備 A 為貴重設備,嚴格禁止超時使用;
( 4)設備C 可以適當加班,但要控制;設備 B 既要求充分利用,又盡可能不加班。
在重要性上,設備 B 是設備C 的 3 倍。
建立相應的目標規划模型並求解。
解:設該企業生產甲乙兩種產品的件數分別為 x1, x2 ,相應的目標規划模型為:

  • 下面采用序貫解法,用lingo求解:

一級目標:

model:
sets:
variable/1..2/:x;!規定變量;
s_con_num/1..4/:g,dplus,dminus;!軟約束條件個數(g的個數=dplus個數=dminus個數)以及需要的相關參數;
s_con(s_con_num,variable):c;!軟約束系數;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=dminus(1);!第一個目標函數;!對應min=z中第一小部分;
2*x(1)+2*x(2)<12;!硬約束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); !利用設置完畢的數據構建軟約束的表達式;
!軟約束表達式;
@for(variable:@gin(x));!限制變量為整數;
end

此時,第一目標最優值為0,第一級偏差為0,下面進行第二步:
二級目標:

!求得dminus(1)=0,接着求解第二個目標;
model:
sets:
variable/1..2/:x;!規定變量;
s_con_num/1..4/:g,dplus,dminus;!軟約束條件個數以及相關參數;
s_con(s_con_num,variable):c;!軟約束系數;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=dminus(2)+dplus(2);!第二個目標函數;
2*x(1)+2*x(2)<12;!硬約束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));
!軟約束表達式;
dminus(1)=0;!第一目標結果;
@for(variable:@gin(x));
end

此時,第二目標最優值為0,偏差為0,下面進行第三步:
三級目標:

!求得dminus(2)=0,接着求解第三個目標;
model:
sets:
variable/1..2/:x;!規定變量;
s_con_num/1..4/:g,dplus,dminus;!軟約束條件個數以及相關參數;
s_con(s_con_num,variable):c;!軟約束系數;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=3*dminus(3)+3*dplus(3)+dminus(4);!第三個目標函數;
2*x(1)+2*x(2)<12;!硬約束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));
!軟約束表達式;
dminus(1)=0;!第一目標約束;
dminus(2)+dplus(2)=0;!二級目標約束;
@for(variable:@gin(x));
end

最終求得x1=2,x2=4,dplus(1)=100,最優利潤為1600

由於上面的過程需要編寫好幾個程序,在使用時不方便,下面給出Lingo編寫的一個通用程序,在程序中用到數據段未知數據的編程方法。

!序貫算法的核心就在於按照p的優先級依次視作單目標規划去求解  eg.p1表示優先級為1的,需要第一個計算;
model:
sets:
level/1..3/:p,z,goal;
variable/1..2/:x;
h_con_num/1..1/:b;
s_con_num/1..4/:g,dplus,dminus;
!以上為建立變量;
h_con(h_con_num,variable):a;!構建約束;
s_con(s_con_num,variable):c;!構建約束;
obj(level,s_con_num)/1 1,2 2,3 3,3 4/:wplus,wminus;!定義P(i)與dplus(i)、dminus(i)之間的系數.其中1 1代表P(1)和dplus(1)、dminus(1)的系數;
endsets
data:
ctr=?;	!?表示需要輸入;
goal=??0;	!因為是一級一級去求偏差的,所以一共三級時,求解到最后一級時只需要輸入前兩級的最優偏差約束即可,所以goal是??0;
b=12;
g=1500 0 16 15;
a=2 2;
c=200 300 2 -1 4 0 0 5;
wplus=0 1 3 1;
wminus=1 1 3 0;
enddata
min=@ sum(level:p*z);	!這個是按照一級一級來求的,因為從該行往下第二行可以發現在求該級目標的時候,其他級的系數均置為了0.;
p(ctr)=1;	!p是序貫算法中的表示優先級的因子,不是一個系數。所以這里當作系數運算時令為1,詳見下一行注釋。序貫算法的核心就在於按照p的優先級依次視作單目標規划去求解  eg.p1表示優先級為1的,需要第一個計算;
@for(level(i)|i#ne#ctr:p(i)=0);!i不等於ctr時,p(i)為0;
@for(level(i):z(i)=@sum(obj(i,j):wplus(i,j)*dplus(j)+wminus(i,j)*dminus(j)));!構建z(i);
@for(h_con_num(i):@sum(variable(j):a(i,j)*x(j))<b(i));!第一個剛性約束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));	!柔性約束;
@for(level(i)|i#lt#@ size(level):@ bnd(0,z(i),goal(i)));	!這里是為了帶上之前求出來的級別最優偏差的約束:0=<z(i)<=goal(i);
end

當程序運行時,會出現一個對話框。
在做第一級目標計算式,ctr輸入1,goal(1),goal(2)輸入兩個較大的值(goal代表最優偏差),表明這兩項約束不起作用。
求的第一級最優偏差為0,進行第二輪的計算。
在第二輪的目標運算中,ctr輸入2,由於第一級偏差為0,因此goal(1)的輸入值為0。
goal(2)輸入一個較大的值,求得第二級的最優偏差仍為0,進行第三級計算。
在第三級計算中,ctr輸入3,由於第一級,第二級偏差均為0,因此goal(1),goal(2)輸入值均為0.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM