进化算法实现

该博客介绍了如何使用遗传算法解决二维空间的优化问题。通过设置精度、种群数量、变量上下界、交叉和变异概率等参数,利用Java实现了一个简单的遗传算法。算法包括初始化种群、计算适应度、轮盘赌选择、交叉和变异操作,以及解码找到最优解。示例中展示了如何应用遗传算法求解一个特定的数学函数。
摘要由CSDN通过智能技术生成

```java
package evolutionary;

import java.util.*;

import static java.lang.Math.*;

public class Evolutionary {

    //精度
    static double precision= 0.0001f;
    //种群个数
    static int number=100;
    //位数
    static int bit_number;
    //上界
    static double[] uppers;
    //下界
    static double[] lowers;
    //交叉概率
    static float cross_probability=0.6f;
    //变异概率
    static float variation_probability=0.01f;
    //迭代次数
    static  int epoch=1000;
    //随机数
    static Random random = new Random();
    //测试数据
    static boolean[] test = new boolean[]{false, false, false, false, false, true, false, true, false, true, false, false, true, false, true, false, false,
            true, true, false, true, true, true, true, false, true, true, true, true, true, true, true, false};

    public static void main(String[] args) {

        uppers = new double[]{12.1, 5.8};
        lowers = new double[]{-3.0, 4.1};
//        uppers = new double[]{2.048, 2.048};
//        lowers = new double[]{-2.048, -2.048};
        evolutionary_algorithms(precision,number,uppers,lowers,cross_probability,variation_probability,epoch);
    }
    //f(x1,x2),适应度函数
    static double func(double[] x) {
        return 21.5 + x[0] * sin(4 * PI * x[0]) + x[1] * sin(20 * PI * x[1]);
    }

//    static double func(double[] x){
//        return 100*pow(x[1]-pow(x[0],2),2)+pow(1-x[1],2);
//    }
    /**
        @Param presion:精度
        @Param number:种群数量
        @Param uppers:对应自变量的上界数组
        @Param lowers:对应自变量的下界数组
        @Param func:适应度函数             暂未灵活设计
        @Param cross_probability:交叉概率
        @Param variation_probability:变异概率
        @Param epoch:迭代轮数
     **/
    static void evolutionary_algorithms(double precision,int number,double[] uppers,double[] lowers,float cross_probability,float variation_probability,int epoch){
        //总编码长度
        bit_number=0;
        //每个自变量的编码长度
        int[] bit_numbers = new int[uppers.length];
        for(int i=0;i<bit_numbers.length;i++){
            bit_numbers[i] = encode(uppers[i], lowers[i]);
            bit_number+=bit_numbers[i];
        }
        System.out.println("编码位数:" + bit_number);
        //种群
        boolean[][] population;
        //适应度
        double[] adaptability=new double[number];
        //对应个体
        boolean[][] next_population;
        //子代适应度值
        double[] next_adaptability;
        //每一代最优值
        double pre_child=0;
        //初始化种群
        population = init_population();
        for (int i = 0; i < epoch; i++) {
            System.out.println("第" + i + "epoch:");
            //计算个体适应度
            adaptability = adaptabilityFunc(population, bit_numbers);
            pre_child=Arrays.stream(adaptability).max().getAsDouble();
            System.out.println(pre_child);
            //轮盘赌
            next_population = roulette(population, adaptability);
            //交叉
            next_population = cross_operators(next_population, cross_probability);
            //变异
            next_population = variation(next_population, variation_probability);
            //子代适应度值
            next_adaptability = adaptabilityFunc(next_population, bit_numbers);
            //生成子代
            population = generate_children(population, adaptability, next_population, next_adaptability);
            //每一代最优值
        }
        //解码
        {
            boolean[] x_string;
            //自变量
            double[] xs=new double[bit_numbers.length];
            //断点位置
            int breakpoint;
            for (int i=0;i<adaptability.length;i++){
                if(adaptability[i]==pre_child){
                    breakpoint=0;
                    for(int j=0;j<bit_numbers.length;j++){
                        breakpoint+=bit_numbers[j];
                        if(j==0)
                            x_string=Arrays.copyOfRange(population[i], 0, breakpoint);
                        else
                            x_string=Arrays.copyOfRange(population[i], breakpoint-bit_numbers[j] ,breakpoint- 1);
                        xs[j]=decode(x_string, uppers[j], lowers[j]);
                    }
                }
            }
            System.out.println(Arrays.toString(xs));
        }
    }
    //初始化种群
    static boolean[][] init_population() {
        boolean[][] population_ = new boolean[number][bit_number];
        for (int i = 0; i < number; i++) {
            System.out.print("第" + i + "个:");
            for (int j = 0; j < bit_number; j++) {
                population_[i][j] = random.nextBoolean();
                if (population_[i][j])
                    System.out.print("1");
                else
                    System.out.print("0");
            }
            System.out.println();
        }
        return population_;
    }
    //计算个体适应度
    static double[] adaptabilityFunc(boolean population[][], int[] bit_numbers) {
        boolean[] x_string;
        //自变量
        double[] xs=new double[bit_numbers.length];
        //断点位置
        int breakpoint;
        double[] adaptability_ = new double[population.length];
        for (int i = 0; i < population.length; i++) {
            breakpoint=0;
            for(int j=0;j<bit_numbers.length;j++){
                breakpoint+=bit_numbers[j];
                if(j==0)
                    x_string=Arrays.copyOfRange(population[i], 0, breakpoint);
                else
                    x_string=Arrays.copyOfRange(population[i], breakpoint-bit_numbers[j] ,breakpoint- 1);
                xs[j]=decode(x_string, uppers[j], lowers[j]);
            }
            adaptability_[i] = func(xs);
        }
        return adaptability_;
    }
    //轮盘赌
    static boolean[][] roulette(boolean[][] population, double[] adaptability) {
        //适应度比值
        double[] probability;
        //累计适应度
        double[] cumulation_probability;
        //对应个体
        boolean[][] next_population;
        //计算比值
        probability = adaptability_probability(adaptability);
        //计算累积适应度
        cumulation_probability = cumulation_probability(probability);
        //选择对应个体
        next_population = choose_parents(cumulation_probability, population);
        return next_population;
    }
    //计算比值
    static double[] adaptability_probability(double[] adaptability) {
        double[] probability_ = new double[adaptability.length];
        double adaptability_all = 0;
        for (int i = 0; i < adaptability.length; i++) {
            adaptability_all += adaptability[i];
        }
        for (int i = 0; i < adaptability.length; i++) {
            probability_[i] = adaptability[i] / adaptability_all;
        }
        return probability_;
    }
    //计算累积适应度
    static double[] cumulation_probability(double[] probability) {
        double[] cumulation_probability_ = new double[probability.length];
        cumulation_probability_[0] = probability[0];
        for (int i = 1; i < cumulation_probability_.length; i++) {
            cumulation_probability_[i] = cumulation_probability_[i - 1] + probability[i];
        }
        return cumulation_probability_;
    }
    //选择父代
    static boolean[][] choose_parents(double[] cumulation_probability, boolean[][] population) {
        double random1;
        boolean[][] next_population = new boolean[number][bit_number];
        for (int i = 0; i < number; i++) {
            random1 = random.nextDouble();
            for (int j = 0; j < population.length; j++) {
                if (j == 0) {
                    if (0 <= random1 && random1 < cumulation_probability[j]) {
                        System.arraycopy(population[j],0,next_population[i],0,population[j].length);
                        break;
                    }
                } else {
                    if (cumulation_probability[j - 1] <= random1 && random1 < cumulation_probability[j]){

                        System.arraycopy(population[j - 1],0,next_population[i],0,population[j-1].length);
                    }
                }
            }
        }
        return next_population;
    }
    static int boolean_to_int(boolean[] x_string) {
        int number = 0;
        for (int i = 0; i < x_string.length; i++) {
            if (x_string[i])
                number += pow(2, (x_string.length - i));
        }
        return number;
    }
    //编码
    static int encode(double upper, double lower) {
        //位数
        return (int) ceil(log((upper - lower) / precision + 1) / log(2));
    }
    //解码
    static double decode(boolean[] x_string, double upper, double lower) {
        return lower + (upper - lower) * boolean_to_int(x_string) / (pow(2, (x_string.length + 1)) - 1);
    }
    //交叉算子
    static boolean[][] cross_operators(boolean[][] next_population, float cross_probability) {
        for (int i = 0; i < number; i = i + 2) {
            if (random.nextDouble() < cross_probability)
                next_population = two_points_cross(next_population, i, i + 1);
        }
        return next_population;
    }
    //两条染色体交叉
    static boolean[][] two_points_cross(boolean[][] next_population, int i, int j) {
        int random1 = random.nextInt(bit_number);
        int random2 = random.nextInt(bit_number);
        int max_bound = Math.max(random1, random2);
        int min_bound = Math.min(random1, random2);
        boolean swap;

        for (int m = min_bound; m < max_bound; m++) {
            swap = next_population[i][m];
            next_population[i][m] = next_population[j][m];

            next_population[j][m] = swap;
        }
        return next_population;
    }
    //变异算子
    static boolean[][] variation(boolean[][] next_population, float variation_probability) {
        Random random = new Random();
        for (int i = 0; i < number * bit_number; i++) {
            if (random.nextDouble() <= variation_probability) {
                next_population[(int) (i / bit_number)][i % bit_number] = !next_population[(int) (i / bit_number)][i % bit_number];
            }
        }
        return next_population;
    }
    //生成子代
    static boolean[][] generate_children(boolean[][] population, double[] adaptability, boolean[][] next_population, double[] next_adaptability) {
        boolean[][] end_populaition = new boolean[population.length][population[0].length];
        int length = population.length;

        population = Arrays.copyOf(population, population.length + next_population.length);
        System.arraycopy(next_population, 0, population, length, next_population.length);
        adaptability = Arrays.copyOf(adaptability, adaptability.length + next_adaptability.length);
        System.arraycopy(next_adaptability, 0, adaptability, length, next_adaptability.length);
        double max1_number;
        double max2_number;
        int m1, m2;
        if (adaptability[0] > adaptability[1]) {
            max1_number = adaptability[0];
            max2_number = adaptability[1];
            m1 = 0;
            m2 = 1;
        } else {
            max1_number = adaptability[1];
            max2_number = adaptability[0];
            m1 = 1;
            m2 = 0;
        }
        for (int i = 2; i < adaptability.length; i++) {
            if (adaptability[i] > max1_number) {
                max2_number = max1_number;
                max1_number = adaptability[i];
                m2 = m1;
                m1 = i;
            } else if (adaptability[i] > max2_number) {
                max2_number = adaptability[i];
                m2 = i;
            }
        }
        end_populaition = roulette(population, adaptability);
        System.arraycopy(population[m1],0, end_populaition[0] ,0, end_populaition[0] .length);
        System.arraycopy(population[m2],0,  end_populaition[1] ,0, end_populaition[1] .length);
        return end_populaition;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值