【发布时间】:2019-03-22 18:21:08
【问题描述】:
我正在创建一个遗传算法来解决一些特定问题。由于这个问题很难描述,我写了一个小例子来说明我在做什么。
我有一个应该随着时间而发展的元素列表。
每个元素都有一个适应度值,它决定了它有多好。这是代表元素的类:
class Element implements Comparable<Element>{
private int fitness;
Element( int _fitness){
this.fitness=_fitness;
}
public int getFitness() {
return fitness;
}
@Override
public int compareTo( Element o ) {
return this.fitness-o.getFitness();
}
@Override
public String toString() {
return this.fitness+"";
}
}
最佳元素是具有最大适应度值的元素。
示例:
list_Iteration_One | list_Iteration_Two| list_Iteration_Three
Element(5) | Element(9) | Element(14)
Element(4) |Element(5) | Element(9)
Element(3) |Element(5) | Element(9)
Element(2) |Element(4) | Element(5)
Element(1) |Element(3) | Element(5)
正如我们所见,程序应该将元素列表作为输入,并进化这些元素以创建一个新列表。
规则是取列表的一半,并合并每两个Elment创建一个新元素。
对于所选元素,它们应该具有最大适应度值。
对于上面的示例,我使用Element(5) + Element(4) 创建Element(9),使用Element(3) + Element(2) 创建Element(5),剩下的我使用Element(5), Element(4), Element(3)。
对于第 3 次迭代,我正在做同样的事情等等。
这是我为一次迭代所做的:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BestDataStructure {
public static void main( String[] args ) {
List<Element> list = Stream.of(new Element(5),
new Element(4),
new Element(3),
new Element(2),
new Element(1)).collect(Collectors.toCollection(ArrayList::new));
List<Element> theNewList = getTheNewList(list);
System.out.println(theNewList);
}
private static List<Element> getTheNewList( List<Element> list ) {
List<Element> theNewList = new ArrayList<>();
int numberOfTimes = list.size()/2;
Element bestElement=null;
Element secondBestElement=null;
for (int i =0; i<numberOfTimes; i++){
bestElement= Collections.max(list);
list.remove(bestElement);
secondBestElement= Collections.max(list);
list.remove(secondBestElement);
Element child = new Element(bestElement.getFitness()+secondBestElement.getFitness());
theNewList.add(child);
theNewList.add(bestElement);
theNewList.add(secondBestElement);
}
return theNewList;
}
}
class Element implements Comparable<Element>{
private int fitness;
Element( int _fitness){
this.fitness=_fitness;
}
public int getFitness() {
return fitness;
}
@Override
public int compareTo( Element o ) {
return this.fitness-o.getFitness();
}
@Override
public String toString() {
return this.fitness+"";
}
}
由于我应该处理大小的List(在 2000 到 50000 元素之间),我需要知道处理此类处理的最佳数据结构。
我每次都在ArryList 中寻找最大元素,这是一个非常糟糕的主意。
每次迭代后的结果列表应该与第一个列表具有相同的大小,不幸的是这不是我在getTheNewList 方法中得到的。
我也在寻找什么,我应该如何处理这个任务,我应该在第一时间寻找最好的元素,还是我应该迭代地选择主题......
【问题讨论】:
-
怎么在第 3 次迭代中,最后三个元素不是 9、5、5?如果我错了,请纠正我,但我的理解是您将最后一个列表中最大的三个元素保留在新列表中?
-
是的,你是对的,一般来说,如果我有一个包含十个元素的列表,我应该在新一代中有 5 个新元素。对于我的示例,我在列表中有 5 个,但在新列表中有两个新元素。剩下的我应该复制上一代最好的元素。
-
听起来你想要一个堆,这是由
PriorityQueue在java.util包中提供的。 -
@DavidConrad 我也想,我会测试这个实现。
标签: java data-structures collections java-stream genetic-algorithm