-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
453 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
import java.util.Random; | ||
|
||
import static Metaheuristics.AVOA.BoundaryCheck.boundaryCheck; | ||
import static Metaheuristics.AVOA.Exploitation.exploitation; | ||
import static Metaheuristics.AVOA.Exploration.exploration; | ||
import static Metaheuristics.AVOA.Initialization.initialization; | ||
import static Metaheuristics.AVOA.RandomSelection.randomSelect; | ||
|
||
public class AVOA { | ||
/** | ||
* Runs the Artificial Vulture Optimization Algorithm (AVOA) to find the global optimum. | ||
* | ||
* @param pop_size The population size. | ||
* @param max_iter The maximum number of iterations. | ||
* @param lower_bound The lower bound of the variables. | ||
* @param upper_bound The upper bound of the variables. | ||
* @param variables_no The number of variables. | ||
* @param fobj The objective function. | ||
* @return An array containing the best vulture 1 fitness, best vulture 1 position, | ||
* and the convergence curve of the algorithm. | ||
*/ | ||
public static Object[] AVOA(int pop_size, int max_iter, double[] lower_bound, double[] upper_bound, | ||
int variables_no, ObjectiveFunction fobj) { | ||
// Initialize Best_vulture1, Best_vulture2 | ||
double[] Best_vulture1_X = new double[variables_no]; | ||
double Best_vulture1_F = Double.POSITIVE_INFINITY; | ||
double[] Best_vulture2_X = new double[variables_no]; | ||
double Best_vulture2_F = Double.POSITIVE_INFINITY; | ||
|
||
// Initialize the first random population of vultures | ||
double[][] X = initialization(pop_size, variables_no, upper_bound, lower_bound); | ||
|
||
// Controlling parameters | ||
double p1 = 0.6; | ||
double p2 = 0.4; | ||
double p3 = 0.6; | ||
double alpha = 0.8; | ||
double beta = 0.2; | ||
double gamma = 2.5; | ||
|
||
// Main loop | ||
int current_iter = 0; // Loop counter | ||
double[] convergence_curve = new double[max_iter]; | ||
|
||
while (current_iter < max_iter) { | ||
for (int i = 0; i < X.length; i++) { | ||
// Calculate the fitness of the population | ||
double[] current_vulture_X = X[i]; | ||
double current_vulture_F = fobj.evaluate(current_vulture_X); | ||
|
||
// Update the first best two vultures if needed | ||
if (current_vulture_F < Best_vulture1_F) { | ||
Best_vulture1_F = current_vulture_F; // Update the first best vulture | ||
System.arraycopy(current_vulture_X, 0, Best_vulture1_X, 0, variables_no); | ||
} | ||
if (current_vulture_F > Best_vulture1_F && current_vulture_F < Best_vulture2_F) { | ||
Best_vulture2_F = current_vulture_F; // Update the second-best vulture | ||
System.arraycopy(current_vulture_X, 0, Best_vulture2_X, 0, variables_no); | ||
} | ||
} | ||
|
||
Random rand = new Random(); | ||
double a = rand.nextDouble() * 4 - 2; | ||
a *= (Math.pow(Math.sin(Math.PI / 2 * (current_iter / (double)max_iter)), gamma) + | ||
Math.cos(Math.PI / 2 * (current_iter / (double)max_iter)) - 1); | ||
double P1 = (2 * rand.nextDouble() + 1) * (1 - (current_iter / (double)max_iter)) + a; | ||
|
||
// Update the location | ||
for (int i = 0; i < X.length; i++) { | ||
double[] current_vulture_X = X[i].clone(); // Pick the current vulture back to the population | ||
double F = P1 * (2 * rand.nextDouble() - 1); | ||
|
||
double[] random_vulture_X = randomSelect(Best_vulture1_X, Best_vulture2_X, alpha, beta); | ||
|
||
if (Math.abs(F) >= 1) { // Exploration | ||
current_vulture_X = exploration(current_vulture_X, random_vulture_X, F, p1, upper_bound, lower_bound); | ||
} else if (Math.abs(F) < 1) { // Exploitation | ||
current_vulture_X = exploitation(current_vulture_X, Best_vulture1_X, Best_vulture2_X, random_vulture_X, F, p2, p3, variables_no); | ||
} | ||
|
||
X[i] = current_vulture_X; // Place the current vulture back into the population | ||
} | ||
|
||
current_iter++; | ||
convergence_curve[current_iter - 1] = Best_vulture1_F; | ||
|
||
X = boundaryCheck(X, lower_bound, upper_bound); | ||
|
||
System.out.printf("In Iteration %d, best estimation of the global optimum is %4.4f \n", current_iter, Best_vulture1_F); | ||
} | ||
|
||
|
||
return new Object[]{Best_vulture1_F, Best_vulture1_X, convergence_curve}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package Metaheuristics.AVOA; | ||
import static Metaheuristics.AVOA.AVOA.AVOA; | ||
|
||
import java.util.Arrays; | ||
|
||
public class AVOAExample { | ||
|
||
public static void main(String[] args) { | ||
int pop_size = 30; | ||
int max_iter = 100; | ||
|
||
// Define your objective function's details here | ||
ObjectiveFunction fobj = new ObjectiveFunction(); | ||
int variables_no = 10; | ||
double[] lower_bound = new double[variables_no]; | ||
Arrays.fill(lower_bound, -100); | ||
double[] upper_bound = new double[variables_no]; | ||
Arrays.fill(upper_bound, 100); | ||
|
||
Object[] result = AVOA(pop_size, max_iter, lower_bound, upper_bound, variables_no, fobj); | ||
double Best_vulture1_F = (double) result[0]; | ||
double[] Best_vulture1_X = (double[]) result[1]; | ||
double[] convergence_curve = (double[]) result[2]; | ||
|
||
// Best optimal values for the decision variables | ||
// parallelcoords(Best_vulture1_X) | ||
System.out.println("Decision variables:"); | ||
for (double value : Best_vulture1_X) { | ||
System.out.println(value); | ||
} | ||
|
||
// Best convergence curve | ||
// plot(convergence_curve); | ||
System.out.println("\nConvergence curve of AVOA:"); | ||
for (double value : convergence_curve) { | ||
System.out.println(value); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
public class BoundaryCheck { | ||
/** | ||
* Performs boundary check on the matrix X. | ||
* | ||
* @param X The input matrix | ||
* @param lb The lower bounds vector | ||
* @param ub The upper bounds vector | ||
* @return The modified matrix after boundary check | ||
*/ | ||
public static double[][] boundaryCheck(double[][] X, double[] lb, double[] ub) { | ||
int numRows = X.length; | ||
int numCols = X[0].length; | ||
|
||
for (int i = 0; i < numRows; i++) { | ||
for (int j = 0; j < numCols; j++) { | ||
boolean FU = X[i][j] > ub[j]; // Check if element exceeds the upper bound | ||
boolean FL = X[i][j] < lb[j]; // Check if element is below the lower bound | ||
|
||
// Perform the boundary check and assign the appropriate value to X[i][j] | ||
X[i][j] = (X[i][j] * ((!(FU || FL)) ? 1 : 0)) + ub[j] * (FU ? 1 : 0) + lb[j] * (FL ? 1 : 0); | ||
} | ||
} | ||
|
||
return X; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
import java.util.Random; | ||
|
||
import static Metaheuristics.AVOA.LevyFlight.levyFlight; | ||
|
||
public class Exploitation { | ||
/** | ||
* Updates the current vulture position based on exploitation. | ||
* | ||
* @param current_vulture_X The current vulture position array to be updated. | ||
* @param Best_vulture1_X The position of the best vulture 1. | ||
* @param Best_vulture2_X The position of the best vulture 2. | ||
* @param random_vulture_X The random vulture position array. | ||
* @param F The exploitation factor. | ||
* @param p2 The probability threshold for phase 1 exploitation. | ||
* @param p3 The probability threshold for phase 2 exploitation. | ||
* @param variables_no The number of variables. | ||
* @return The updated current vulture position array. | ||
*/ | ||
public static double[] exploitation(double[] current_vulture_X, double[] Best_vulture1_X, double[] Best_vulture2_X, | ||
double[] random_vulture_X, double F, double p2, double p3, int variables_no) { | ||
Random rand = new Random(); | ||
|
||
// Phase 1 | ||
if (Math.abs(F) < 0.5) { | ||
if (rand.nextDouble() < p2) { | ||
// Calculate intermediate values A and B | ||
double[] A = new double[current_vulture_X.length]; | ||
double[] B = new double[current_vulture_X.length]; | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
A[i] = Best_vulture1_X[i] - ((Best_vulture1_X[i] * current_vulture_X[i]) / (Best_vulture1_X[i] - Math.pow(current_vulture_X[i], 2))) * F; | ||
B[i] = Best_vulture2_X[i] - ((Best_vulture2_X[i] * current_vulture_X[i]) / (Best_vulture2_X[i] - Math.pow(current_vulture_X[i], 2))) * F; | ||
} | ||
// Update current vulture position by averaging A and B | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
current_vulture_X[i] = (A[i] + B[i]) / 2; | ||
} | ||
} else { | ||
// Update current vulture position using random vulture position, absolute difference, F, and levyFlight | ||
double[] levyFlight = levyFlight(variables_no); // Replace this line with your levyFlight implementation | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
current_vulture_X[i] = random_vulture_X[i] - Math.abs(random_vulture_X[i] - current_vulture_X[i]) * F * levyFlight[i]; | ||
} | ||
} | ||
} | ||
|
||
// Phase 2 | ||
if (Math.abs(F) >= 0.5) { | ||
if (rand.nextDouble() < p3) { | ||
// Update current vulture position using random vulture position, random values, and F | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
double randomValue = 2 * rand.nextDouble(); | ||
current_vulture_X[i] = Math.abs(randomValue * random_vulture_X[i] - current_vulture_X[i]) * (F + rand.nextDouble()) - (random_vulture_X[i] - current_vulture_X[i]); | ||
} | ||
} else { | ||
// Calculate intermediate values s1 and s2 | ||
double[] s1 = new double[current_vulture_X.length]; | ||
double[] s2 = new double[current_vulture_X.length]; | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
s1[i] = random_vulture_X[i] * (rand.nextDouble() * current_vulture_X[i] / (2 * Math.PI)) * Math.cos(current_vulture_X[i]); | ||
s2[i] = random_vulture_X[i] * (rand.nextDouble() * current_vulture_X[i] / (2 * Math.PI)) * Math.sin(current_vulture_X[i]); | ||
} | ||
// Update current vulture position by subtracting s1 and s2 from random vulture position | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
current_vulture_X[i] = random_vulture_X[i] - (s1[i] + s2[i]); | ||
} | ||
} | ||
} | ||
|
||
return current_vulture_X; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
import java.util.Random; | ||
|
||
public class Exploration { | ||
/** | ||
* Updates the current vulture position based on exploration. | ||
* | ||
* @param current_vulture_X The current vulture position array to be updated. | ||
* @param random_vulture_X The random vulture position array. | ||
* @param F The exploration factor. | ||
* @param p1 The probability threshold for exploration. | ||
* @param upper_bound The upper bound of the vulture position range. | ||
* @param lower_bound The lower bound of the vulture position range. | ||
* @return The updated current vulture position array. | ||
*/ | ||
public static double[] exploration(double[] current_vulture_X, double[] random_vulture_X, double F, double p1, double[] upper_bound, double[] lower_bound) { | ||
Random rand = new Random(); | ||
|
||
// Check if a randomly generated value is less than p1 | ||
if (rand.nextDouble() < p1) { | ||
// Exploration based on random vulture position | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
double randomFactor = 2 * rand.nextDouble(); // Generate a random factor between 0 and 2 | ||
// Update the current vulture position using the random factor and F | ||
current_vulture_X[i] = random_vulture_X[i] - Math.abs((randomFactor * random_vulture_X[i]) - current_vulture_X[i]) * F; | ||
} | ||
} else { | ||
// Exploration based on random values within bounds | ||
for (int i = 0; i < current_vulture_X.length; i++) { | ||
double randomFactor = rand.nextDouble(); // Generate a random factor between 0 and 1 | ||
double range = upper_bound[i] - lower_bound[i]; // Calculate the range for the current dimension | ||
// Update the current vulture position using the random factor, F, upper bound, and lower bound | ||
current_vulture_X[i] = random_vulture_X[i] - F + randomFactor * (range * rand.nextDouble() + lower_bound[i]); | ||
} | ||
} | ||
|
||
return current_vulture_X; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
import java.util.Random; | ||
|
||
public class Initialization { | ||
/** | ||
* Initialize the first population of search agents. | ||
* | ||
* @param N The population size | ||
* @param dim The dimensionality of the search space | ||
* @param ub The upper bounds vector | ||
* @param lb The lower bounds vector | ||
* @return The initialized population matrix | ||
*/ | ||
public static double[][] initialization(int N, int dim, double[] ub, double[] lb) { | ||
int boundaryNo = ub.length; // Number of boundaries | ||
|
||
Random rand = new Random(); | ||
double[][] X = new double[N][dim]; // Initialized population matrix | ||
|
||
// If the boundaries of all variables are equal and the user enters a single number for both ub and lb | ||
if (boundaryNo == 1) { | ||
double upperBound = ub[0]; | ||
double lowerBound = lb[0]; | ||
for (int i = 0; i < N; i++) { | ||
for (int j = 0; j < dim; j++) { | ||
X[i][j] = rand.nextDouble() * (upperBound - lowerBound) + lowerBound; | ||
} | ||
} | ||
} | ||
|
||
// If each variable has a different lb and ub | ||
if (boundaryNo > 1) { | ||
for (int i = 0; i < dim; i++) { | ||
double upperBound = ub[i]; | ||
double lowerBound = lb[i]; | ||
for (int j = 0; j < N; j++) { | ||
X[j][i] = rand.nextDouble() * (upperBound - lowerBound) + lowerBound; | ||
} | ||
} | ||
} | ||
|
||
return X; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package Metaheuristics.AVOA; | ||
|
||
import org.apache.commons.math3.special.Gamma; | ||
import java.util.Random; | ||
|
||
public class LevyFlight { | ||
/** | ||
* Generates a Levy flight of length d. | ||
* | ||
* @param d The length of the Levy flight | ||
* @return The Levy flight as an array | ||
*/ | ||
public static double[] levyFlight(int d) { | ||
double beta = 3.0 / 2.0; | ||
|
||
// Calculate the sigma value | ||
double sigma = Math.pow((Gamma.gamma(1 + beta) * Math.sin(Math.PI * beta / 2) / | ||
(Gamma.gamma((1 + beta) / 2) * beta * Math.pow(2, (beta - 1) / 2))), 1 / beta); | ||
|
||
Random rand = new Random(); | ||
|
||
// Generate random values for u and v | ||
double[] u = new double[d]; | ||
double[] v = new double[d]; | ||
for (int i = 0; i < d; i++) { | ||
u[i] = rand.nextGaussian() * sigma; | ||
v[i] = rand.nextGaussian(); | ||
} | ||
|
||
// Calculate the step values | ||
double[] step = new double[d]; | ||
for (int i = 0; i < d; i++) { | ||
step[i] = u[i] / Math.pow(Math.abs(v[i]), 1 / beta); | ||
} | ||
|
||
return step; | ||
} | ||
} |
Oops, something went wrong.