采用遗传算法求解函数最优值

10 篇文章 0 订阅
4 篇文章 0 订阅

一、实验要求

遗传算法(Genetic AlgorithmsGA)是一种基于自然选择和自然遗传机制的搜索算法,它是一种有效的解决最优化问题的方法,属于一种进化算法。本实验要求采用简单遗传算法求解如下一元函数的最大值:

二、遗传算法基本流程

遗传算法由美国Michigan大学的John Holland和他的同事及学生提出的。类似于自然界演化的基本法则,适者生存是遗传算法的核心机制:复制(reproduce)、杂交(crossover)、变异(mutation)等自然界的生物演化规则在遗传算法中都得到类似的体现。遗传算法是从代表问题可能潜在解集的一个种群开始的。初代种群产生之后,按照适者生存、优胜劣汰的原理,逐代进化产生出越来越好的近似种群在每一代中,根据问题域中个体适应度大小挑选个体,并借助自然遗传学的遗传算子进行组合交叉和变异,产生出代表解的解集的种群。这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码可以作为问题近似最优解。

遗传算法的流程框图大体如下:

三、遗传算法求解详细过程

1)编码

变量x作为实数,可以视为遗传算法的表现形式。从表现型到基因型的映射称为编码。二进制编码将某个变量值代表的个体表示为一个[0,1]二进制串(遗传算法最简单、最经典的编码方法)。若设定求解精确到6位小数,由于区间长度为2-(-1)=3,必须将区间[-1,2]分为3*10^6等份。因为2097152=2^21<3*10^6<=2^22=4194304,所以编码的二进制串长至少需要22位。

2)产生初始种群

个体由串长为22的随机产生的二进制串组成染色体的基因码,产生一定数目的个体组成种群,种群的大小(规模)就是指种群中的个体数目。

3)计算适应度

适应度大的个体其存活和被选中的概率大。适应度的计算就是对个体的计算,本例求函数最大值,目标函数值大的个体适应度大,所以直接引用目标函数作为适应度函数f(s)=f(x)。例如x1=0.637197通过编码得到的二进制串是s1=[1000101110110101000111],这个串就是个体。此个体的适应度就是:

假设选择种群数量为3 ,每个个体为s1=[1000101110110101000111],s2=[0000001110000000010000],s3=[1110000000111111000101],分别对应于数量值x1=0.637197,x2=-0.958973, x3=1.627888,另两个个体的适应度计算如下:

4)选择

采用轮盘赌选择法,f(s1)=2.286345f(s2)=1.078878f(s3)=3.250650,把三个适应度依比例画在轮盘上,转动轮盘,最后停在哪里,就选择谁,适应度大的被选中概率大。

选择方法的实现:产生[0,1]间的随机数,以随机数落在那个范围进行选择:

[0,0.16)[0.16,0.51)[0.51,1]

5)遗传操作

下面是经过选择操作后的两个个体:

s2=[00000 01110000000010000] 

s3=[11100 00000111111000101]

首先执行单点交叉,随机随机选择交叉点,将之后的串交叉,得到新的两个个体为:

s2'=[00000 00000111111000101] 
s3'=[11100 01110000000010000]

这两个个体的适应度分别为:

6)变异操作

假定以一小概率选择S3的第5个遗传因子(第5位)变异,遗传因子由原来的0变为1,产生新个体:s3'=[1110100000111111000101],该个体适应度为:

个体的适应度比它的父个体的适应度减小了。

但如果选中第11个遗传因子变异,产生新个体为s3''= [11100000001111111000101],适应度,又发现s3''的适应度比其父个体的适应度改善了,这说明变异操作的扰动作用(全局搜索)。

CODE:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//import java.util.Scanner;

public class GA {
    static int geneLength = 22;
    static int individualSize = 16;
    static int maxEvolve = 50;
    static double crossoverProbability = 0.7;
    static double mutationProbablility = 0.2;
    static double sumFitness = 0.0;
    static class individual implements Cloneable{
        double fitness;
        double Pl;
        double Pr;
        int[] gene;
        
        public individual(double fitness, double pl, double pr, int[] gene) {
            super();
            this.fitness = fitness;
            Pl = pl;
            Pr = pr;
            this.gene = gene;
        }

        @Override
        public String toString() {
            return "individual [fitness=" + fitness + ", Pl=" + Pl + ", Pr=" + Pr + ", gene=" + Arrays.toString(gene)
                    + "]";
        }
        
        public Object clone(){
            individual idd = null;
            try {
                idd = (individual) super.clone();
            } catch (CloneNotSupportedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            idd.gene = this.gene.clone();
            return idd;
        }
    }

    static List<individual> initPop(){
        List<individual> population = new ArrayList<individual>();
        int ca = 0;
        while(ca < individualSize){
            int[] gene = new int[geneLength];
            for(int i=0; i<geneLength; i++){
                gene[i] = (int)(Math.random()*100)%2;
            }
            population.add(new individual(0.0, 0.0, 0.0, gene));
            ca++;
        }
        return population;
    }

    static void updateFitness(List<individual> population){
        int constant = 4194103;
        for(int i=0; i<individualSize; i++){
            StringBuffer sb = new StringBuffer();
            for(int j=0; j<geneLength; j++){
                sb.append(population.get(i).gene[j]);
            }
            int H = Integer.valueOf(sb.toString(), 2);
            double x = -1.0 + 3.0*(H*1.0/constant*1.0);
            population.get(i).fitness = x*Math.sin(10*Math.PI*x)+2.0;
            sumFitness += population.get(i).fitness;
        }
    }


