The following program calculates the minimum point of a multi-variable function using the Hooke-Jeeves directional search method.
The function hookejeeves has the following input parameters:
The function generates the following output:
Here is a sample session to find the optimum for the following function:
y = 10 + (X(1) - 2)^2 + (X(2) + 5)^2
The above function resides in file fx1.m. The search for the optimum 2 variables has the initial guess of [0 0], initial step vector of [0.1 0.1] with a minimum step vector of [1e-5 1e-5]. The search employs a maximum of 1000 iterations and a function tolerance of 1e-7:
>> [X,BestF,Iters] = hookejeeves(2, [0 0], [.1 .1], [1e-5 1e-5], 1e-7, 1000, 'fx1')
X =
2.0000 -5.0000
BestF =
10
Iters =
15
Here is the MATLAB listing:
function [X,BestF,Iters] = hookejeeves(N, X, StepSize, MinStepSize, Eps_Fx, MaxIter, myFx)
% Function HOOKEJEEVS performs multivariate optimization using the
% Hooke-Jeeves search method.
%
% Input
%
% N - number of variables
% X - array of initial guesses
% StepSize - array of search step sizes
% MinStepSize - array of minimum step sizes
% Eps_Fx - tolerance for difference in successive function values
% MaxIter - maximum number of iterations
% myFx - name of the optimized function
%
% Output
%
% X - array of optimized variables
% BestF - function value at optimum
% Iters - number of iterations
%
Xnew = X;
BestF = feval(myFx, Xnew, N);
LastBestF = 100 * BestF + 100;
bGoOn = true;
Iters = 0;
while bGoOn
Iters = Iters + 1;
if Iters > MaxIter
break;
end
X = Xnew;
for i=1:N
bMoved(i) = 0;
bGoOn2 = true;
while bGoOn2
xx = Xnew(i);
Xnew(i) = xx + StepSize(i);
F = feval(myFx, Xnew, N);
if F < BestF
BestF = F;
bMoved(i) = 1;
else
Xnew(i) = xx - StepSize(i);
F = feval(myFx, Xnew, N);
if F < BestF
BestF = F;
bMoved(i) = 1;
else
Xnew(i) = xx;
bGoOn2 = false;
end
end
end
end
bMadeAnyMove = sum(bMoved);
if bMadeAnyMove > 0
DeltaX = Xnew - X;
lambda = 0.5;
lambda = linsearch(X, N, lambda, DeltaX, myFx);
Xnew = X + lambda * DeltaX;
end
BestF = feval(myFx, Xnew, N);
% reduce the step size for the dimensions that had no moves
for i=1:N
if bMoved(i) == 0
StepSize(i) = StepSize(i) / 2;
end
end
if abs(BestF - LastBestF) < Eps_Fx
break
end
LastBest = BestF;
bStop = true;
for i=1:N
if StepSize(i) >= MinStepSize(i)
bStop = false;
end
end
bGoOn = ~bStop;
end
function y = myFxEx(N, X, DeltaX, lambda, myFx)
X = X + lambda * DeltaX;
y = feval(myFx, X, N);
% end
function lambda = linsearch(X, N, lambda, D, myFx)
MaxIt = 100;
Toler = 0.000001;
iter = 0;
bGoOn = true;
while bGoOn
iter = iter + 1;
if iter > MaxIt
lambda = 0;
break
end
h = 0.01 * (1 + abs(lambda));
f0 = myFxEx(N, X, D, lambda, myFx);
fp = myFxEx(N, X, D, lambda+h, myFx);
fm = myFxEx(N, X, D, lambda-h, myFx);
deriv1 = (fp - fm) / 2 / h;
deriv2 = (fp - 2 * f0 + fm) / h ^ 2;
diff = deriv1 / deriv2;
lambda = lambda - diff;
if abs(diff) < Toler
bGoOn = false;
end
end
% end
%{
Sub DirectSearch()
Const MAX_VARS = 3
Dim N As Integer, I As Integer
Dim Row As Integer, MaxIter As Integer
Dim X(MAX_VARS) As Double, Xnew(MAX_VARS) As Double
Dim StepSize(MAX_VARS) As Double
Dim MinStepSize(MAX_VARS) As Double
Dim Deltax(MAX_VARS) As Double
Dim F As Double, XX As Double, Lambda As Double
Dim BestF As Double, LastBestF As Double, EPSF As Double
Dim bStop As Boolean, bMadeAnyMove As Boolean
Dim bMoved(MAX_VARS) As Boolean
N = MAX_VARS
For I = 1 To N
Xnew(I) = Cells(I + 1, 2)
StepSize(I) = Cells(I + 1, 3)
MinStepSize(I) = Cells(I + 1, 4)
Next I
EPSF = Cells(2, 1)
Range("E1:Z32000").Clear
Range("E1").Value = "F(X())"
Range("E1:Z1").Font.Bold = True
For I = 1 To N
Cells(1, 5 + I) = "X(" & I & ")"
Cells(1, 5 + I + N) = "Step(" & I & ")"
Next I
' calculate and display function value at initial point
BestF = MyFx(Xnew, N)
LastBestF = 100 * BestF + 100
Row = 1
Do
Row = Row + 1
For I = 1 To N
X(I) = Xnew(I)
Next I
For I = 1 To N
bMoved(I) = False
Do
XX = Xnew(I)
Xnew(I) = XX + StepSize(I)
F = MyFx(Xnew, N)
If F < BestF Then
BestF = F
bMoved(I) = True
Else
Xnew(I) = XX - StepSize(I)
F = MyFx(Xnew, N)
If F < BestF Then
BestF = F
bMoved(I) = True
Else
Xnew(I) = XX
Exit Do
End If
End If
Loop
Next I
' moved in any direction?
bMadeAnyMove = True
For I = 1 To N
If Not bMoved(I) Then
bMadeAnyMove = False
Exit For
End If
Next I
If bMadeAnyMove Then
For I = 1 To N
Deltax(I) = Xnew(I) - X(I)
Next I
''' Lambda = CubicIntMin(N, X, Deltax, 0, 1, 0.0001, 0.00001, 100)
''' For I = 1 To N
''' Xnew(I) = X(I) + Lambda * Deltax(I)
''' Next I
If LinSearch_DirectSearch(X, N, Lambda, Deltax, 0.1, 0.0001) Then
For I = 1 To N
Xnew(I) = X(I) + Lambda * Deltax(I)
Next I
End If
End If
BestF = MyFx(Xnew, N)
' reduce the step size for the dimensions that had no moves
For I = 1 To N
If Not bMoved(I) Then StepSize(I) = StepSize(I) / 2
Next I
' show results
Cells(Row, 5) = BestF
For I = 1 To N
Cells(Row, 5 + I) = X(I)
Cells(Row, 5 + I + N) = StepSize(I)
Next I
' test function value convergence
'If Abs(BestF - LastBestF) < EPSF Then Exit Do
LastBestF = BestF
bStop = True
For I = 1 To N
If StepSize(I) >= MinStepSize(I) Then
bStop = False
Exit For
End If
Next I
Loop Until bStop
End Sub
%}
Copyright (c) Namir Shammas. All rights reserved.