遗传算法:创建两个HashMaps的后代

时间:2017-04-03 07:40:46

标签: java hashmap genetic-algorithm

在此问题被删除之前重复: 我看过类似的问题,他们都是从两个阵列创建后代。我需要做同样的事情(如果可能的话,使用HashMaps)。

这是我的重现功能。

    public Map<String, Integer> reproduce(Map<String, Integer> x, Map<String, Integer> y, int n){
    Random rand = new Random();
    int c = rand.nextInt(n);
    !!CREATE OFFSPRING from x and y and store it into child!!
    return(child);
}

例如,如果传递给函数的x和y值是:  x = {0 = 1} {1 = 0} {2 = 1} 并且y = {0 = 2} {1 = 1} {2 = 2}

我想使用这些地图重现以创建子地图,例如:     child = {0 = 1} {1 = 1} {2 = 2}

孩子从x获得第一个元组,从y获得第二和第三元组。

从x切换到y的点由随机数c确定。

如何在不将地图转换为数组的情况下执行此操作?

三江源, 迪伦

2 个答案:

答案 0 :(得分:0)

严格地说,java中的Map接口没有顺序访问的方法。 所以你不能采取第一个元素&#34;从地图 - 他们之间没有秩序。 一些实现确实有保证排序 - SortedMap(按键排序)和LinkedHashMap(按插入顺序排序)。

在这些情况下,您可以使用entryMap()方法。

所以(假设n是两个映射的大小)如果你想从第一个中获取x元素而从第二个中获取y元素,你可以创建两个迭代器并从它们中取出,如:

int c = rand.nextInt(n);
Iterator<Entry<String, Integer>> i1 = x.entrySet().iterator();
Iterator<Entry<String, Integer>> i2 = y.entrySet().iterator();
int i = 0;
Map<Integer, String> child = new HashMap<String, Integer>();
Entry<String, Integer> e1, e2;
while (i < n)
{ 
   if (i < c) {
     e1= i1.next();
     e2 = i2.next();
     child.add(e1.getKey(), e1.getValue());
   }
   else
   {
     e2 = i2.next();
     child.add(e2.getKey(), e2.getValue());
   }
   i++;
}

答案 1 :(得分:0)

我接受你的意思:你需要来自c的第一个x元组和来自y的其余元组。按照String.compareTo()定义的密钥的自然顺序。这比从xy随机获取每个元组要复杂一些。当然可以做到。

正如@Yossi Vainshtein已经在另一个答案中指出的那样,地图通常不会保持元组的顺序,所以向地图询问第一个c元组是没有意义的。所以我们需要明确地对键进行排序。在我们对它们进行排序之前,我们需要将它们放在不同的数据结构,列表或数组中。所以我把钥匙拿出来放入一个清单并对其进行排序。因此,虽然没有将地图本身转换为数组,但我确实只将密钥集转换为通过数组实现幕后的列表。

如果两个父地图具有相同的键,则这种方式只能按预期工作。所以你的方法应该做的第一件事是检查是否是这种情况。

要从地图中取出密钥,请使用x.keySet(),类似于y。要将它们放入列表中,请使用new ArrayList<>(x.keySet())。要对列表进行排序,请使用Collections.sort()。要创建空子,请使用Map<String, Integer> child = new HashMap<>();。要填充它,请迭代列表的第一个c元素,并从x填写相应的键和值;然后迭代剩余的键并从y填写键和值。然后你就完成了。快乐的编码。

如果您从c x c x n - c y开始n - 1,则不关心c - 1元组正在考虑x我们可以完全跳过列表和排序。

编辑:我从您的评论中了解到,密钥始终为0到c。在这种情况下,没有理由从地图中取出密钥并对它们进行排序。只需遍历数字0到n - 1。对于每个数字,将其转换为字符串,从y获取值并将字符串和值放入子项中。然后对数字friendsuser_id1执行相同操作。比我上面概述的要简单得多。