6.15 工程數學實驗二

七安。發表於2024-06-13

實驗二:最速下降法程式設計

一、實驗目的

透過最速下降法的程式設計,為今後的約束最佳化方法的學習和程式設計奠定基礎;掌握負梯度方向的定義和最速下降法的迭代公式;透過此次實驗,進一步鞏固最速下降法的基本原理和思想。

二、實驗內容

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

2)終止準則取

3)完成最速下降法(負梯度法)的MATLAB程式設計、除錯;

(4)要求選取多個不同的初始點,並給出迭代次數,最優函式值等相關資訊,有能力的同學嘗試畫出最優值隨迭代次數變化的曲線圖;

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

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

1. 演算法步驟

首先定義實驗的函式,然後算出梯度,給出幾組例值。

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)))^2;

% 最速下降法求解

% 設定初始點和迭代終止準則

x0_list = [-2, 5, 6, 7; 2 ,2 ,6 , 5; 0.5, -1.5, 2, 5]; % 多個不同的初始點

max_iter = 10000;

tol = 1e-5;

results = zeros(size(x0_list, 1), 4); % 儲存最優結果

for i = 1:size(x0_list, 1)

x0 = x0_list(i,:);

x = x0';

a = 0.01; % 步長

iter = 0;

grad_norm = inf;

func_values = zeros(max_iter, 1); % 新增:記錄每一步的函式值

while grad_norm > tol && iter < max_iter

iter = iter + 1;

grad = [400*x(1)^3-400*x(1)*x(2)+2*x(1)-2;

200*(x(2)-x(1)^2);

10*(x(3)-x(4));

-10*(x(3)-x(4))];

x_new = x - a*grad;

if f(x_new) < f(x)

x = x_new;

a = a * 1.1;

else

a = a * 0.5;

end

grad_norm = norm(grad);

func_values(iter) = f(x); % 記錄當前迭代的函式值

end

results(i, :) = x;

fprintf('初始點 (%g, %g, %g, %g)\n', x0(1), x0(2), x0(3), x0(4));

fprintf('迭代次數: %d\n', iter);

fprintf('最優點: (%g, %g, %g, %g)\n', x(1), x(2), x(3), x(4));

fprintf('最優函式值: %g\n', f(x));

fprintf('\n');

% 繪製當前初始點對應的函式值變化曲線

plot(1:iter, func_values(1:iter), 'LineWidth', 1.5, ...

'DisplayName', sprintf('初始點%d', i));

hold on;

end

% 新增標題、標籤、圖例和網格

xlabel('迭代次數');

ylabel('函式值');

title('函式值隨迭代次數變化');

legend('show');

grid on;

hold off;

3. 結果

四、心得體會

在這個實驗中,我學習了最速下降法的基本原理和實現過程。透過程式設計實踐,我掌握了負梯度方向的定義和最速下降法的迭代公式。在實驗中,我首先定義了目標函式,並計算了其梯度。然後,我選擇了多個不同的初始點,並設定了迭代終止準則。在迭代過程中,我不斷更新引數,直到滿足了停止條件或達到最大迭代次數。

透過實驗,我深入理解了最速下降法的迭代過程,以及如何根據梯度資訊來更新引數以找到函式的區域性最小值。我還學會了如何利用MATLAB程式語言來實現最速下降法,並且能夠繪製出函式值隨迭代次數變化的曲線圖,以直觀地觀察演算法的收斂情況。

總的來說,這個實驗幫助我鞏固了最速下降法的基本原理和思想,提高了我的程式設計能力和數值最佳化的實踐經驗。透過這次實驗,我更加熟悉了最佳化演算法的實現過程,並且對如何解決實際問題有了更深入的理解。

相關文章