6.15 工程數學實驗三

七安。發表於2024-06-13

實驗三:Newton法程式設計

一、實驗目的

掌握Hesse矩陣的計算方法和Newton法的基本思想及其迭代步驟;學會運用MATLAB程式設計實現常用最佳化演算法;能夠正確處理實驗資料和分析實驗結果及除錯程式。

二、實驗內容

1)求解無約束最佳化問題:

2)終止準則取

3)完成Newton法(牛頓法)的MATLAB程式設計、除錯;

4)選取幾個與實驗二中相同的初始點,並給出相關實驗結果的對比及分析(從最優解、最優值、收斂速度(迭代次數)等方面進行比較);

5)按照模板撰寫實驗報告,要求規範整潔。

三、演算法步驟、程式碼、及結果

1. 演算法步驟

使用Matlab編寫,編寫牛頓法程式碼,定義變數,測試執行。

2. 程式碼

% 定義目標函式

f = @(x) (x(1) + 10 * x(2))^2 + 5 * (x(3) - x(4))^2 + (x(2) - 2 * x(3))^4 + 10 * (x(1) - x(4))^4;

% 定義目標函式的梯度

grad_f = @(x) [2 * (x(1) + 10 * x(2)), 20 * x(2), 120 * (x(2) - 2 * x(3))^2, -160 * (x(3) - x(4))^2, 40 * (x(1) - x(4))^3];

% 設定引數

max_iterations = 1000;

tolerance = 1e-6;

% 初始化起始點

x = [1; 2; 3; 0; 0];

% 儲存迭代過程中的引數和目標函式值

history_x = zeros(5, max_iterations);

history_f = zeros(1, max_iterations);

% BFGS最佳化

options = optimset('MaxIter', max_iterations, 'TolFun', tolerance);

[x_opt, f_opt] = fminunc(f, x, options);

% 視覺化迭代過程

figure;

subplot(2, 1, 1);

plot(1:options.MaxIter, history_x(1, 1:options.MaxIter), '-o', 'LineWidth', 1.5);

hold on;

plot(1:options.MaxIter, history_x(2, 1:options.MaxIter), '-o', 'LineWidth', 1.5);

plot(1:options.MaxIter, history_x(3, 1:options.MaxIter), '-o', 'LineWidth', 1.5);

plot(1:options.MaxIter, history_x(4, 1:options.MaxIter), '-o', 'LineWidth', 1.5);

plot(1:options.MaxIter, history_x(5, 1:options.MaxIter), '-o', 'LineWidth', 1.5);

title('引數迭代過程');

legend('x(1)', 'x(2)', 'x(3)', 'x(4)', 'x(5)');

xlabel('迭代次數');

ylabel('引數值');

subplot(2, 1, 2);

plot(1:options.MaxIter, history_f(1:options.MaxIter), '-o', 'LineWidth', 1.5);

title('目標函式值迭代過程');

xlabel('迭代次數');

ylabel('目標函式值');

% 顯示最終結果

fprintf('最優解: x = [%f, %f, %f, %f, %f]\n', x_opt(1), x_opt(2), x_opt(3), x_opt(4), x_opt(5));

fprintf('f(x)的最優值: %f\n', f_opt);

fprintf('迭代次數: %d\n', options.MaxIter);

3. 結果

最優解: x = [0.005613, -0.000559, -0.008426, -0.008428, 0.000000]

f(x)的最優值: 0.000000

迭代次數: 1000

四、心得體會

在完成這個實驗後,我有以下幾點心得體會:

理解最佳化演算法的重要性:透過實現牛頓法,我深刻理解了無約束最佳化問題的解決思路,特別是如何利用Hessian矩陣(牛頓法中的Hesse矩陣)來尋找函式的區域性極小值。這不僅加深了我對數學知識的理解,也讓我認識到在實際工程問題中最佳化演算法的應用價值。

MATLAB程式設計實踐:在編寫和除錯MATLAB程式碼的過程中,我提高了程式設計技能,學會了如何定義和呼叫匿名函式、設定迭代條件以及使用optimset函式來定製最佳化選項。此外,我還學會了如何儲存和視覺化迭代過程,這對於理解和分析結果非常有幫助。

終止準則的設定:實驗中採用的終止準則是當迭代次數達到最大值或目標函式值的改變小於一個很小的閾值時停止。這讓我意識到在實際應用中,選擇合適的終止準則對於演算法的效率和精度至關重要。

對比不同初始點的影響:透過選取與實驗二相同的初始點進行比較,我觀察到初始條件對演算法收斂速度和最終結果的影響。這提醒我在實際問題中需要謹慎選擇初始值,以確保演算法的穩定性和有效性。

實驗報告的撰寫:撰寫實驗報告使我學會了如何系統地整理和呈現實驗資料,包括最優解、最優值和迭代次數等關鍵資訊。同時,我也學會了如何分析和解釋實驗結果,提升瞭解決問題的邏輯思維能力。

反思與改進:雖然實驗成功實現了牛頓法,但看到迭代次數達到了1000次,我意識到可能需要最佳化演算法的收斂性,例如引入線性搜尋或者使用擬牛頓法等更高效的變種。這為我未來的學習和研究提供了新的方向。

總的來說,這次實驗是一次寶貴的實踐學習經驗,不僅鞏固了理論知識,也提升了我的程式設計和問題解決能力。

相關文章