Skip to content

Commit

Permalink
AVOA implemented completely
Browse files Browse the repository at this point in the history
  • Loading branch information
theablemo committed Jul 12, 2023
1 parent 5115169 commit 9166c3e
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

.idea
97 changes: 97 additions & 0 deletions Metaheuristics/AVOA/AVOA.java
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};
}
}
40 changes: 40 additions & 0 deletions Metaheuristics/AVOA/AVOAExample.java
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);
}
}

}
28 changes: 28 additions & 0 deletions Metaheuristics/AVOA/BoundaryCheck.java
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;
}
}
73 changes: 73 additions & 0 deletions Metaheuristics/AVOA/Exploitation.java
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;
}
}
40 changes: 40 additions & 0 deletions Metaheuristics/AVOA/Exploration.java
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;
}
}
45 changes: 45 additions & 0 deletions Metaheuristics/AVOA/Initialization.java
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;
}
}
38 changes: 38 additions & 0 deletions Metaheuristics/AVOA/LevyFlight.java
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;
}
}
Loading

0 comments on commit 9166c3e

Please sign in to comment.