通用遗传算法
| package chapter5; |
| |
| import java.util.List; |
| |
| |
| |
| |
| |
| |
| |
| public abstract class Chromosome<T extends Chromosome<T>> implements Comparable<T> { |
| |
| public abstract double fitness(); |
| public abstract List<T> crossover(T other); |
| public abstract void mutate(); |
| public abstract T copy(); |
| @Override |
| public int compareTo(T o) { |
| Double mine = this.fitness(); |
| Double other = o.fitness(); |
| return mine.compareTo(other); |
| } |
| |
| } |
| package chapter5; |
| |
| import java.util.*; |
| import java.util.List; |
| |
| |
| |
| |
| |
| |
| |
| public class GeneticAlgorithm<C extends Chromosome<C>> { |
| |
| |
| |
| |
| public enum SelectType { |
| ROULETTE, TOURNAMENT; |
| } |
| |
| private List<C> population; |
| private double mutationChance; |
| private double crossChance; |
| private SelectType selectType; |
| private Random random; |
| |
| |
| |
| |
| |
| public GeneticAlgorithm(List<C> initialPopu, double mutationChance, |
| double crossChance, SelectType selectType) { |
| this.population = initialPopu; |
| this.mutationChance = mutationChance; |
| this.crossChance = crossChance; |
| this.selectType = selectType; |
| this.random = new Random(); |
| } |
| |
| |
| |
| |
| |
| |
| private List<C> pickRoulette(double[] wheel, int numPicks) { |
| List<C> picks = new ArrayList<>(); |
| for (int i = 0; i < numPicks; i++) { |
| |
| double pick = random.nextDouble(); |
| |
| for (int j = 0; j < wheel.length; j++) { |
| pick -= wheel[j]; |
| if (pick <= 0) { |
| |
| picks.add(population.get(j)); |
| } |
| } |
| } |
| return picks; |
| } |
| |
| |
| |
| |
| |
| |
| private List<C> pickTournament(int partchromoNum, int picksNum) { |
| |
| Collections.shuffle(population); |
| |
| List<C> tournamet = population.subList(0, partchromoNum); |
| |
| Collections.sort(tournamet,Collections.reverseOrder()); |
| return tournamet.subList(0,picksNum); |
| } |
| |
| |
| |
| |
| private void reproduceAndReplace(){ |
| |
| List<C> newPopulation = new ArrayList<>(); |
| while (newPopulation.size()<population.size()){ |
| |
| List<C> parents; |
| |
| if (selectType == SelectType.ROULETTE){ |
| |
| double totalFitness = population.stream().mapToDouble(C::fitness).sum(); |
| |
| double[] wheel = population.stream().mapToDouble(C -> C.fitness() / totalFitness).toArray(); |
| parents = pickRoulette(wheel, 2); |
| |
| }else { |
| parents = pickTournament(population.size() / 2, 2); |
| } |
| |
| if (random.nextDouble()<crossChance){ |
| C father = parents.get(0); |
| C mother = parents.get(1); |
| List<C> crossover = father.crossover(mother); |
| newPopulation.addAll(crossover); |
| }else { |
| newPopulation.addAll(parents); |
| } |
| |
| if (newPopulation.size()>population.size()){ |
| newPopulation.remove(0); |
| } |
| |
| population = newPopulation; |
| } |
| } |
| |
| private void mutate(){ |
| for (C indiv:population){ |
| if (random.nextDouble()<mutationChance){ |
| indiv.mutate(); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public C run(int maxGenerations,double threshold){ |
| C best = Collections.max(population).copy(); |
| for (int generation =0;generation<maxGenerations;generation++){ |
| if (best.fitness()>=threshold){ |
| return best; |
| } |
| System.out.println("Generation:"+generation+" Best"+best.fitness()+ |
| " Avg"+population.stream().mapToDouble(C::fitness).average().orElse(0.0)); |
| reproduceAndReplace(); |
| mutate(); |
| C hightest = Collections.max(population); |
| if (hightest.fitness()>best.fitness()){ |
| best = hightest.copy(); |
| } |
| } |
| return best; |
| } |
| |
| } |
| package chapter5; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Random; |
| |
| |
| |
| |
| |
| |
| |
| public class SimpleEquation extends Chromosome<SimpleEquation>{ |
| |
| private int x,y; |
| @Override |
| public double fitness() { |
| return 6*x-x*x+4*y-y*y; |
| } |
| public SimpleEquation(){}; |
| public SimpleEquation(int x,int y){ |
| this.x = x; |
| this.y = y; |
| } |
| @Override |
| public List<SimpleEquation> crossover(SimpleEquation other) { |
| SimpleEquation child1 = new SimpleEquation(x,other.y); |
| SimpleEquation child2 = new SimpleEquation(other.x, y); |
| List<SimpleEquation> list = new ArrayList<>(); |
| list.add(child1); |
| list.add(child2); |
| return list; |
| } |
| |
| @Override |
| public void mutate() { |
| Random random = new Random(); |
| if (random.nextDouble()>0.5){ |
| if (random.nextDouble()>0.5){ |
| x +=1; |
| }else { |
| x -=1; |
| } |
| }else { |
| if (random.nextDouble()>0.5){ |
| y +=1; |
| }else |
| y -=1; |
| } |
| } |
| |
| @Override |
| public SimpleEquation copy() { |
| return new SimpleEquation(x,y); |
| } |
| |
| @Override |
| public String toString() { |
| return "X: " + x + ", y:" + y + "Fitness" + fitness(); |
| } |
| private static final int MAX_START = 100; |
| public static SimpleEquation randomInstance(){ |
| Random random = new Random(); |
| return new SimpleEquation(random.nextInt(MAX_START),random.nextInt(MAX_START)); |
| } |
| |
| public static void main(String[] args) { |
| ArrayList<SimpleEquation> initPopulation = new ArrayList<>(); |
| final int populationSize = 20; |
| final int generations =100; |
| final double threshold = 13.0; |
| for (int i =0; i<populationSize;i++){ |
| initPopulation.add(SimpleEquation.randomInstance()); |
| } |
| GeneticAlgorithm<SimpleEquation> ga = new GeneticAlgorithm<>( |
| initPopulation,0.1,0.7, GeneticAlgorithm.SelectType.ROULETTE); |
| SimpleEquation result = ga.run(100, 13.0); |
| System.out.println(generations+threshold); |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)