Java版旅行商遗传算法

目录

1.主函数

2.geneticalgorithm 遗

传算法

3.individual个体

4.population种群

5.City城市

6.Route

7.多个遗传算法Java版源代码下载


1.主函数

package chapter1_TSP;

public class TSP {
    public static int maxGenerations = 500;
    public static double tolerance = 1e-5;
    public static void main(String[] args)
    {
        long startTimes = System.currentTimeMillis();
        // maxToleranceTimes
        double pre_best_distance = 0;
        int times = 0 ;   //差值小于tolerance 的次数
        int tolerance_maxTimes = 100;

        // Create cities
        int numCities = 10000;
        City[] cities = new City[numCities];
        // Loop to create random cities
        for (int cityIndex = 0; cityIndex < numCities; cityIndex++) {
            // Generate x,y position
            int xPos = (int) (100 * Math.random());
            int yPos = (int) (100 * Math.random());
            // Add city
            cities[cityIndex] = new City(xPos, yPos);
        }  //当然这个1w城市有点夸张了

//		// loop to create certain cities
//		 int[][] positions={ {1,2},{3,5},{9,6},{6,3},{53,15},{56,21},{26,18},{28,29},{9,24},{32,18},
//		 				{43,4},{23,7},{17,20},{30,6},{10,12},{38,20},{99,100},{0,0},{19,27},{56,32}
//		 				,{0,100},{100,0},{50,50},{12,12},{24,24}};
//		 City[] cities=new City[positions.length];
//		 for(int cityIndex=0;cityIndex<positions.length;cityIndex++)
//		 	cities[cityIndex]=new City(positions[cityIndex][0],positions[cityIndex][1]);
//		 int numCities = cities.length;


        // Initial GA
        GeneticAlgorithm ga = new GeneticAlgorithm(100, 0.9, 0.01, 2, 4);

        // Initialize population
        Population population = ga.initPopulation(cities.length);

        // Evaluate population
        ga.evalPopulation(population, cities);

        Route startRoute = new Route(population.getFittest(0), cities);
        System.out.println("Start Distance: " + startRoute.getDistance());

        // Keep track of current generation
        int generation = 1;
        // ************************** Start evolution loop ******************************
        while (ga.isTerminationConditionMet(generation, maxGenerations) == false) {
            // Print fittest individual from population
            Route route = new Route(population.getFittest(0), cities);
            System.out.println("G"+generation+" Best distance: " + route.getDistance());

            // Apply crossover
            population = ga.crossoverPopulation(population);

            // Apply mutation
            population = ga.mutatePopulation(population);

            // Evaluate population
            ga.evalPopulation(population, cities);

            // Increment the current generation
            generation++;

//			// sequence of cities--toString
//			System.out.println("bestroute: ("+population.getFittest(0).toString()+")");

            // tolerance times   isTerminated 2
            if(pre_best_distance-route.getDistance() <tolerance)
                times++;
            else
                times=0 ;
            if(times>tolerance_maxTimes)
                break;
            pre_best_distance = route.getDistance();   //update pre_distance
        }
        // ************************** end of the loop ******************************

        System.out.println("Stopped after " + (generation-1) + " generations.");
        Route route = new Route(population.getFittest(0), cities);
        System.out.println("Best distance: " + route.getDistance());
        System.out.println("route: ("+population.getFittest(0).toString()+")");
        System.out.println("用时"+(double)(System.currentTimeMillis()-startTimes)/1000+"s");
    }
}

2.geneticalgorithm 遗

传算法

package chapter1_TSP;

import java.util.Arrays;
import java.util.stream.IntStream;

