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

时间:2019-11-27 12:00:22

标签: repast-simphony

以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] 

我实际上想用engergy == 5来查询人类并按其ID对它们进行排序,例如:

[human_1, human_2, human_3, human_4, human_5]

这样,当我执行一些进一步的操作时,我总是可以获得一致的结果。

1 个答案:

答案 0 :(得分:2)

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

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]