【发布时间】:2011-04-03 21:41:41
【问题描述】:
我已经在 java 中实现了一个遗传算法来解决我的一个班级的旅行商问题。它似乎工作得很好,但速度很慢。我代表一个人,我将其称为“Tour”的一个实例,它是一个代表旅行顺序的整数数组列表。 (即 [1,5,4,3,2,0] 表示按顺序前往城市 1,5,4,3,2,0,1。每一代都执行以下步骤...
- 按升序对总体进行排序(最合适的成员得分最低)
- 根据轮盘选择选择 20% 的种群进行繁殖,从而提高适应度较高的成员的繁殖机会
- 利用这 20% 来让 10% 的孩子使用贪婪交叉
- 随机贪婪变异 5% 的孩子
- 删除最低 10% 的人口并用子代替换(数组的前 90% 仍将在后面排序)
- 重复 50,000 次
我怀疑排序部分是瓶颈,因为我读过 Collections.sort 方法使用复制整个数组的 MergeSort。在我的情况下,这可能非常低效,因为当我想要的只是根据适应度进行排序时,它会复制一个数组或 Tours(它们本身就是数组)。除了排序之外,还有没有更好的方法来获得 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;
}
}
}
【问题讨论】:
-
老兄,这与遗传算法无关,这是关于java中的排序
标签: java sorting genetic-algorithm