遗传算法GA,0-1规划(背包)问题,快速易懂入门,附完整程序

毕业论文用到了遗传算法。根据的学习心得,用最简洁易懂的方式去描述一下。我做的是单目标最小值优化问题,实现n维的计算。

目录:

一. 遗传算法简介

二. 须知一般术语

三.流程图

四.实例说明

五.程序如下

附完整程序

一.遗传算法简介

解决最佳化的搜索算法,是进化算法的一种。包括遗传、突变、自然选择以及杂交等。遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)的抽象表示(称为染色体)的种群向更好的解进化。一般解用二进制表示。解的维数作为基因数,一组解作为一个染色体。一组染色体表示一个群体。适应度函数作为评价标准,也就是我们所求的目标函数。通过自然选择和突变产生新的生命种群,该种群在算法的下一次迭代中成为当前种群。

二.须知一般术语

基因:染色体的内部表现,也是可行解的个数

染色体:通俗讲就是一组解,也是一个个体

种群:一组染色体,多个个体,就是一个种群,我们从种群中进化出一个最优个体,就是最优解。

适应度:度量某个物种对于生存环境的适应程度,可以理解为就是目标函数

编码:对解的范围进行二进制编排

解码:二进制编码对应的十进制

选择(selection):以一定的概率从种群中选择若干个个体。

交叉(crossover):两个染色体的某一相同位置处切断,相互交换片段,形成两个新的染色体。

变异(mutation):一定的概率变异,产生新的染色体,例如0变为1

三.流程图

四.实例说明

在这里插入图片描述

题目很简单,主要看求解过程
步骤:

  1. 作为0-1规划问题,其解为0或者1,则用一位二进制表示

  2. i为30,则随机生成30位二进制,作为一组可行解

  3. 带入适应度函数即可

  4. 设置种群数量。一般为300,迭代1000次.

  5. 此0-1规划,只需初始化个体(编码)即可,因为编码与解码一样,都是0或1

五.程序如下

初始化染色体

class ClsInit {
    //初始化一条染色体,可解性的个数
    public int[] initSingle(int GENE){
        int[] res = new int[GENE];
        for(int i = 0; i < GENE; i++){
            if(Math.random() < 0.5){
                res[i]=0;
            }else{
                res[i]=1;
            }
        }
        return res;
    }

    //初始化一组染色体,即二维数组
    public int[][] initAll(int GENE,int groupsize){
        int[][] iAll = new int[groupsize][GENE];
        for(int i = 0; i < groupsize; i++){
            iAll[i] = initSingle(GENE);
        }
        return iAll;
    }
}

计算个体的适应度

class ClsFitness {
    //计算个体的适应度
    public double fitSingle(int[] str,int GENE){
        double fitness=0;
        for (int i = 0; i < str.length; i++) {
            fitness += str[i];

        }
        return fitness;
    }

    //计算二维数组的适应度
    public double[] fitAll(int str[][],int GENE){
        double [] fit = new double[str.length];
        for(int i = 0;i < str.length; i++){
            fit[i] = fitSingle(str[i],GENE);
        }
        return fit;
    }

    //适应度最值的序号
    public int mFitNum(double fit[]){
        double m = fit[0];
        int n = 0;
        for(int i = 1;i < fit.length; i++){
            if(fit[i] < m){
                m = fit[i];
                n = i;
            }
        }
        return n;
    }



    //适应度最值
    public double mFitVal(double fit[]){
        double m = fit[0];
        for(int i = 1;i < fit.length; i++){
            if(fit[i] < m){
                m = fit[i];
            }
        }
        return m;
    }
}

选择

class ClsRWS {
    ClsInit init = new ClsInit();
    ClsFitness fitness = new ClsFitness();
    /* fit[]适应度数组
    *  group[]群体数组
    *  GENE基因数,可行解的维数
    * */
    public int[][] RWS(int group[][], int GENE){
        double p[] = new double[group.length];	//染色体概率数组
        int[][] newgroup = new int[group.length][GENE];
        double F = 0;

        double[]fit = fitness.fitAll(group,GENE);//计算适应度数组

        //所有适应度的和F
        for(int i = 0; i < fit.length; i++){
            F = F +fit[i];
        }

        //初始化p[]
        for(int i = 0; i < fit.length; i++){
            p[i] = fit[i] / F;
        }

        //求出适应度最大的个体min,它的序号是min
        int min = fitness.mFitNum(fit);


        //转动轮盘,适应度大的被选中的概率大
        for (int i = 0; i < fit.length; i++){
            double r = Math.random();
            double q= 0;	//累计概率

            //适应度最大的个体直接继承
            if(i == min){
                for (int j = 0; j < GENE; j++)
                    newgroup[i][j] = group[i][j];
                    p[i] = 0;	//将其概率置0
                    continue;


            }


            //遍历轮盘,轮盘指针停在哪个区域
            for(int j = 0; j < fit.length; j++){
                q += p[j];
                if(r <= q){
                    for (int k = 0; k < GENE; k++) {
                        newgroup[i][k]=group[j][k];//假如被选中,保留进下一代
                        p[j] = 0;	//将其概率置0
                        break;
                    }

                }
                newgroup[i] = init.initSingle(GENE);	//假如没被选中,被外来者取代
            }
        }
        return newgroup;
    }
}

