【发布时间】:2015-10-27 06:26:26
【问题描述】:
我正在用 Java 开发一个基于代理的模型。我使用了一个分析器来减少任何低效率,以至于唯一阻碍它的是 Java 的 Collections.shuffle()。
我的模型中的代理(它们是动物)需要以随机顺序进行处理,以便没有一个代理始终在其他代理之前处理。
我正在寻找:比 Java 的 Collections.shuffle() 更更快的随机播放方法,或者以随机顺序处理 ArrayList 中元素的替代方法这明显更快。如果您知道比 ArrayList 更快的数据结构,请务必回答。我考虑过 LinkedList 和 ArrayDeque,但它们并没有太大区别。
目前,我正在尝试洗牌的列表中有超过 1,000,000 个元素。随着时间的推移,这个数量会增加,并且洗牌变得越来越低效。
是否有更快的随机处理元素的替代数据结构或方法?
我只需要能够存储元素并以随机顺序处理它们。我不使用包含或任何比存储和迭代更复杂的东西。
这里有一些示例代码可以更好地解释我想要实现的目标:
更新:对于 ConcurrentModificationException,我很抱歉,我没有意识到我已经这样做了,我也不想让任何人感到困惑。在下面的代码中修复它。
ArrayList<Agent> list = new ArrayList<>();
void process()
{
list.add(new Agent("Zebra"));
Random r = new Random();
for (int i = 0; i < 100000; i++)
{
ArrayList<Agent> newlist = new ArrayList<>();
Collections.shuffle(list);//Something that will allow the order to be random (random quality does not matter to me), yet faster than a shuffle
for (String str : list)
{
newlist.add(str);
if(r.nextDouble() > 0.99)//1% chance of adding another agent to the list
{
newlist.add(new Agent("Lion"));
}
}
list = newlist;
}
}
另一个更新 我考虑过做 list.remove(rando.nextInt(list.size()) 但由于 ArrayLists 的 remove 是 O(n) 这样做会更糟糕,而不是 shuffle 这么大的列表大小。
【问题讨论】:
-
如果你尝试一下,你会得到一个
ConcurrentModificationException。 -
如果你想要统一的改组,我不希望任何更快的改组方法在物理上是可能的。
-
Fisher-Yates shuffle 对
n大小的数组执行n交换操作。我非常怀疑你能在不到那个时间里做一个统一的洗牌。 -
我不明白为什么每次迭代都需要对整个
List进行洗牌,因为无论如何 90% 的Strings 都会被忽略。难道你不能每次只选择一些随机索引,并且在整个方法结束时只洗牌一次吗? -
一些 cmets/answers似乎 被您发布的代码误导了 - 我假设它是 pseudocode,只是为了说明主意。如果您提供了有关真实应用案例的更多信息(或代码),可能会提供更好的建议。
标签: java performance random collections shuffle