蒙特卡洛模擬(3)————求解有約束的非線性規劃問題

卢宇博發表於2024-08-04

目錄
  • 前言
  • 一、問題提出
  • 二、蒙特卡羅模擬的大體思路
    • 1.求出每個變數的大致範圍
    • 2.生成隨機數進行模擬試驗
  • 三、手動計算每個變數的大致範圍
    • 1.處理等式問題————進行降維
    • 2.處理不等式問題————得到大致範圍
      • (1)先處理簡單的約束,得到變數範圍
      • (2)對複雜的約束進行放縮,得到變數範圍
  • 四、程式碼求解————進行計算機模擬
    • 1.設定數字格式
    • 2.生成隨機數與變數初始化
    • 3.輸入迴圈進行模擬
    • 4.輸出結果
  • 五、縮小範圍重新模擬得到更加精確的取值

前言

在人們的生產實踐中,經常會遇到如何利用現有資源來安排生產,以取得最大經濟效益的問題。此類問題構成了運籌學的一個重要分支--數學規劃
如果目標函式或約束條件中包含非線性函式,就稱這種規劃問題為非線性規劃問題。一般說來,解非線性規劃要比解線性規劃問題困難得多,也不像線性規劃有單純形法這一通用方法,非線性規劃目前還沒有適於各種問題的一般演算法,各個方法都有自己特定的適用範圍。
本章來介紹用計算機生成隨機數的方法來求解非線性規劃問題

一、問題提出

二、蒙特卡羅模擬的大體思路

1.求出每個變數的大致範圍

2.生成隨機數進行模擬試驗

在試驗中,由於我們求的只是一個大致範圍,因此我們需要先判斷隨機數是否滿足精確的約束。
在滿足的前提下,再將這個隨機數帶入表示式,判斷其是否是最大的

三、手動計算每個變數的大致範圍

1.處理等式問題————進行降維

由x1-x2=10,得到x2=x1-10,那麼原函式就可以轉化為f(x)=x1(x1-10)x3,相當於降了一維。但是在程式碼部分,這一步的降維體現在不用再生成一個新的隨機數

2.處理不等式問題————得到大致範圍

(1)先處理簡單的約束,得到變數範圍

因為 10<=x2<=20,則20<=x1<=30(由x1-x2=10)

(2)對複雜的約束進行放縮,得到變數範圍

四、程式碼求解————進行計算機模擬

1.設定數字格式

format long g
matlab預設會將數字保留四位小數,若太大會用科學計數法來表示,但是在我們的規劃問題中,我們想要得到具體的數值,因此輸入此命令可以將Matlab的計算結果顯示為一般的長數字格式

2.生成隨機數與變數初始化

n=10000000; %生成的隨機陣列數
x1=unifrnd(20,30,n,1);  % 生成在[20,30]之間均勻分佈的隨機陣列成的n行1列的向量構成x1
x2=x1 - 10;
x3=unifrnd(-10,16,n,1);  % 生成在[-10,16]之間均勻分佈的隨機陣列成的n行1列的向量構成x3
fmax=-inf; % 初始化函式f的最大值為負無窮(後續只要找到一個比它大的我們就對其更新)

3.輸入迴圈進行模擬

在此步中,我們將x1,x2,x3的數值構造乘了一個新的x向量,這樣每次迴圈都可以生成一個3個數的向量,代表這一次迴圈的x1,x2,x3
然後,判斷是否滿足條件,如果滿足條件就計算函式值,進行迭代最大值

for i=1:n
    x = [x1(i), x2(i), x3(i)];  %構造x向量, 這裡千萬別寫成了:x =[x1, x2, x3]
    if (-x(1)+2*x(2)+2*x(3)>=0)  &  (x(1)+2*x(2)+2*x(3)<=72)     % 判斷是否滿足條件
        result = x(1)*x(2)*x(3);  % 如果滿足條件就計算函式值
        if  result  > fmax  % 如果這個函式值大於我們之前計算出來的最大值
            fmax = result;  % 那麼就更新這個函式值為新的最大值
            X = x;  % 並且將此時的x1 x2 x3儲存到一個變數中
        end
    end
end

4.輸出結果

disp(strcat('蒙特卡羅模擬得到的最大值為',num2str(fmax)))
disp('最大值處x1 x2 x3的取值為:')
disp(X)

五、縮小範圍重新模擬得到更加精確的取值

我們上一步得到了最大值處x1 x2 x3的取值為:22.5897459433039 12.5897459433039 12.1153738601129
因此我們可以將x1的下界從20提高到22,x3的確界從[-10,16],縮小到[11,13],然後進行再次進行迴圈與模擬

x1=unifrnd(22,23,n,1);  % 生成在[22,23]之間均勻分佈的隨機陣列成的n行1列的向量構成x1
x2=x1 - 10;
x3=unifrnd(11,13,n,1);  % 生成在[11,13]之間均勻分佈的隨機陣列成的n行1列的向量構成x3

相關文章