交叉

class ClsCross {
    ClsFitness fitness = new ClsFitness();
    //group群体
    //GENE基因数
    //mFitNum最大适应度染色体序号
    public int[][] cross(int[][] group,int GENE,double crossRate){
        int []temp1=new int [GENE];
        int []temp2=new int [GENE];
        int pos = 0;

        double[] fit = fitness.fitAll(group,GENE);
        int mFitNum = fitness.mFitNum(fit);	//计算适应度最小的染色体序号
        int[] min = new int[GENE];
        for (int i = 0; i < GENE; i++) {
            min[i]=group[mFitNum][i];
        }
        for(int i = 0; i < group.length; i++){
            if(Math.random() < crossRate){
                pos = (int)(Math.random()*GENE) + 1;//交叉点

                for (int j = 0; j < pos; j++) {
                    temp1[j]=group[i][j];
                    temp2[j]=group[(i+1)%group.length][j];
                }

                for (int j = pos; j < GENE; j++) {
                    temp1[j]=group[(i+1)%group.length][j];
                    temp2[j]=group[i][j];
                }

                for (int j = 0; j < GENE; j++) {
                    group[i][j]=temp1[j];
                    group[(i+1) % group.length][j]=temp2[j];
                }

            }
        }
        for (int i = 0; i < GENE; i++) {
            group[0][i]=min[i];
        }
        return group;
    }
}

变异

class ClsMutation {
    ClsFitness fitness = new ClsFitness();
    public int[][] mutation(int[][] group,int GENE,double MP){
        double[] fit = fitness.fitAll(group,GENE);
        int mFitNum = fitness.mFitNum(fit);	//计算适应度最大的染色体序号
        int []min=new int [GENE];
        for(int i=0;i<GENE;i++)
        {
            min[i]=group[mFitNum][i];
        }


        for(int i = 0; i < group.length * MP; i++){
            int n = (int) (Math.random() * GENE * group.length );	//从[0,GENE * group.length)区间取随机数
            int chrNum = (int) (n / GENE);	//取得的染色体数组下标
            int gNum = (int)(n % GENE); 	//取得的基因下标

            if(group[chrNum][gNum] == 0 ){
                group[chrNum][gNum]=1;
            }else{
                group[chrNum][gNum]=0;
            }
        }


        for (int i = 0; i < GENE; i++) {
            group[0][i]=min[i];
        }
        return group;
    }
}

调用功能类

class GA {
    public static final int groupsize = 100;	//染色体数或者群体中个体数
    public static final double MP = 0.06;	//变异概率
    public static final double CP = 0.83;	//交叉概率
    public static final int ITERA = 300;	//迭代次数
    public static final int GENE =30;//基因数或者问题的维数



    //输出原群体和适应度,测试用
    public void outAll(int[][] group){
        ClsFitness fitness = new ClsFitness();
        ClsInit init = new ClsInit();
        for(int i=0;i<group.length;i++){
            group[i]=init.initSingle(GENE);
        }

        double fit[] = fitness.fitAll(group,GENE);
        System.out.println("原种群");
        for (int i = 0; i < group.length; i++) {
            for (int j = 0; j < GENE; j++) {
                System.out.print(group[i][j]);
            }
            System.out.println();

        }
        System.out.println("原群体适应度");
        for (int i = 0; i < group.length; i++) {
            System.out.println(fit[i]);
        }

    }

    double min;
    //输出适应度最小值,返回最优个体
    public int outmin(String string,int[][] group){
        ClsFitness fitness = new ClsFitness();
        double[] fit = fitness.fitAll(group,GENE);
        min = fitness.mFitVal(fit);
        int k = fitness.mFitNum(fit);
        System.out.println(string +min);
        System.out.print("可行解=");
        for (int i = 0; i < GENE; i++) {
            System.out.print(group[k][i]);
        }
        System.out.println();
        return fitness.mFitNum(fit);
    }

    public static void main(String[] args) {
        ClsInit init = new ClsInit();
        ClsRWS rws = new ClsRWS();
        ClsCross cross = new ClsCross();
        ClsMutation mutation = new ClsMutation();
        GA ga = new GA();

        int[][] group = init.initAll(ga.GENE,groupsize);	//初始化
        ga.outAll(group);


        for(int i = 0; i < ITERA; i++){
            System.out.println("第"+ i+ "代");
            group= rws.RWS(group, ga.GENE); //选择
            ga.outmin("选择适应度=",group);

            group = cross.cross(group,ga.GENE,CP);	//交叉
            ga.outmin("交叉适应度=",group);

            group = mutation.mutation(group, ga.GENE, MP);	//变异
            ga.outmin("变异适应度=",group);

            System.out.println("");
        }
    }
}

多维优化实例完整代码

  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Devour123

愿每一份用功都可以得到回报

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值