Repast - 如何从查询中对代理集进行排序?

Repast - how to sort the agent set from query?

以Jzombie模型为例,如果我想查询所有能量等于5的人并将他们放入列表中,我将有以下代码:

List<Human> human_list = ArrayList<Human>();
Query<Object> query = new PropertyEquals<Object>(context, "energy", 5);
for (Object o : query.query()) {
    Human h = (Human)o;
    human_list.add(h);
}

但是,human_list 中人类的顺序是随机的,并且在不同的模拟运行之间有所不同。这会导致结果不一致的问题,如下所示:

run-1:
[human_2, human_4, human_3, human_5, human_1] 

run-2:
[human_1, human_3, human_4, human_2, human_1] 

run-3:
[human_5, human_1, human_3, human_5, human_2] 

我实际上想查询 energy == 5 的人并按他们的 id 对他们进行排序,例如:

[human_1, human_2, human_3, human_4, human_5]

这样当我执行一些进一步的操作时,我总能得到一致的结果。

无法保证来自查询的对象顺序,但是假设模型在其他方面是完全确定的,对象将始终相同。因此,您需要使用 Collections.sort() 对查询结果列表进行排序。对数组进行排序需要比较包含的对象以确定顺序。对于包含数字或字符串等简单类型的数组,只需在数组上调用 Collections.sort() 即可。由于您想比较代理,因此您需要让代理 class 实现类似的功能:

public class Human implements Comparable<Human>{

然后提供 compareTo() 方法的实现,如下所示,它根据字符串名称比较代理:

@Override public int compareTo(Human other) { return this.name.compareTo(other.name); }

对人类列表进行排序只需通过:

Collections.sort(human_list);

如果您指定 Human-1、Human-2 等人工代理名称,您可能会看到如下所示的输出:

[Human-18, Human-3, Human-7, Human-86, Human-92]

而且您每次都会看到相同的顺序。因为在这个例子中我们比较的是字符串,所以顺序可能不是我们期望的那样。字符串比较查看破折号后的第一个数字,因此 "Human-18" 排在 "Human-3" 之前,因为此字符位置为“1”<“3”。为了以更合乎逻辑的方式排序,我们可以将人类代理与整数 ID 进行比较。新的 compareTo 看起来像:

@Override public int compareTo(Human other) { return this.id - other.id; }

这将按如下方式打印人为顺序:

[Human-3, Human-7, Human-18, Human-86, Human-92]