前言
LINGO 作為非線性規划運算的專用軟件,得出結果一般都是純文本的一列數據,要想將數據呈現到論文當中,需要整理到 EXCEL 中,使用復制粘貼容易出錯還費時,所以必須要動用函數來提高效率!
案例場景
有這樣一個例子,求發電機廠一天7各時段對4台不同機型的發電機分配開啟數量以及輸出功率,用LINGO求解,最后需要將7*4=28的數量數據N,以及對應功率P,輸出到EXCEL中。如下圖所示:


這里的台數和功率都是7行4列的數據。
而利用LINGO算出來的純文本導出數據長這樣:

沒錯,就這種一路排到底的輸出格式,如果是手動復制粘貼,豈不是眼睛都要瞎掉?不過這里值得注意的是,數據的輸出是按行輸出的,先是N(1,:),再是N(2,:)。
EXCEL 之定義名稱
在EXCEL中,使用定義名稱,可以將某一塊的數據賦予一個指定的名字,這樣就和程序里的數據初始化一樣,比如定義一個數組,首先要給他一個名字,然后再被其他函數調用。在EXCEL里定義名稱的數據可以被宏函數調用。而LINGO也可以通過函數來調用EXCEL中定義了名稱的數據。
如何定義名稱?
以前面的台數表格為例,框選對應的 7*4 的數據區域,CTRL + F3 ,會彈出窗口(如果沒反應,就點擊頂部功能欄"公式",找到"定義名稱",一樣可以彈出窗口),設置名稱為NUM,確定。同理可以給功率命名為 POW。


命名完了之后,在表格的左上角下拉可以看到已經命名好的數據,包括了NUM和POW。

最后將表格保存為 Q1_Output.xls ,(或者.xlsx格式,.xls格式時,在調用時可以省去后綴,而.xlsx格式必須加上后綴)。保存好了后,把表格打開,放在一邊,不要關閉,因為LINGO寫入數據時,可能因為權限不夠的原因,關閉狀態下的EXCEL無法寫入,而后台打開狀態時可以寫入。
LINGO 之 @OLE
LINGO自帶的ole函數可以負責與EXCEL傳遞數據。語法如下:
!data為數據表,x為表格內標記為x名稱的某塊區域;
X = @ole('data.xls','x');!從EXCEL導入數據到LINGO;
@ole('data.xls','x') = X;!從LINGO導出數據到EXCEL;
所以為了導出我們的N、P數據,我們寫如下代碼到 data:里
@OLE('Q1_Output','NUM')=N;
@OLE('Q1_Output','POW')=P;
完整代碼如下:
model:
sets:
A /1..7/: T, D ;
B /1..4/:N0,Pmax,Pmin,F,M,S;
U(A,B): N, P ;
endsets
data:
T = 6 3 3 2 4 4 2;
D = 11000 33000 25000 36000 25000 30000 18000;
N0 = 10 5 8 4;
Pmax=1800 1500 2000 3500;
Pmin= 800 1000 1200 1800;
F =2200 1800 3800 4600;
M = 2.7 2.2 1.8 3.6;
S =4000 1500 2500 1000;
@OLE('Q1_Output','NUM')=N;
@OLE('Q1_Output','POW')=P;
enddata
W1 =@sum(B(j):N(1,j)*S(j))+@sum(A(i)|i#ge#2:
@sum(B(j):(N(i,j)-N(i-1,j)+@abs(N(i,j)-N(i-1,j)))
/2*S(j)));
W2=@sum(A(i): @sum(B(j):N(i,j)*F(j)*T(i)));
W3=@sum(A(i): @sum(B(j):(P(i,j)-Pmin(j))*
N(i,j)*M(j)*T(i)));
min =W1+W2+W3;
@for(A(i): @sum(B(j):P(i,j)*N(i,j)) >=D(i));
@for(U(i,j):N(i,j)>=0);
@for(U(i,j):N(i,j)<=N0(j));
@for(U(i,j):@gin(N(i,j)));
@for(U(i,j):Pmin(j)<=P(i,j));
@for(U(i,j):P(i,j)<=Pmax(j));
end
一鍵導出數據
做好前面兩步,即EXCEL數據輸出區域命名,還有LINGO導出數據函數,最后把EXCEL打開放在屏幕左邊,LINGO放右邊,點擊solve,坐等程序跑完,EXCEL中就驚現數據了,是不是很nice!?