// GA的方法用以 "操作" "种群"
public class GeneticAlgorithm
{
    //    public cross
    // @param
    private int populationSize;
    private double crossrate;
    private double mutationrate;
    private int elitismCount;
    protected int tournamentSize;
    public GeneticAlgorithm(int populationSize,double crossrate,double mutationrate,
                            int elitismCount,int tournamentSize)
    {
        this.populationSize=populationSize;
        this.crossrate=crossrate;
        this.mutationrate=mutationrate;
        this.elitismCount=elitismCount;
        this.tournamentSize=tournamentSize;
    }
    public Population initPopulation(int chromosomeLength)
    {
        return new Population(populationSize,chromosomeLength);
    }
    public double calcFitness(Individual individual,City[] cities)//个体适应度
    {
        Route route = new Route(individual,cities);
        double fitness = 1/route.getDistance();
        individual.setFitness(fitness);
        return fitness;
    }
    public final void evalPopulation(Population population, City[] cities)
    {
        double populationFitness=0;

        IntStream.range(0,populationSize).parallel().forEach(i-> this.calcFitness(population.getIndividual(i),cities) );

        for(Individual individual:population.getIndividuals())
        {
//            Thread.sleep();
            populationFitness += individual.getFitness();
        }

//        for(Individual individual:population.getIndividuals())
//            populationFitness += this.calcFitness(individual,cities);
        double avgFitness = populationFitness/population.size();
        population.setPopulationFitness(avgFitness);
    }
    public Individual selectParent(Population population)// 锦标赛选择
    {
        Population tournament = new Population(this.tournamentSize);
        // 打乱 population
        population.shuffle();
        for(int i=0;i<tournamentSize;i++)
        {
            Individual tournamentIndividual = population.getIndividual(i);
            tournament.setIndividual(i,tournamentIndividual);
        }
        // 返回随机选中的 个体中,最优秀的
        return tournament.getFittest(0);
    }
    public Population crossoverPopulation(Population population)
    {
        Population newPopulation  = new Population(population.size());
        // 遍历个体,两两交叉
        for(int index=0;index<population.size();index++)
        {
            Individual parent1 = population.getFittest(index);
            // 创建空白子代
//            Individual offspring = new Individual(parent1.getchromosomeLength());
            int[] offspringChromosome = new int[parent1.getChromosomeLength()];
            Arrays.fill(offspringChromosome, -1);
            Individual offspring = new Individual(offspringChromosome);

            if (crossrate > Math.random() && index >= elitismCount)  //精英群体保存,不交叉
            {
                Individual parent2 = selectParent(population);
                // 顺序交叉
                int substirng1 = (int) (Math.random() * (parent1.getChromosomeLength()));
                int substring2 = (int) (Math.random() * (parent1.getChromosomeLength()));
                int startPostion = Math.min(substirng1, substring2);
                int finalPostion = Math.max(substirng1, substring2);

                for (int i = startPostion; startPostion < finalPostion; startPostion++)
                    offspring.setGene(i, parent1.getGene(i));
                for (int i = 0; i < parent2.getChromosomeLength(); i++)
                {
                    int parent2Gene = i + finalPostion;
                    if (parent2Gene >= parent2.getChromosomeLength())
                        parent2Gene -= parent2.getChromosomeLength();
                    if (offspring.containsGene(parent2.getGene(parent2Gene)) == false)//若无则添加
                    {
                        for(int off_i=0;off_i<offspring.getChromosomeLength();off_i++)
                        {
                            if (offspring.getGene(off_i) == -1)
                            {
                                offspring.setGene(off_i, parent2.getGene(parent2Gene));
                                break; //交叉基因完就退出
                            }
                        }
                    }
                }
                newPopulation.setIndividual(index,offspring);
            }
            else
            {
                newPopulation.setIndividual(index, parent1);
            }
        }
        return newPopulation;
    }
    public Population mutatePopulation(Population population)
    {
        Population newPopulation = new Population(this.populationSize);
        // 每个个体 自身变异
        for(int index=0;index<population.size();index++)
        {
            Individual individual = population.getFittest(index);
            if(index>=elitismCount)
            {
                // 遍历 个体的基因
                for(int genIndex=0;genIndex<individual.getChromosomeLength();genIndex++)
                {
                    if (mutationrate > Math.random())
                    {
                        int mutatePos = (int) (Math.random()* individual.getChromosomeLength());
                        int gene1 = individual.getGene(genIndex);
                        int gene2= individual.getGene(mutatePos);
                        individual.setGene(genIndex,gene2);
                        individual.setGene(mutatePos,gene1);
                    }
                }
            }
            newPopulation.setIndividual(index,individual);
        }
        return newPopulation;
    }
    public boolean isTerminationConditionMet(int generation, int MaxGenerarion)
    {
        return generation>MaxGenerarion;
    }
}

3.individual个体

package chapter1_TSP;

import java.util.Random;

