java - 遗传算法 - 我需要什么数据结构?
问题描述
我希望在这里允许这样一个开放式的问题。我正在研究一个简单的 GA,它将演变一个字符串输出以匹配给定的目标字符串。因此,每一代都将创建一个由 N 个字符串组成的种群,每个字符串都将根据其与目标字符串的汉明距离分配一个适应度。然后我需要某种方式来存储和排序这些信息。我在处理中工作,但 Java 中的解决方案几乎总是可以通过导入在这种语言中使用。
由于我所追求的是模糊的键值结构,我的直觉是我想要某种字典,但我对这些工作的经验很少。还有一些复杂性使我们偏离了我对字典如何工作的理解。我想做以下事情:
存储每个字符串及其相关的适应度。这两者的重复必须是可能的。
按值对结构进行排序,即按适合度的降序列出总体。
剔除最底层的 50% 人口。可能最简单的方法是直接用适合人群的后代替换不适合人群。
访问时间/计算效率不是特别值得关注的。
昨晚我尝试使用 HashMap 解决此问题,但我一直遇到诸如在此结构下不允许重复键之类的问题,并且我找不到一种简单的方法来迭代 HashMap 并仅更改底部 X%按值输入。
总而言之,我需要一个结构,其中每个条目由一个 String 和一个 integer 组成,可以存储每个条目的重复项,该结构可以按整数值降序排序,因此顶部或底部 X% 的条目可以是在不影响其余部分的情况下进行操作。
非常感谢您的时间,任何帮助将不胜感激。
解决方案
有很多方法可以解决这个问题。就个人而言,我会尝试最简单的解决方案。我不知道您项目的整个背景及其愿景,但是,根据您向我们提供的信息,我发布了我会选择的解决方案。
注意:以下课程可能不完整。您可能必须添加更多方法才能更轻松地使用它们。这只是一个解决方案的想法,以代码形式提出,可能对您有用。
该类Pair
对一对字符串及其适应值进行建模。该类Population
对特定一代的人口进行建模。它将其成员保存在列表中并提供操作列表的方法。它还允许重复对。您可以选择X
种群的顶部或底部成员并对其进行操作。
public class Pair implements Comparable<Pair>{
private final String value;
private final int fitness;
public Pair(String value, int fitness) {
this.value = value;
this.fitness = fitness;
}
public String getValue() {
return value;
}
public int getFitness() {
return fitness;
}
@Override
public int compareTo(Pair pair) {
return -Integer.compare(this.fitness, pair.fitness);
}
@Override
public String toString() {
return "Pair{" + "value='" + value + '\'' + ", fitness=" + fitness + '}';
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class Population {
private final List<Pair> members = new ArrayList<>();
public void addMember(Pair pair) {
members.add(pair);
}
public List<Pair> getTop(int x) {
return members.stream().sorted().limit(x).collect(Collectors.toList());
}
public List<Pair> getBottom(int x) {
return members.stream().sorted(Comparator.reverseOrder()).limit(x).collect(Collectors.toList());
}
}
这是一个非全面的测试类:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class PopulationTest {
Population population = new Population();
@BeforeEach
void populate() {
population.addMember(new Pair("test", 5));
population.addMember(new Pair("abc", 13));
population.addMember(new Pair("xyz", 8));
population.addMember(new Pair("abc", 20));
}
@Test
void testSortDescending() {
List<Pair> members = population.getTop(4);
for (int i = 0; i < members.size() - 1; i++) {
assertTrue(members.get(i).getFitness() >= members.get(i + 1).getFitness());
}
}
@Test
void testGetTop() {
List<Pair> top = population.getTop(2);
assertEquals(20, top.get(0).getFitness());
assertEquals(13, top.get(1).getFitness());
}
@Test
void testGetBottom() {
List<Pair> bottom = population.getBottom(2);
assertEquals(5, bottom.get(0).getFitness());
assertEquals(8, bottom.get(1).getFitness());
}
}
推荐阅读
- java - 如何在 java 中测量密码的 mb/s 速度?
- unity3d - Unity WebGL POST 请求在构建游戏后不起作用
- php - 使用 PDF2Text (PHP) 从 PDF 中提取文本
- sql - 初始化字符串的格式不符合从索引 132 开始的规范有问题
- d3.js - d3 v5 树缩放、拖动和重置
- c++ - 宏定义中预处理器标记周围的两个双引号
- ios - 创建相机覆盖以快速读取 OCR 代码
- java - 如何将 DeviceGray 颜色转换为 rgb?
- javascript - 模态页面在物理设备上显示页面阴影,在模拟器上没有
- docker - 我可以从 Windows 2016 上托管的 docker 在 dotnet core 3.0 应用程序上运行 dotnetcore 吗?