在C#中随机化通用列表顺序的最佳方法是什么?我在一个列表中有一组有限的75个数字,我想为其分配一个随机顺序,以便为抽奖类型的应用程序绘制它们.
假设您需要有一个需要经常迭代的整数列表/数组,我的意思是非常频繁.原因可能有所不同,但它说它是高容量处理的最内循环的核心.
通常,由于其大小的灵活性,人们会选择使用列表(列表).最重要的是,msdn文档声称列表在内部使用数组,并且应该执行速度快(使用Reflector快速查看确认这一点).不用说,有一些开销.
有没有人真正测量过这个?通过列表迭代6M次与阵列相同的时间?
我在Vector中有一组对象,我想从中选择一个随机子集(例如100个项目返回;随机选择5个).在我的第一次(非常草率)传球中,我做了一个非常简单且可能过于聪明的解决方案:
Vector itemsVector = getItems();
Collections.shuffle(itemsVector);
itemsVector.setSize(5);
Run Code Online (Sandbox Code Playgroud)
虽然这样做的好处很简单,但我怀疑它不能很好地扩展,即Collections.shuffle()必须至少为O(n).我不太聪明的选择是
Vector itemsVector = getItems();
Random rand = new Random(System.currentTimeMillis()); // would make this static to the class
List subsetList = new ArrayList(5);
for (int i = 0; i < 5; i++) {
// be sure to use Vector.remove() or you may get the same item twice
subsetList.add(itemsVector.remove(rand.nextInt(itemsVector.size())));
}
Run Code Online (Sandbox Code Playgroud)
有关更好地从集合中抽取随机子集的方法的任何建议吗?
我正在尝试编写一种算法,该算法可以随机地从序列中选择N个不同的项目,而不需要事先知道序列的大小,并且在不止一次迭代序列的情况下进行迭代是很昂贵的.例如,序列的元素可能是一个巨大文件的行.
我在N = 1时找到了一个解决方案(也就是说,当试图从一个巨大的序列中随机选择一个元素时):
import random
items = range(1, 10) # Imagine this is a huge sequence of unknown length
count = 1
selected = None
for item in items:
if random.random() * count < 1:
selected = item
count += 1
Run Code Online (Sandbox Code Playgroud)
但是如何才能为其他N值(比如N = 3)实现同样的目的呢?
说我有y不同的值,我想x随机选择它们.这样做的有效算法是什么?我可以打电话给rand() x时间,但如果很大x,表现会很差y.
请注意,此处需要组合:每个值应具有相同的概率,但结果中的顺序并不重要.当然,任何生成排列的算法都是合格的,但我想知道如果没有随机顺序要求,是否可以更有效地做到这一点.
如何有效地生成0和上限N之间的K个非重复整数的列表,涵盖了这种情况的排列.
在Python中,我可以这样做:
>>> import random
>>> ints = [1,2,3]
>>> random.choice(ints)
3
Run Code Online (Sandbox Code Playgroud)
在C#中,我做的第一件事是:
var randgen = new Random();
var ints = new int[] { 1, 2, 3 };
ints[randgen.Next(ints.Length)];
Run Code Online (Sandbox Code Playgroud)
但这需要索引,也需要复制ints困扰我.所以,我想出了这个:
var randgen = new Random();
var ints = new int[] { 1, 2, 3 };
ints.OrderBy(x=> randgen.Next()).First();
Run Code Online (Sandbox Code Playgroud)
仍然不是很好,很有效率.是否有更优雅的方式从IEnumberable获取随机值?
我有一个网站,用户提交问题(每天零,一或多个),投票并每天回答一个问题(更多细节在这里).用户只能通过提交,投票或回答一次来查看问题.
我有一些玩家已经看过的问题.我需要每个月从池中删除30个问题.我需要选择要删除的问题,以便最大限度地提高游泳池中可用问题的数量.
有5个问题的池的例子(需要删除3个):
我虽然要删除顶级玩家所看到的问题,但这个位置会发生变化.按照上面的例子,玩家A只剩下2个问题要玩(2和4).但是,如果我删除1,3和5,情况将是:
该解决方案的得分为零,即具有最少可用问题量的玩家具有零可用问题.
在这种情况下,最好删除1,3和4,给出:
此解决方案的得分为1,因为有两个可用问题最少的玩家有一个可用问题.
如果数据量很小,我就可以强制解决问题.但是,我有数百个玩家和问题,所以我正在寻找一些算法来解决这个问题.
我希望使用这篇文章中提供的答案从列表中随机选择唯一的项目.
按照所描述的方法,在我的循环的每次迭代中,我生成概率值,该概率值是从列表中挑选当前项目的概率百分比.
我需要知道的是如何使用此百分比值来选择项目(或不是).
这是我的代码,remainingIndices是一个List<int>
for (var i = 0; i < remainingIndices.Count; i++)
{
var probability = pixelsToAdd / (float)(remainingIndices.Count - i);
}
Run Code Online (Sandbox Code Playgroud)
pixelsToAdd是120并且remainingIndices.Count是3600.我得到的概率值从0.0333333351开始
解决方案应该灵活,可以使用更广泛的值,最好是任何值.
谢谢
评论
对于这个问题的未来读者,我应该澄清,起初我认为概率值是0到100之间的某个百分比,但实际上它是介于0和1之间的值,因此与返回值完全匹配Random.NextDouble()因此可以用于比较如下面的答案所述.
我有一个长度为 100 万(0 到 100 万)的数据向量 A。从 A 开始,我想创建包含 A 索引的向量 B(其长度可以说只是 A 的 10%)。这些索引是从 A 中随机抽取的样本索引。我尝试使用 srand() 和 random_shuffle,这是一个好方法吗?提取非常大的向量样本的方法?有人可以建议我吗?
std::vector <int> samplingIndex;
for (int i = 0; i < 1000000; ++i) { samplingIndex.push_back(i); }
std::srand(50);
std::random_shuffle(samplingIndex.begin(), samplingIndex.end());
Run Code Online (Sandbox Code Playgroud)
之后,我从采样索引中取出前 10% 的索引来制作 B。
algorithm ×5
c# ×3
random ×3
probability ×2
.net ×1
arrays ×1
c++ ×1
collections ×1
combinations ×1
generic-list ×1
generics ×1
java ×1
list ×1
math ×1
performance ×1
python ×1
statistics ×1
subset ×1
vector ×1
visual-c++ ×1