Scala:以随机顺序在集合上迭代,而不创建副本

Scala:以随机顺序在集合上迭代,而不创建副本,scala,random,collections,iteration,traversal,Scala,Random,Collections,Iteration,Traversal,Scala中是否有一种方法可以为不可变集合(例如列表或向量)获取流/视图/迭代器,该集合将以随机顺序遍历集合?据我所知,Random.shuffle(coll)创建了一个副本,这不是一种节省内存的方法。Random.shuffle(coll.view)(或coll.stream或coll.iterator)是更好的方法吗?这是否会造成明显的CPU开销?或者有更合适的方法吗?洗牌算法需要在集合中随机移动,并且需要以某种方式记住过去的选择。对于随机访问,不可变集合的速度不是很快(O(n)而不是O(1

Scala中是否有一种方法可以为不可变集合(例如列表或向量)获取流/视图/迭代器,该集合将以随机顺序遍历集合?据我所知,Random.shuffle(coll)创建了一个副本,这不是一种节省内存的方法。Random.shuffle(coll.view)(或coll.stream或coll.iterator)是更好的方法吗?这是否会造成明显的CPU开销?或者有更合适的方法吗?

洗牌算法需要在集合中随机移动,并且需要以某种方式记住过去的选择。对于随机访问,不可变集合的速度不是很快(
O(n)
而不是
O(1)
对于
List
,可以说
O(1)
对于
Vector
,但常数因子很大)


相比之下,复制集合几乎总是明智之举。

洗牌算法需要在集合中随机移动,并且需要以某种方式记住过去的选择。对于随机访问,不可变集合的速度不是很快(
O(n)
而不是
O(1)
对于
List
,可以说
O(1)
对于
Vector
,但常数因子很大)


复制集合,比较而言,几乎总是明智之举。

如果考虑到集合复制,考虑将索引<代码>数组< /COD>改组为<代码>向量< /代码>,例如,

val myVector: Vector[MyObject] = ...

val shuffledIdx = util.Random.shuffle(0 until myVector.size)
这复制了一系列
Int
,可能比专用对象轻。然后

shuffledIdx.map { idx => task (myVector(idx)) }

以随机顺序在MyVector 中对每个条目进行迭代/映射。

< P>如果考虑到集合复制,考虑将索引<代码> >数组>代码>改为<代码>向量< /代码>,例如,

val myVector: Vector[MyObject] = ...

val shuffledIdx = util.Random.shuffle(0 until myVector.size)
这复制了一系列
Int
,可能比专用对象轻。然后

shuffledIdx.map { idx => task (myVector(idx)) }

以随机顺序迭代/映射
myVector
中的每个项。

在(我的)情况下,当内存比CPU复制更有价值时,不可接受。因此,我需要CPU密集度较低的方法。Random.shuffle(myVector.iterator)是否复制了整个向量?@Uniqus请参阅(新建ArrayBuffer)@Uniqus中的第108行-如果您有足够的条目来处理另一组指针的问题,我很确定您不会希望从运行时的
O(n)
遍历随机列表到
O(n^2)
。当
n
很大时,
O(n^2)
非常糟糕(秒->周)。是的,存储过去的选择仍然会消耗内存(不是一次,而是随着时间的推移),因此它只会推迟潜在的问题。因此,唯一可以接受的方法确实是复制。好了,谢谢大家,问题已经得到解答。C++中有问题,但我决定坚持复制。在(我的)情况下,内存比CPU拷贝更宝贵,是不可接受的。所以我需要更少的CPU密集型方法。Random.shuffle(myVector.iterator)是否复制了整个向量?@Uniqus请参阅(新建ArrayBuffer)@Uniqus中的第108行-如果您有足够的条目来处理另一组指针的问题,我很确定您不会希望从运行时的
O(n)
遍历随机列表到
O(n^2)
。当
n
很大时,
O(n^2)
非常糟糕(秒->周)。是的,存储过去的选择仍然会消耗内存(不是一次,而是随着时间的推移),因此它只会推迟潜在的问题。因此,唯一可以接受的方法确实是复制。好了,谢谢大家,问题是回答了。C++中有,但是我决定坚持复制。寻找(伪)随机数生成器,其中第一个MyVCCTORE。大小值是唯一的,不必洗牌初始范围,至今没有成果搜索…寻找(伪)随机数生成器,其中第一个myVector.size值是唯一的,无需洗牌初始范围,到目前为止搜索没有结果。。。