我正在开发一个模拟器,在模拟器中,Person对象(存储在ArrayList中)“复制”并生产婴儿,他们继承“基因”,表示为4个字母的字符串。在程序开始时,第一批人的基因库是随机生成的。
在计时器的每一个滴答中,我想计算出在所有的人对象中最常见的“基因”是什么。
这四封信是:
在这种情况下,有256种可能的组合,而且必须有比256条if-else语句更有效的检查。
Person类(减去get/set方法)
public class Person {
static Random rand = new Random();
private Person mother;
private Person father;
private String genes;
private char sex;
private int age, numKids;
public Person() {
mother = null;
father = null;
genes = createGenes();
if (rand.nextDouble() <= 0.5)
sex = 'm';
else
sex = 'f';
age = 18;
numKids = 0;
}
public Person(Person m, Person f) {
mother = m;
father = f;
genes = inheritGenes(m, f);
if (rand.nextDouble() <= 0.5)
sex = 'm';
else
sex = 'f';
age = 0;
}
//create genes for original Persons
private String createGenes() {
String genetics = "";
double first = rand.nextDouble();
double second = rand.nextDouble();
double third = rand.nextDouble();
double fourth = rand.nextDouble();
if (first <= 0.25)
genetics += "G";
else if (first <= 0.68)
genetics += "Z";
else if (first <= 0.9)
genetics += "N";
else
genetics += "F";
if (second <= 0.65)
genetics += "A";
else if (second <= 0.79)
genetics += "T";
else if (second <= 0.85)
genetics += "C";
else
genetics += "G";
if (third <= 0.64)
genetics += "B";
else if (third <= 0.95)
genetics += "F";
else if (third <= 0.98)
genetics += "Q";
else
genetics += "N";
if (fourth <= 0.37)
genetics += "A";
else if (fourth <= 0.58)
genetics += "C";
else if (fourth <= 0.63)
genetics += "T";
else
genetics += "E";
return genetics;
}
//inherit genes from parents for new Persons
public String inheritGenes(Person m, Person f) {
String genetics = "";
double first = rand.nextDouble();
double second = rand.nextDouble();
double third = rand.nextDouble();
double fourth = rand.nextDouble();
if (first < 0.5) {
genetics += m.getGenes().charAt(0);
} else
genetics += f.getGenes().charAt(0);
if (second < 0.5) {
genetics += m.getGenes().charAt(1);
} else
genetics += f.getGenes().charAt(1);
if (third < 0.5) {
genetics += m.getGenes().charAt(2);
} else
genetics += f.getGenes().charAt(2);
if (fourth < 0.5) {
genetics += m.getGenes().charAt(3);
} else
genetics += f.getGenes().charAt(3);
return genetics;
}
}发布于 2019-08-30 22:17:48
从List<Person>中找到最常见基因的示例代码。我刚为genes String添加了一个吸气器
String getGenes() {
return genes;
}守则如下:
List<Person> people = new ArrayList<>();
for (int i = 0; i < 100; i++) {
people.add(new Person()); // 100 random genes
}
String mostCommonGene = people.stream()
.map(Person::getGenes)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparingLong(Map.Entry::getValue))
.get()
.getKey();
System.out.println("Most common gene: " + mostCommonGene);我们使用Java 8流:
stream() of people列表。map() ( Person )转换为String --它们的genes。collect()的基因流与groupingBy()喂食Function.identity()和Collectors.counting()。此步骤生成一个Map<String, Long>,它表示genes及其频率的映射。有效地统计people列表中基因的出现情况。entrySet(),然后再调用stream() --现在我们有了一系列的地图条目(你可以把它们看作对),基因及其在一个物体中的频率。方便)。max()查找值最高的条目(解释为频率)。Comparator.comparingLong()告诉max()算法如何比较这些对,但它们不是long_s --这就是为什么我们必须告诉它如何将_entry转换为long --我们得到了该条目的值。get(),因为max()返回一个Optional<T>。我们只想要T (条目)。getKey()。正如前面提到的,关键是基因,而值是它的频率。如果您不熟悉这个答案中描述的大多数概念,我强烈建议您学习Java8Streams。一旦你习惯了,你就停不下来了。
发布于 2019-08-30 22:32:13
根据使用场景的不同,使用额外的Map<String,Long>作为每个基因的计数器(对于每个新的人基因增加计数器)可能更有效。
这种方法将使用更多的内存(包含256个元素的Map<String,Long>),而新的人员构造将稍微慢一些(地图的更新),但是如果有许多存活的Person对象,那么获取每个滴答上最常见的基因可能要快得多,因为这些对象已经在Map中进行了分组和计数,因此应该比较最多256个条目。
https://stackoverflow.com/questions/57733511
复制相似问题