HHO算法JAVA实现
参考GitHub链接中matlab程序编写
package Algorithm.HHO;
import org.apache.commons.math3.special.Gamma;
import java.util.Arrays;
import java.util.Random;
/**
* @auther guoyu
* @create 2020-11-15 22:54
*/
public class HHOTest2 {
private double[] UB;//变量上界
private double[] LB;//变量下界
private double rabbitEnergy = Double.MAX_VALUE;//函数最优值
private int T;//迭代次数
private int N;//种群数量
private double[] xRabbitLocation;//最优位置
private int dim;//维数
public double[][] total;//每个个体的位置
public static final String MAX = "MAX";//求最大值
public static final String MIN = "MIN";//求最小值
/**
* 构造函数
*
* @param UB 上界
* @param LB 下界
* @param T 迭代次数
* @param N 种群数量
*/
public HHOTest2(double[] UB, double[] LB, int T, int N, int dim) {
this.UB = UB;
this.LB = LB;
this.T = T;
this.N = N;
this.dim = dim;
if (UB.length != dim || LB.length != dim) {
System.out.println("不匹配");
System.exit(-1);
}
init(N, UB, LB, dim);
}
/**
* 初始化每个个体的位置
*
* @param num 个体数量
* @param UB 上界
* @param LB 下界
* @param dim 维数
*/
public void init(int num, double[] UB, double[] LB, int dim) {
total = new double[num][dim];
for (int i = 0; i < num; i++) {
total[i] = new double[dim];
for (int k = 0; k < dim; k++) {
total[i][k] = productdouble(UB[k], LB[k]);
}
}
xRabbitLocation = new double[dim];
}
/**
* 计算最优值函数
*
* @return 最优解
*/
public double HHOFuction(Funtion funtion, String s) {
double[] xRandom = new double[dim];
int t = 0;
while (t < T) {
double fitness = 0;
//calculate the fitness values of hawks
for (int i = 0; i < N; i++) {
panduan(total);
fitness = funtion.calculate(total[i]);
if (s.equals("MIN")) {
if (fitness < rabbitEnergy) {
rabbitEnergy = fitness;
for (int i1 = 0; i1 < dim; i1++) {
xRabbitLocation[i1] = total[i][i1];
}
}
} else {
if (fitness > rabbitEnergy) {
rabbitEnergy = fitness;
for (int i1 = 0; i1 < dim; i1++) {
xRabbitLocation[i1] = total[i][i1];
}
}
}
}
///
double E1 = 2 * (1 - (t * 1.0 / T));// factor to show the decreaing energy of rabbit
//Update the location of Harris' hawks
for (int i = 0; i < N; i++) {
double E0 = 2 * (Math.random()) - 1;//-1<E0<1
double escapingEnergy = E1 * E0;//escaping energy of rabbit
//
if (Math.abs(escapingEnergy) >= 1) {
// //Exploration:
Random r = new Random();
double q = productdouble();
int index1 = r.nextInt(N);//0-N-1
xRandom = total[index1];
if (q >= 0.5) {
double r1 = productdouble();
double r2 = productdouble();
for (int i1 = 0; i1 < dim; i1++) {
total[i][i1] = xRandom[i1] - r1 * (Math.abs(xRandom[i1] - 2 * r2) * total[i][i1]);
}
} else {
double r3 = productdouble();
double r4 = productdouble();
for (int i1 = 0; i1 < dim; i1++) {
total[i][i1] = (xRabbitLocation[i1] - mean(total, i1)) - r3 * (LB[i1] + r4 * (UB[i1] - LB[i1]));
}
}
}
if (Math.abs(escapingEnergy) < 1) {
// Exploitation:
//Attacking the rabbit using 4 strategies regarding the behavior of the rabbit
// phase 1: surprise pounce (seven kills)
// surprise pounce (seven kills): multiple, short rapid dives by different hawks
double ran = productdouble();//probablity of each event
if (ran >= 0.5 && Math.abs(escapingEnergy) < 0.5) {// Hard besiege
for (int i1 = 0; i1 < dim; i1++) {
total[i][i1] = xRabbitLocation[i1] - escapingEnergy * Math.abs(xRabbitLocation[i1] - total[i][i1]);
}
}
if (ran >= 0.5 && Math.abs(escapingEnergy) >= 0.5) {//% Soft besiege
double J = 2 * (1 - productdouble());// random jump strength of the rabbit
for (int i1 = 0; i1 < dim; i1++) {
total[i][i1] = (xRabbitLocation[i1] - total[i][i1]) - escapingEnergy * (Math.abs(J * xRabbitLocation[i1] - total[i][i1]));
}
}
// phase 2: performing team rapid dives (leapfrog movements)
if (ran < 0.5 && Math.abs(escapingEnergy) >= 0.5) {// Soft besiege % rabbit try to escape by many zigzag deceptive motions
double J = 2 * (1 - productdouble());
double[] arg = new double[dim];
double[] arg1 = new double[dim];
for (int j = 0; j < dim; j++) {
arg[j] = xRabbitLocation[j] - escapingEnergy * (Math.abs(J * xRabbitLocation[j] - total[i][j]));
}
if (funtion.calculate(arg) < funtion.calculate(total[i])) {
total[i] = arg;
} else {// hawks perform levy-based short rapid dives around the rabbit
for (int j = 0; j < dim; j++) {
arg1[j] = arg[j] + productdouble() * levy(1);
}
if (funtion.calculate(arg1) < funtion.calculate(total[i])) {
total[i] = arg1;
}
}
}
if (ran < 0.5 && Math.abs(escapingEnergy) < 0.5) {//% Hard besiege % rabbit try to escape by many zigzag deceptive motions
// % hawks try to decrease their average location with the rabbit
double J = 2 * (1 - productdouble());
double[] arg = new double[dim];
double[] arg1 = new double[dim];
for (int j = 0; j < dim; j++) {
arg[j] = xRabbitLocation[j] - escapingEnergy * (Math.abs(J * xRabbitLocation[j] - mean(total, j)));
}
if (funtion.calculate(arg) < funtion.calculate(total[i])) {
total[i] = arg;
} else {//Perform levy-based short rapid dives around the rabbit
for (int j = 0; j < dim; j++) {
arg1[j] = arg[j] + productdouble() * levy(1);
}
if (funtion.calculate(arg1) < funtion.calculate(total[i])) {
total[i] = arg1;
}
}
}
}
}
t++;
System.out.println(Arrays.toString(xRabbitLocation));
}
return rabbitEnergy;
}
/**
* 生成随机数
*
* @param UB
* @param LB
* @return
*/
public double productdouble(double UB, double LB) {
double r = Math.random();
while (r == 0.0) {
r = Math.random();
}
r = r * (UB - LB) + LB;
return r;
}
public double productdouble() {
double r = Math.random();
while (r == 0.0) {
r = Math.random();
}
return r;
}
/**
* 求平均值
*
* @param x 个体的坐标
* @return 平均值
*/
public double mean(double[] x) {
double sum = 0;
for (int i = 0; i < x.length; i++) {
sum += x[i];
}
return sum / x.length;
}
public double mean(double[][] x, int k) {
double sum = 0;
for (int i = 0; i < x.length; i++) {
sum += x[i][k];
}
return sum / x.length;
}
/**
* levy 飞行函数
*
* @return
*/
public double levy(int dim) {
double beta = 1.5;
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));
double u = productdouble();
double v = productdouble();
double o = 0.01 * u * sigma / Math.pow(Math.abs(v), (1 / beta)); //随机数要正态分布吗
return o;
}
/**
* 判断变量是否出界
* @param x
*/
public void panduan(double[][] x) {
for (int i = 0; i < x.length; i++) {
for (int i1 = 0; i1 < dim; i1++) {
if (x[i][i1] > UB[i1]) {
x[i][i1] = UB[i1];
}
if (x[i][i1] < LB[i1]) {
x[i][i1] = LB[i1];
}
}
}
}
public double[] getUB() {
return UB;
}
public void setUB(double[] UB) {
this.UB = UB;
}
public double[] getLB() {
return LB;
}
public void setLB(double[] LB) {
this.LB = LB;
}
public double getRabbitEnergy() {
return rabbitEnergy;
}
public void setRabbitEnergy(double rabbitEnergy) {
this.rabbitEnergy = rabbitEnergy;
}
public int getT() {
return T;
}
public void setT(int t) {
T = t;
}
public int getN() {
return N;
}
public void setN(int n) {
N = n;
}
public double[] getxRabbitLocation() {
return xRabbitLocation;
}
public void setxRabbitLocation(double[] xRabbitLocation) {
this.xRabbitLocation = xRabbitLocation;
}
public int getDim() {
return dim;
}
public void setDim(int dim) {
this.dim = dim;
}
public double[][] getTotal() {
return total;
}
public void setTotal(double[][] total) {
this.total = total;
}
}
package Algorithm.HHO;
/**
* @auther guoyu
* @create 2020-11-15 11:03
*/
public interface Funtion {
public double calculate(double[] x);
}
package Algorithm.HHO;
/**
* @auther guoyu
* @create 2020-11-15 11:03
*/
public class Funtion1 implements Funtion {
@Override
public double calculate(double[] x){
return Math.pow((x[1]-Math.pow(x[0],2)*5.1/(4*Math.pow(Math.PI,2))+5/Math.PI*x[0]-6),2)+10*(1-1/(8*Math.PI))* Math.cos(x[0])+10;
}
}
package Algorithm.HHO;
/**
* @auther guoyu
* @create 2020-11-14 21:55
*/
public class Test {
public static void main(String[] args) {
double[] a = new double[]{10,15};
double[] b = new double[]{-5,0};
HHOTest2 hhoTest = new HHOTest2(a, b, 500, 30, 2);
System.out.println(hhoTest.HHOFuction(new Funtion1(), HHOTest2.MIN));
}
}
输出:
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
[3.141546874209301, 2.275089218720725]
0.39788737065562607
matlab输出:
The best location of HHO is: 3.1415 2.2752
The best fitness of HHO is: 0.39789