    static individual bestIndividual(List<individual> population){
        individual best = (individual) population.get(0).clone();
        for(int i=1; i<individualSize; i++){
            if(population.get(i).fitness > best.fitness){
                best = (individual) population.get(i).clone();
            }
        }
        return best;
    }

    static List<individual> selectPop(List<individual> population){
        int ca = 0;
        List<individual> newPopulation = new ArrayList<individual>();
        double start = 0.0;
        for(int i=0; i<individualSize; i++){
            double p = population.get(i).fitness/sumFitness;
            population.get(i).Pl = start;
            population.get(i).Pr = p + start;
            start = population.get(i).Pr;

        }
        while(ca < individualSize){
            boolean flag = false;
            double P = Math.random();
            for(int j=0; j<individualSize; j++){
                if(P>population.get(j).Pl && P<population.get(j).Pr){
                    newPopulation.add(population.get(j));
                    flag = true;
                    break;
                }
            }
            if(!flag){
                newPopulation.add(bestIndividual(population));
            }
            ca++;
        }
        return newPopulation;
    }

    static void crossover(List<individual> population){
        boolean flag = false;
        int father = 0;
        int mother = 0;

        for(int i=0; i<individualSize; i++){
            double P = Math.random();
            if(P < crossoverProbability){
                if(flag){
                    mother = i;
                    int l = (int) (Math.random()*geneLength);
                    int r = (int) (Math.random()*geneLength);
                    if(l>r){
                        int t = l;
                        l = r;
                        r = t;
                    }
                    int t[] = new int[geneLength];
                    for(int f=l; f<r; f++){
                        t[f] = population.get(father).gene[f];
                        population.get(father).gene[f] = population.get(mother).gene[f];
                        population.get(mother).gene[f] = t[f];
                    }
                    flag = false;
                }
                else{
                    father = i;
                    flag = true;
                }
            }
        }
    }

    static void mutation(List<individual> population){
        for(int i=0; i<individualSize; i++){
            double p = Math.random();
            if(p<mutationProbablility){
                int cnt = (int) (Math.random()*geneLength);
                while(cnt>0){
                    int point = (int) (Math.random()*(geneLength-1));
                    population.get(i).gene[point] = 1-population.get(i).gene[point];
                    cnt -= 1;
                }
            }
        }


        for(int i=0; i<geneLength; i++){
            int count = 0;
            for(int j=0; j<individualSize; j++){
                count += population.get(j).gene[i];
            }


            if(count<3 || count>(individualSize-3)){
                int cn = (int) (Math.random()*individualSize);
                population.get(cn).gene[i] = 1-population.get(cn).gene[i];
                int cn1 = (int) (Math.random()*individualSize);
                while(cn1==cn){
                    cn1 = (int) (Math.random()*individualSize);
                }
                population.get(cn1).gene[i] = 1-population.get(cn1).gene[i];
            }
        }


    }

    public static void main(String[] args) {
// Scanner in = new Scanner(System.in);
        int ca = 0;
        List<individual> population = initPop();
        updateFitness(population);
        List<individual> bestList = new ArrayList<individual>();
        while(ca < maxEvolve){
            List<individual> newP = selectPop(population);
            crossover(newP);
            mutation(newP);
            population = newP;
            updateFitness(population);
            bestList.add(bestIndividual(population));
            ca++;
            System.out.println();
            for(int i=0; i<individualSize; i++){
                System.out.print("基因:"+Arrays.toString(population.get(i).gene)+" ");
                System.out.println("函数值:"+population.get(i).fitness);
            }
        }
        System.out.println("---------------结果---------------");
        individual P = bestIndividual(population);
        System.out.print("基因:"+Arrays.toString(P.gene)+" ");
        System.out.println("函数值:"+P.fitness);
    }
}

输出:

问题函数图像:

算法进化图像:

  • 16
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
遗传算法是一种启发式搜索算法,常被用于解决函数最优问题。在Matlab中,可以使用遗传算法工具箱来实现遗传算法求解函数最优。 首先,需要定义适应度函数。适应度函数一般根据问题的特点来设计,目的是对个体的适应程度进行评估。适应度函数的好坏直接影响到遗传算法的搜索结果。 接下来,需要定义遗传算法的参数,如种群大小、遗传代数、交叉概率、变异概率等。种群大小决定了每一代中有多少个个体参与进化,遗传代数表示遗传算法的迭代次数,交叉概率和变异概率控制了遗传算法的搜索空间。 然后,初始化种群。种群是由一定数量的个体组成的集合,每个个体表示问题的一个可能解。通常,可以使用随机数生成一些初始个体作为种群的初始解。 接着,根据选择、交叉和变异等操作进行遗传算法的迭代。在每一代中,根据适应度函数对种群中的个体进行选择、交叉和变异操作,生成新的子代个体。通过迭代更新种群,逐渐寻找到适应度更好的个体。 最后,根据适应度函数对最终的种群进行评估,找到具有最优适应度的个体。该个体即为函数最优解。 总之,使用Matlab中的遗传算法工具箱,可以较为方便地求解函数最优。通过适应度函数的定义、参数的设置、种群的初始化以及遗传算法的迭代等步骤,可以找到函数最优解。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值