我有一个对象列表,我想连续以随机顺序访问这些对象。
我想知道是否有办法确保随机值并不总是相似。
实施例
我的列表是队列列表,我正在尝试交错这些值以产生真实的测试场景。
在任何其他项目之前,我并不特别想要队列1和2中的所有项目。 有没有保证的方法来做到这一点?
由于
编辑:: 我拥有的队列列表基本上是我传输到Web服务的文件列表。文件需要按特定顺序排列,因此队列。
所以我有 Queue1 =“set1_1.xml”,set1_2.xml“,...”set1_n.xml“ 队列2 ...... ... QueueN
虽然每个文件需要按照队列中的其他文件的顺序进行传输,但我想模拟一个真实世界的模拟,其中文件将在不同的时间从不同的源接收,因此将它们交错。
目前我只是在0到(队列数)上使用简单的rand来确定接下来要出列的文件。这有效,但我问是否可能已经离开以获得更多的统一性,而不是从队列1和2中获得50个文件,然后从队列3中获取5个文件。
我确实意识到改变随机性不再使其随机化。
感谢您的所有答案。
答案 0 :(得分:2)
嗯,情况并不完全清楚,但是随机的东西是你永远不能告诉; -p 。你试图做的任何“保证”可能会减少随机性。
你好吗?我个人会这样做:
static IEnumerable<T> GetItems<T>(IEnumerable<Queue<T>> queues)
{
int remaining = queues.Sum(q => q.Count);
Random rand = new Random();
while (remaining > 0)
{
int index = rand.Next(remaining);
foreach (Queue<T> q in queues)
{
if (index < q.Count)
{
yield return q.Dequeue();
remaining--;
break;
}
else
{
index -= q.Count;
}
}
}
}
这在整个集合中应该是相当统一的。这里的诀窍在于,通过将队列视为单个大型队列,趋势是具有大量项目的队列将更快地出列(因为在其范围内获得索引的可能性更大)。这意味着它应该自动平衡队列之间的消耗,以便它们(大致)同时干燥。如果您没有LINQ,只需更改第一行:
int remaining = 0;
foreach(Queue<T> q in queues) {remaining += q.Count;}
使用示例:
static void Main()
{
List<Queue<int>> queues = new List<Queue<int>> {
Build(1,2,3,4,5), Build(6,7,8), Build(9,10,11,12,13)
};
foreach (int i in GetItems(queues))
{
Console.WriteLine(i);
}
}
static Queue<T> Build<T>(params T[] items)
{
Queue<T> queue = new Queue<T>();
foreach (T item in items)
{
queue.Enqueue(item);
}
return queue;
}
答案 1 :(得分:2)
这取决于你真正想要的......
如果“随机”值是真正随机的,那么将通过足够的迭代得到均匀分布。
如果您正在谈论控制或操纵分配,那么这些值将不再是真正随机的!
所以,你可以拥有:
答案 2 :(得分:0)
你想要洗牌吗?
如果是这样,你可以通过对随机值进行排序来实现。
尝试这样的事情:
private Random random = new Random();
public int RandomSort(Queue q1, Queue q2)
{
if (q1 == q2) { return 0; }
return random.Next().CompareTo(random.Next());
}
然后在调用List.Sort();
时使用RandomSort作为参数答案 3 :(得分:0)
如果要排队的项目具有GetHashCode()算法,该算法在所有整数上均匀分布值,则可以对散列值采用模运算符来指定要将项添加到的队列。这基本上与哈希表用于确保值的均匀分布的原理相同。