實驗二:最速下降法程式設計
一、實驗目的
透過最速下降法的程式設計,為今後的約束最佳化方法的學習和程式設計奠定基礎;掌握負梯度方向的定義和最速下降法的迭代公式;透過此次實驗,進一步鞏固最速下降法的基本原理和思想。
二、實驗內容
(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程式語言來實現最速下降法,並且能夠繪製出函式值隨迭代次數變化的曲線圖,以直觀地觀察演算法的收斂情況。
總的來說,這個實驗幫助我鞏固了最速下降法的基本原理和思想,提高了我的程式設計能力和數值最佳化的實踐經驗。透過這次實驗,我更加熟悉了最佳化演算法的實現過程,並且對如何解決實際問題有了更深入的理解。