我基本上有两个列表:list1和list2,每个列表都包含位图图像作为元素。
我的问题是如何从两个列表中随机选择位图元素并将它们混合在一起并存储它们是另一个列表“list3”。
List<Bitmap> list1 = new List<Bitmap>();
List<Bitmap> list2 = new List<Bitmap>();
(List3包含随机混合list1和list2的元素,两个列表的大小根据生成的图像数量而变化)
答案 0 :(得分:1)
这个答案主要关注随机交错两个最小偏见的列表。
使用适当的算法非常重要,并且在两个不等长列表之间进行交错时使用rnd.Next(2) == 0
时是一个重要的偏差。当交错2个元素的列表和20个元素的列表时,这种偏差非常 - 较短列表中的元素将聚集在结果的前面附近。虽然并不总是容易看到这种偏见,但它存在于任何两个不等长的列表之间,而不考虑列表的“权重”。
因此,不是使用rnd.Next(2) == 0
来选择源列表,而是一个无偏见的实现应该在所有剩余元素之间选择相当。
if (randInt(remaining(l1) + remaining(l2)) < remaining(l1)) {
// take from list 1
// (also implies list 1 has elements; as rand < 0 never matches)
} else {
// take from list 2
// (also implies list 2 has elements)
}
实现可能如下所示:
IEnumerable<T> RandomInterleave<T>(IEnumerable<T> a, IEnumerable<T> b) {
var rnd = new Random();
int aRem = a.Count();
int bRem = b.Count();
while (aRem > 0 || bRem > 0) {
var i = rnd.Next(aRem + bRem);
if (i < aRem) {
yield return a.First();
a = a.Skip(1);
aRem--;
} else {
yield return b.First();
b = b.Skip(1);
bRem--;
}
}
}
var list3 = RandomInterleave(list1, list2).ToList();
答案 1 :(得分:0)
再一次,给你一个例子。
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
List<int> list3 = new List<int>();
// putting some values into the lists to mix them
for (int i=0; i<50; i++) list1.Add(1);
for (int i=0; i<40; i++) list2.Add(2);
var rnd = new Random();
int listIndex1 = 0;
int listIndex2 = 0;
while (listIndex1 < list1.Count || listIndex2 < list2.Count)
{
if (rnd.Next(2) == 0 || listIndex2 >= list2.Count)
{
list3.Add(list1[listIndex1++]);
}
else
{
list3.Add(list2[listIndex2++]);
}
}
foreach (var mixed in list3) { Console.WriteLine(mixed); }
输出:
1
1
2
2
2
2
1
2
2
1
1
2
2
2
1
...