Java 在遗传算法中有效地寻找最不合适的成员
我用java实现了一个遗传算法来解决我的一类人的旅行推销员问题。它似乎工作得很好,但速度很慢。我将一个我称之为“Tour”实例的个体表示为一个整数数组列表,该数组列表表示旅行的顺序。(即[1,5,4,3,2,0]表示按顺序前往城市1,5,4,3,2,0,1。每一代人执行以下步骤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%
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中将要使用的代码的链接,您可以简单地窃取它 甚至比应用自适应排序更好的方法是先对新的孩子进行排序(使用自适应排序,因为你要先培育最适合的父母,所以经验也是如此)