public class Individual
{
    private int[] chromosome;
    private double fitness=-1;
    public Individual(int chromosomeLength)
    {
      this.chromosome=new int[chromosomeLength];
      for(int gene=0;gene<chromosomeLength;gene++)
          this.chromosome[gene]=gene;
      shuffle();   //打乱顺序,构造随机排序的城市数组
    }
    public Individual(int[] chromosome)
    {
        this.chromosome=chromosome;
    }
    public int[] getChromosome()
    {
        return this.chromosome;
    }
    public int getChromosomeLength()
    {
        return this.chromosome.length;
    }
    public void setFitness(double fitness)
    {
        this.fitness=fitness;
    }
    public double getFitness()
    {
        return this.fitness;
    }
//    public double calcFitness(City[] cities)
//    {
//        double distance=0;
//        for(int gene=0;gene<this.chromosome.length;gene++)
//            distance+=cities[chromosome[gene]].distanceFrom(
//                    cities[chromosome[(gene+1)% chromosome.length]]);
//        this.fitness = 1/distance;
//        return this.fitness;
//    }
    public void shuffle()
    {
        Random rnd=new Random();
        for(int gene=0;gene<chromosome.length;gene++)
        {
            int randint = rnd.nextInt(gene+1);
            int temp= chromosome[gene];
            this.chromosome[gene] = this.chromosome[randint];
            this.chromosome[randint] = temp;
        }
    }
    public void setGene(int Index,int gene)
    {
        this.chromosome[Index]=gene;
    }
    public int getGene(int Index)
    {
        return this.chromosome[Index];
    }
    public String toString()
    {
        String str="";
        if(this.chromosome.length>0)
            str+= this.chromosome[0];
        for(int gene=1;gene< chromosome.length;gene++)
            str+=","+chromosome[gene];
        return str;
    }
    public boolean containsGene(int gene)
    {
        for(int Gene:this.chromosome)
            if (Gene==gene)
                return true;
        return false;
    }
}

4.population种群

package chapter1_TSP;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

public class Population
{
    private Individual[] population;
    private double populationFitness=-1;
    public Population(int populationSize)
    {
        this.population=new Individual[populationSize];
    }
    public Population(int populationSize,int chromosomeLength)
    {
        this(populationSize);
        for(int individualCount=0;individualCount<populationSize;individualCount++)
            this.population[individualCount]=new Individual(chromosomeLength);
    }

    public Individual[] getIndividuals()
    {
        return this.population;
    }
    public void setPopulationFitness(double populationFitness)
    {
        this.populationFitness=populationFitness;
    }
    public double getPopulationFitness()
    {
        return this.populationFitness;
    }
    public int size()
    {
        return this.population.length;
    }
    public Individual setIndividual(int offset, Individual individual)
    {
        return this.population[offset] = individual;
    }
    public Individual getIndividual(int offset)
    {
        return this.population[offset];
    }
    public Individual getFittest(int offset)
    {
        Arrays.sort(population, new Comparator<Individual>() {
            @Override
            public int compare(Individual o1, Individual o2)
            {
                return Double.compare(o2.getFitness(), o1.getFitness());
            }
        });
        return this.population[offset];
    }
    public void shuffle()
    {
        Random rnd = new Random();
        for(int individ=population.length-1 ; individ>0 ; individ--)
        {
            int randi = rnd.nextInt(individ+1);
            Individual temp=this.population[individ];
            this.population[individ] = this.population[randi];
            this.population[randi] = temp;
        }
    }


}

5.City城市

package chapter1_TSP;

public class City
{
    private double x;
    private double y;
    public City(double x,double y)
    {
        this.x=x;
        this.y=y;
    }
    public City(City city)
    {
        this(city.x, city.y);
    }

    public double distanceFrom(City city)
    {
        double Distance=0;
        double delta_x=Math.pow(this.getX()-city.getX(),2);
        double delta_y=Math.pow(this.getY()-city.getY(),2);

        Distance = Math.sqrt(Math.abs(delta_x+delta_y));
        return Distance;
    }
    public double getX()
    {
        return this.x;
    }
    public double getY()
    {
        return this.y;
    }
}

6.Route

package chapter1_TSP;

public class Route {
    public City[] route;
    public double distance;

    public Route(Individual individual, City[] cities) {
        this.distance = 0;
        int[] chromosome = individual.getChromosome();
        this.route = new City[cities.length];
        for (int gene = 0; gene < chromosome.length; gene++)
            this.route[gene] = cities[chromosome[gene]];
    }

    public double getDistance() {
        if (this.distance > 0)
            return this.distance;
        double distance = 0;
        for (int CityIndex = 0; CityIndex < route.length; CityIndex++)
            distance += route[CityIndex].distanceFrom(route[(CityIndex + 1) % route.length]);
        this.distance = distance;
        return this.distance;
    }
}

当然这不是题主原创的,推荐一本书,叫Java版遗传算法,这本书讲的挺详细,几个外国人写的,这个代码是学完后半写半抄的。书上有源代码,建议买,二手就够了,便宜实惠。

7.多个遗传算法Java版源代码下载

Java版遗传算法源代码下载

提取码:1111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值