Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在遗传算法中有效地寻找最不合适的成员_Java_Sorting_Genetic Algorithm - Fatal编程技术网

Java 在遗传算法中有效地寻找最不合适的成员

Java 在遗传算法中有效地寻找最不合适的成员,java,sorting,genetic-algorithm,Java,Sorting,Genetic Algorithm,我用java实现了一个遗传算法来解决我的一类人的旅行推销员问题。它似乎工作得很好,但速度很慢。我将一个我称之为“Tour”实例的个体表示为一个整数数组列表,该数组列表表示旅行的顺序。(即[1,5,4,3,2,0]表示按顺序前往城市1,5,4,3,2,0,1。每一代人执行以下步骤 按递增顺序对总体排序(大多数适合的成员得分最低) 根据轮盘赌轮盘的选择,挑选20%的种群进行繁殖,这样更适合的成员将有更多的繁殖机会 用这20%让10%的孩子使用贪婪的交叉 随机贪婪突变5%的儿童 移除人口中最低的10%

我用java实现了一个遗传算法来解决我的一类人的旅行推销员问题。它似乎工作得很好,但速度很慢。我将一个我称之为“Tour”实例的个体表示为一个整数数组列表,该数组列表表示旅行的顺序。(即[1,5,4,3,2,0]表示按顺序前往城市1,5,4,3,2,0,1。每一代人执行以下步骤

  • 按递增顺序对总体排序(大多数适合的成员得分最低)
  • 根据轮盘赌轮盘的选择,挑选20%的种群进行繁殖,这样更适合的成员将有更多的繁殖机会
  • 用这20%让10%的孩子使用贪婪的交叉
  • 随机贪婪突变5%的儿童
  • 移除人口中最低的10%并替换为子代(数组中的前90%仍将在字尾后排序)
  • 重复50000次
  • 我怀疑排序部分是瓶颈,因为我读到Collections.sort方法使用MergeSort复制整个数组。在我的情况下,这可能是非常无效的,因为它将复制一个或多个数组(它们本身就是数组)当我只想根据适合度进行排序时。除了排序之外,还有没有更好的方法获得Java中数组的最低10%呢?或者是就地排序?谢谢你的建议

    package assignment3;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Random;
    
    public class Tsp {
    
    private static int MAX_GENERATIONS = 50000;
    private static int MUTATION_CHANCE = 5;
    
    private Cities cityList;
    private Population population = new Population();
    
    public Tsp(Cities cityList) {
    this.cityList = cityList;
    this.population.createRandomPopulation(cityList);
    }
    
    public void clearTours() {
    this.population.createRandomPopulation(cityList);
    }
    
    public Tour getBestTour() {
    Collections.sort(this.population);
    return this.population.get(0);
    }
    
    public void start() {
    for (int generation = 0; generation < MAX_GENERATIONS; generation++) {
        Collections.sort(this.population);
        evolve();
    
    }
    }
    
    private void evolve() {
    // Sum all the fitnesses
    // Update the breeding chance for each tour
    // create a breeding array of ints that is 20% size of the population to
    // be used to determine how to make the 10% children
    // if array is odd add an index
    // While the array size is too small
    // loop through the population
    // if array correct size exit loop
    // compare random number with tour breeding chance
    // make sure tour isn't in breeding array
    // if pass random and not in breeding array
    // add to breeding array
    // end while
    
    // loop through breeding array
    // breed one parent with next
    // store child in temp array
    
    // For each child if randomly selected perform mutation
    
    // remove 10% of worst children from population
    // Add new children to population
    
    
    
    ArrayList<Integer> breedingArray = getBreedingArray();
    Population children = new Population();
    for (int i = 0; i < breedingArray.size(); i += 2) {
        Tour parent1 = population.get(i);
        Tour parent2 = population.get(i + 1);
        children.add(parent1.performCrossover(cityList, parent2));
    }
    
    for (Tour t : children) {
        Random r = new Random();
        if (MUTATION_CHANCE >= r.nextInt(100)) {
        t.performGreedyMutation(cityList);
        }
    }
    
    int start = (population.size() - 1) - children.size();
    int endIndex = population.size() - 1;
    
    population.subList(start, endIndex).clear();
    population.addAll(children);
    }
    
    private ArrayList<Integer> getBreedingArray( ) {
    updateBreedingChance();
    
    int breedingArraySize = (int) (this.population.size() * 0.2);
    if (breedingArraySize % 2 != 0) {
        breedingArraySize += 1;
    }
    
    Random r = new Random();
    ArrayList<Integer> breedingArray = new ArrayList<Integer>();
    while (breedingArray.size() != breedingArraySize) {
        for (int i = 0; i < this.population.size(); i++) {
        if (breedingArray.size() == breedingArraySize) {
            break;
        }
        Tour check = this.population.get(i);
        boolean passesRandomSelection = r.nextDouble() < check.breadingChance;
        boolean notAlreadySelected = !breedingArray.contains(i);
    
        if (passesRandomSelection && notAlreadySelected) {
            breedingArray.add(i);
        }
    
        }
    }
    return breedingArray;
    }
    
    private void updateBreedingChance() {
    double totalFitness = 0;
    for (Tour t : this.population) {
        if (t.fitness == 0) {
        throw new RuntimeException("Fitness cannot be zero");
        }
        totalFitness += t.fitness;
    }
    
    double totalInverseFitness = 0;
    for (Tour t : this.population) {
        totalInverseFitness += totalFitness / t.fitness;
    }
    
    for (Tour t : this.population) {
        t.breadingChance = (totalFitness / t.fitness) / totalInverseFitness;
    }
    
    }
    
    包分配3;
    导入java.util.ArrayList;
    导入java.util.Collections;
    导入java.util.Random;
    公共类Tsp{
    私有静态整数最大生成数=50000;
    私有静态int_机会=5;
    私人城市城市主义者;
    私人人口=新人口();
    公共Tsp(城市列表){
    this.cityList=城市列表;
    this.population.createRandomPopulation(cityList);
    }
    公共旅游{
    this.population.createRandomPopulation(cityList);
    }
    公共旅游getBestTour(){
    Collections.sort(this.population);
    返回此.population.get(0);
    }
    公开作废开始(){
    对于(整数代=0;代=r.nextInt(100)){
    t、 执行经理提名(城市名单);
    }
    }
    int start=(population.size()-1)-children.size();
    int endIndex=population.size()-1;
    subList(开始、结束索引).clear();
    人口:全部(儿童);
    }
    私有ArrayList getBreedingArray(){
    updateReedingChance();
    int breedingArraySize=(int)(this.population.size()*0.2);
    如果(breedingArraySize%2!=0){
    繁殖阵列大小+=1;
    }
    随机r=新随机();
    ArrayList breedingArray=新的ArrayList();
    while(breedingArray.size()!=breedingArraySize){
    for(int i=0;i

    }

    在步骤(5)中进行部分排序可能会更快。简单算法:将总体设为a,然后从该堆中弹出。1*n次。(这是部分排序;中有更好的算法,包括一个名为“.”的算法)

    如果您“怀疑”出了问题,那么您的第一个操作必须是找出问题是否存在。分析代码。然后您将知道慢位在哪里。您可以使用分析工具,或者通过调用System.nanoTime()来完成此操作在关键点处输入,并保留一些总数。在进行任何优化之前执行此操作

    现在,关于您正在排序的数组,一个有趣的事情是,它通常是“大部分排序的”。前90%是上一轮的幸存者,他们被排序。您可以通过使用一个来利用这一点,这对这些大部分排序的数组来说工作较少。有几种已知的自适应排序,但一种很好的通用排序这实际上将成为Java7中的标准排序——Wikipedia文章中关于它的脚注包括一个指向OpenJDK中将要使用的代码的链接,您可以简单地窃取它

    甚至比应用自适应排序更好的方法是先对新的孩子进行排序(使用自适应排序,因为你要先培育最适合的父母,所以经验也是如此)