当前位置:首页 > Java > 正文

Java实现遗传算法(从零开始掌握智能优化算法)

在人工智能和优化领域,遗传算法(Genetic Algorithm, GA)是一种模拟自然选择和生物进化过程的智能算法。它被广泛应用于解决复杂的优化问题,比如路径规划、函数优化、机器学习参数调优等。本教程将带你用Java语言从零开始实现一个简单的遗传算法,即使你是编程小白,也能轻松上手!

Java实现遗传算法(从零开始掌握智能优化算法) Java遗传算法 遗传算法入门 Java优化算法 智能算法教程 第1张

什么是遗传算法?

遗传算法受达尔文“物竞天择,适者生存”思想启发,通过模拟生物进化过程来寻找最优解。其核心步骤包括:

  • 初始化种群:随机生成一组候选解(称为“个体”)。
  • 适应度评估:计算每个个体的“适应度”(即目标函数值)。
  • 选择:根据适应度挑选优秀个体作为父母。
  • 交叉(Crossover):父母个体交换部分基因,产生子代。
  • 变异(Mutation):以小概率随机改变子代的某些基因。
  • 迭代:重复上述过程,直到满足终止条件(如达到最大代数或找到满意解)。

实战:用Java实现遗传算法求解最大值

我们以一个经典例子为例:在区间 [0, 31] 内,找到使函数 f(x) = x² 最大的整数 x。虽然这个问题很简单,但它能清晰展示遗传算法的基本流程。

我们将用5位二进制串表示 x(因为 2⁵ = 32,刚好覆盖 0~31)。例如,"11111" 表示 31,"00000" 表示 0。

第一步:定义个体类

public class Individual {    // 用 boolean 数组表示基因(true=1, false=0)    private boolean[] genes;    private int fitness = 0;    public Individual() {        genes = new boolean[5]; // 5位基因        for (int i = 0; i < genes.length; i++) {            genes[i] = Math.random() > 0.5;        }    }    // 获取基因    public boolean getGene(int index) {        return genes[index];    }    // 设置基因    public void setGene(int index, boolean value) {        genes[index] = value;        fitness = 0; // 修改基因后需重新计算适应度    }    // 获取基因长度    public int size() {        return genes.length;    }    // 将基因转换为十进制整数    public int getDecimalValue() {        int value = 0;        for (int i = 0; i < genes.length; i++) {            if (genes[i]) {                value += Math.pow(2, genes.length - 1 - i);            }        }        return value;    }    // 计算适应度:f(x) = x²    public int getFitness() {        if (fitness == 0) {            int x = getDecimalValue();            fitness = x * x;        }        return fitness;    }    @Override    public String toString() {        StringBuilder sb = new StringBuilder();        for (boolean gene : genes) {            sb.append(gene ? "1" : "0");        }        return sb.toString();    }}

第二步:定义种群类

import java.util.Arrays;public class Population {    private Individual[] individuals;    public Population(int size) {        individuals = new Individual[size];        for (int i = 0; i < size; i++) {            individuals[i] = new Individual();        }    }    public Individual getIndividual(int index) {        return individuals[index];    }    public Individual getFittest() {        Individual fittest = individuals[0];        for (int i = 1; i < individuals.length; i++) {            if (individuals[i].getFitness() > fittest.getFitness()) {                fittest = individuals[i];            }        }        return fittest;    }    public int size() {        return individuals.length;    }}

第三步:实现遗传算法主逻辑

public class GeneticAlgorithm {    private static final double MUTATION_RATE = 0.015;    private static final int TOURNAMENT_SIZE = 3;    private static final boolean ELITISM = true;    // 交叉操作    public static Individual crossover(Individual parent1, Individual parent2) {        Individual child = new Individual();        int midpoint = (int) (Math.random() * parent1.size());        for (int i = 0; i < child.size(); i++) {            if (i < midpoint) {                child.setGene(i, parent1.getGene(i));            } else {                child.setGene(i, parent2.getGene(i));            }        }        return child;    }    // 变异操作    public static void mutate(Individual individual) {        for (int i = 0; i < individual.size(); i++) {            if (Math.random() < MUTATION_RATE) {                boolean gene = individual.getGene(i);                individual.setGene(i, !gene);            }        }    }    // 锦标赛选择    public static Individual tournamentSelection(Population population) {        Population tournament = new Population(TOURNAMENT_SIZE);        for (int i = 0; i < TOURNAMENT_SIZE; i++) {            int randomId = (int) (Math.random() * population.size());            tournament.getIndividual(i).setGene(0, population.getIndividual(randomId).getGene(0));            // 简化:实际应深拷贝整个个体        }        return tournament.getFittest();    }}

第四步:运行主程序

public class Main {    public static void main(String[] args) {        int populationSize = 20;        int generations = 100;        Population population = new Population(populationSize);        System.out.println("初始最优解: " + population.getFittest().getDecimalValue()                          + " (适应度: " + population.getFittest().getFitness() + ")");        for (int generation = 0; generation < generations; generation++) {            Population newPopulation = new Population(0);            // 精英保留策略            if (GeneticAlgorithm.ELITISM) {                newPopulation.getIndividual(0).setGene(0, population.getFittest().getGene(0));                // 实际应完整复制最优个体            }            // 生成新种群            int elitismOffset = GeneticAlgorithm.ELITISM ? 1 : 0;            for (int i = elitismOffset; i < populationSize; i++) {                Individual parent1 = GeneticAlgorithm.tournamentSelection(population);                Individual parent2 = GeneticAlgorithm.tournamentSelection(population);                Individual child = GeneticAlgorithm.crossover(parent1, parent2);                GeneticAlgorithm.mutate(child);                newPopulation.getIndividual(i).setGene(0, child.getGene(0));                // 同样,简化处理            }            population = newPopulation;            System.out.println("第 " + (generation + 1) + " 代最优解: "                              + population.getFittest().getDecimalValue()                              + " (适应度: " + population.getFittest().getFitness() + ")");        }        System.out.println("\n最终结果: x = " + population.getFittest().getDecimalValue()                          + ", f(x) = " + population.getFittest().getFitness());    }}

💡 提示:以上代码为了教学简化了部分细节(如深拷贝),在实际项目中建议完善对象复制逻辑。

总结与延伸

通过本教程,你已经掌握了如何用Java遗传算法解决一个简单的优化问题。虽然示例简单,但其结构适用于更复杂的问题——只需修改适应度函数、基因编码方式和交叉/变异策略即可。

如果你想深入学习遗传算法入门知识,可以尝试以下方向:

  • 使用实数编码代替二进制编码
  • 实现多目标优化(如NSGA-II算法)
  • 将遗传算法应用于旅行商问题(TSP)
  • 结合神经网络进行超参数优化

无论你是学生、开发者还是AI爱好者,掌握这种Java优化算法都将为你打开智能计算的大门。希望这篇智能算法教程对你有所帮助!