The following program calculates the minimum point of a multi-variable function using the Hooke-Jeeves directional search method.
The program prompts you to enter for each variable:
1. Guess for the minimum point.
2. Initial search step value.
3. The minimum search step value.
The program displays intermediate results to show the iteration progress and also the following final results:
1. The coordinates of the minimum value.
2. The step size for each variable.
3. The minimum function value.
4. The number of iterations
The current code finds the minimum for the following function:
f(x1,x2) = 100 *(x1 ^ 2 - x2) ^ 2 + (1 - x1) ^ 2
Here is a sample session (the intermediate results have been edited out to shorten the session screen and to focus on the input and final output):
Here is the BASIC listing:
! Directional Search using Hooke and Jeeves method OPTION TYPO OPTION NOLET DECLARE NUMERIC MAX_VARS DECLARE NUMERIC N, I, K DECLARE NUMERIC Iter, MaxIter DECLARE NUMERIC F, XX, Lambda, bOK DECLARE NUMERIC BestF, LastBestF, EPSF DECLARE NUMERIC bStop, bMadeAnyMove DECLARE NUMERIC bTrue, bFalse Dim X(1), Xnew(1) Dim StepSize(1) Dim MinStepSize(1) Dim DeltaX(1) Dim bMoved(1) bTrue = 1 bFalse = 0 !---------------- Declare SUBs ------------------- SUB MyFx(X(), N, Res) Res = 100 * (X(1) ^ 2 - X(2)) ^ 2 + (1 - X(1)) ^ 2 ! Res = X(1) - X(2) + 2 * X(1) ^ 2 + 2 * X(1) * X(2) + X(2) ^ 2 End SUB SUB MyFxEx(N, X(), DeltaX(), Lambda, Res) LOCAL I Dim X2(1) MAT ReDim X2(N) For I = 1 To N X2(I) = X(I) + Lambda * DeltaX(I) Next I CALL MyFx(X2, N, Res) End SUB Sub GetGradients(X(), N, Deriv(), DerivNorm) LOCAL XX, I, H, Fp, Fm DerivNorm = 0 For I = 1 To N XX = X(I) H = 0.01 If Abs(XX) > 1 Then H = H * XX X(I) = XX + H CALL MyFx(X, N, Fp) X(I) = XX - H CALL MyFx(X, N, Fm) X(I) = XX Deriv(I) = (Fp - Fm) / 2 / H DerivNorm = DerivNorm + Deriv(I) ^ 2 Next I DerivNorm = Sqr(DerivNorm) End Sub SUB LinSearch_DirectSearch(X(), N, Lambda, DeltaX(), InitStep, MinStep, boolRes) LOCAL F1, F2 CALL MyFxEx(N, X, DeltaX, Lambda, F1) Do CALL MyFxEx(N, X, DeltaX, Lambda + InitStep, F2) If F2 < F1 Then F1 = F2 Lambda = Lambda + InitStep Else CALL MyFxEx(N, X, DeltaX, Lambda - InitStep, F2) If F2 < F1 Then F1 = F2 Lambda = Lambda - InitStep Else ! reduce search step size InitStep = InitStep / 10 End If End If Loop Until InitStep < MinStep boolRes = bTrue End SUB !---------------------------- MAIN PROGRAM -------------------- ! Directional Search using Hooke and Jeeves method MAX_VARS = 2 N = MAX_VARS MAT REDIM X(MAX_VARS), Xnew(MAX_VARS) MAT REDIM StepSize(MAX_VARS) MAT REDIM MinStepSize(MAX_VARS) MAT REDIM DeltaX(MAX_VARS) MAT REDIM bMoved(MAX_VARS) PRINT "Hooke-Jeeves Directional Search Method" For I = 1 To N PRINT "Enter value for X(";I;")"; INPUT Xnew(I) PRINT "Enter step size for X(";I;")"; INPUT StepSize(I) PRINT "Enter minimum step size for X(";I;")"; INPUT MinStepSize(I) Next I ! calculate and display function value at initial point CALL MyFx(Xnew, N, BestF) LastBestF = 100 * BestF + 100 Iter = 0 Do Iter = Iter + 1 For I = 1 To N X(I) = Xnew(I) Next I For I = 1 To N bMoved(I) = bFalse Do XX = Xnew(I) Xnew(I) = XX + StepSize(I) CALL MyFx(Xnew, N, F) If F < BestF Then BestF = F bMoved(I) = bTrue Else Xnew(I) = XX - StepSize(I) CALL MyFx(Xnew, N, F) If F < BestF Then BestF = F bMoved(I) = bTrue Else Xnew(I) = XX Exit Do End If End If Loop Next I ! moved in any direction? bMadeAnyMove = bTrue For I = 1 To N If bMoved(I) = 0 Then bMadeAnyMove = bFalse Exit For End If Next I If bMadeAnyMove = 1 Then For I = 1 To N DeltaX(I) = Xnew(I) - X(I) Next I Lambda = 1 CALL LinSearch_DirectSearch(X, N, Lambda, DeltaX, 0.1, 0.0001, bOK) If bOK = bTrue Then For I = 1 To N Xnew(I) = X(I) + Lambda * DeltaX(I) Next I End If End If CALL MyFx(Xnew, N, BestF) ! reduce the step size for the dimensions that had no moves For I = 1 To N If bMoved(I) = bFalse Then StepSize(I) = StepSize(I) / 2 Next I ! show results Print "For iteration ";Iter For I = 1 To N Print "For X(";I;") Value = ";X(I);" and step size = ";StepSize(I) Next I Print ! remove next set of comments to pause between results ! If Remainder(Iter, 8) = 0 And Iter > 0 Then ! Print "Press any key to continue ..."; ! GET KEY K ! End If LastBestF = BestF bStop = bTrue For I = 1 To N If StepSize(I) >= MinStepSize(I) Then bStop = bFalse Exit For End If Next I Loop Until bStop = bTrue Print "******** FINAL RESULTS *********" Print "Results for optimum point" For I = 1 To N Print "For X(";I;") Value = ";X(I);" and step size = ";StepSize(I) Next I Print "Function value = ";BestF Print "Number of iterations = ";Iter ENDThe above listing has a set of commented statements that when uncommented will allow you to pause during the display of the intermediate results. The current code will display these intermediate results without pausing. For a large number of iterations, you will only see the data for the trailing iterations.
Copyright (c) Namir Shammas. All rights reserved.