遗传算法(Java模拟)

使用Java模拟达尔文进化论中物竞天择的过程:

分为三个部分:

第一步:初始化族群

第二步:选择

第三步:繁殖

结果展示:

遗传算法(Java模拟)

族群类:

import java.util.ArrayList;
import java.util.Random;

/**
 * @Auther: wdq
 * @Date: 2021/4/18 21:11
 * @Description:
 */
public class Population {

    /**
     * 突变率
     */
    private static float mutationRate;

    /**
     * 个体数组
     */
    private static DNA[] populations;

    /**
     * 目标答案
     */
    private static String target;

    /**
     * 代数
     */
    private static int cnt = 0;

    /**
     * 输出适应度最好的一个
     *
     * @param cnt 代数
     */
    private static void printBest(int cnt) {
        float t = 0;
        int index = 0;
        for (int i = 0; i < populations.length; i++) {
            if (t < populations[i].fitness) {
                t = populations[i].fitness;
                index = i;
            }
        }
        System.out.println("第" + cnt + "代中,适应度" + (int) (populations[index].fitness * 100) + "%:" + populations[index].getPhrase());
    }

    /**
     * 选择
     */
    private static void draw() {
        // 计算适应度
        for (DNA population : populations) {
            population.fitness(target);
        }
        printBest(cnt);
        // 创建交配池
        ArrayList<DNA> matingPool = new ArrayList<>();
        // 按照适应度得分将个体加入交配池
        for (DNA population : populations) {
            int n = (int) (population.fitness * 100);
            for (int j = 0; j <= n; j++) {
                matingPool.add(population);
            }
        }
        // 繁殖
        Random random = new Random();
        for (int i = 0; i < populations.length; i++) {
            int a = random.nextInt(matingPool.size());
            int b = random.nextInt(matingPool.size());
            DNA parentA = matingPool.get(a);
            DNA parentB = matingPool.get(b);
            // 交叉
            DNA child = parentA.crossover(parentB);
            // 变异
            child.mutate(mutationRate);
            populations[i] = child;
        }
    }

    /**
     * 初始化
     */
    private static void setup() {
        int totalPopulation = 150;
        target = "tobeornottobe";
        mutationRate = (float) 0.01;
        populations = new DNA[totalPopulation];
        for (int i = 0; i < populations.length; i++) {
            populations[i] = new DNA(target.length());
        }
    }

    /**
     * 主程序
     * @param args
     */
    public static void main(String[] args) {
        setup();
        boolean ok = true;
        while (ok) {
            cnt++;
            draw();
            for (DNA population : populations) {
                if (population.getPhrase().equals(target)) {
                    ok = false;
                    population.fitness(target);
                    System.out.println("第"+(cnt+1)+"代中,适应度"+(int)(population.fitness*100)+"%:"+population.getPhrase());
                    break;
                }
            }
        }
    }

}

 DNA类

import java.util.Random;

/**
 * @Auther: wdq
 * @Date: 2021/4/18 20:51
 * @Description:
 */
public class DNA {

    public char[] genes;
    public float fitness;

    /**
     * 构造函数
     *
     * @param num DNA长度
     */
    public DNA(int num) {
        Random random = new Random();
        genes = new char[num];
        for (int i = 0; i < genes.length; i++) {
            genes[i] = (char) (random.nextInt(128 - 32) + 32);
        }
    }

    /**
     * 计算适应度
     *
     * @param target 目标
     */
    public void fitness(String target) {
        int score = 0;
        for (int i = 0; i < genes.length; i++) {
            if(genes[0] == 't')
            {
                int a=0;
            }
            if (genes[i] == target.charAt(i)) {
                score ++;
            }
        }
        fitness = (float) score / (float)target.length();
    }

    /**
     * 繁殖
     * @param partner 和该DNA结合的DNA
     * @return DNA
     */
    public DNA crossover(DNA partner) {
        DNA child = new DNA(genes.length);
        int midpoint = new Random().nextInt(genes.length);
        for (int i = 0; i < genes.length; i++) {
            if (i < midpoint) child.genes[i] = genes[i];
            else child.genes[i] = partner.genes[i];
        }
        return child;
    }

    /**
     * 突变
     *
     * @param mutationRate 突变概率
     */
    public void mutate(float mutationRate) {
        Random random = new Random();
        for (int i = 0; i < genes.length; i++) {
            if (Math.random() < mutationRate) {
                genes[i] = (char) (random.nextInt(128 - 32) + 32);
            }
        }
    }

    /**
     * 转换成字符串
     * @return 表现型
     */
    public String getPhrase() {
        return new String(genes);
    }
}

创建自己的遗传算法

1、更改变量

突变因子和族群数量可修改 

2、适应度函数

适应度函数设计的好坏影响算法本身

3、基因型和表现型

表现型包含基因型。dna的基因不同,表现型可能相同也可能不同。设计类的时候,基因型可以设计成表现型的内部类

 

参考文献:《代码本色 用编程模拟自然系统》

上一篇:存储过程中的MySQL PREPARE语句


下一篇:.Net Core 访问 appsettings.json