C# 通过随机数生成确保均匀(ish)分布

C# 通过随机数生成确保均匀(ish)分布,c#,.net,list,queue,random,C#,.net,List,Queue,Random,我有一个对象列表,我想以随机顺序连续访问这些对象 我想知道是否有办法确保随机值并不总是相似的 例如 我的列表是一个队列列表,我正在尝试交错这些值以生成一个用于测试的真实场景 我并不特别希望队列1和2中的所有项目都排在任何其他项目之前。 有没有一种可靠的方法可以做到这一点 谢谢 编辑:: 我拥有的队列列表基本上是我正在传输到Web服务的文件列表。文件需要按一定的顺序排列,因此需要队列 所以我有 Queue1=“set1_1.xml”,set1_2.xml“,…“set1_n.xml” 队列2。。。

我有一个对象列表,我想以随机顺序连续访问这些对象

我想知道是否有办法确保随机值并不总是相似的

例如

我的列表是一个队列列表,我正在尝试交错这些值以生成一个用于测试的真实场景

我并不特别希望队列1和2中的所有项目都排在任何其他项目之前。 有没有一种可靠的方法可以做到这一点

谢谢

编辑:: 我拥有的队列列表基本上是我正在传输到Web服务的文件列表。文件需要按一定的顺序排列,因此需要队列

所以我有 Queue1=“set1_1.xml”,set1_2.xml“,…“set1_n.xml” 队列2。。。 ... 排队

虽然每个文件都需要按照队列中其他文件的顺序进行传输,但我想模拟一个真实世界的模拟,在这个模拟中,文件将在不同的时间从不同的来源接收,并因此进行交叉

目前,我只是在0到(队列数)上使用一个简单的rand来确定下一个要退出队列的文件。这是可行的,但我想问的是,是否有可能获得更大的一致性,而不是队列1和2中有50个文件,然后队列3中有5个文件

虽然我意识到改变随机性不再使其随机


谢谢你的回答。

好吧,现在还不完全清楚这个场景是什么,但随机性的问题是你永远无法知道;-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;
            }
        }
    }
}
静态IEnumerable GetItems(IEnumerable队列)
{
剩余整数=queues.Sum(q=>q.Count);
Random rand=新的Random();
而(剩余>0)
{
int index=rand.Next(剩余);
foreach(队列中的队列q)
{
如果(索引
这在整个集合上应该是相当一致的。这里的技巧是,通过将队列视为单个大型队列,趋势是包含大量项目的队列将更快地退出队列(因为在其范围内有更多的机会获得索引)。这意味着它应该自动平衡队列之间的消耗,以便它们(大致)同时耗尽。如果没有LINQ,只需更改第一行:

int remaining = 0;
foreach(Queue<T> q in queues) {remaining += q.Count;}
int剩余=0;
foreach(队列中的队列q){剩余+=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;
}
static void Main()
{
列表队列=新列表{
建造(1,2,3,4,5),建造(6,7,8),建造(9,10,11,12,13)
};
foreach(GetItems(队列)中的inti)
{
控制台写入线(i);
}
}
静态队列生成(参数T[]项)
{
队列=新队列();
foreach(项目中的T项目)
{
排队。排队(项目);
}
返回队列;
}

好吧,现在还不完全清楚这个场景是什么,但随机性的问题是你永远无法分辨;-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;
            }
        }
    }
}
静态IEnumerable GetItems(IEnumerable队列)
{
剩余整数=queues.Sum(q=>q.Count);
Random rand=新的Random();
而(剩余>0)
{
int index=rand.Next(剩余);
foreach(队列中的队列q)
{
如果(索引
这在整个集合上应该是相当一致的。这里的技巧是,通过将队列视为单个大型队列,趋势是包含大量项目的队列将更快地退出队列(因为在其范围内有更多的机会获得索引)。这意味着它应该自动平衡队列之间的消耗,以便它们(大致)同时耗尽。如果没有LINQ,只需更改第一行:

int remaining = 0;
foreach(Queue<T> q in queues) {remaining += q.Count;}
int剩余=0;
foreach(队列中的队列q){剩余+=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;
}
static void Main()
{
列表队列=新列表{
建造(1,2,3,4,5),建造(6,7,8),建造(9,10,11,12,13)
};
foreach(GetItems(队列)中的inti)
{
控制台写入线(i);
}
}
静态队列生成(参数T[]项)
{
队列=新队列();
foreach(项目中的T项目)
{
排队。排队(项目);
}
返回队列;
}

这取决于你真正想要什么

如果“随机”值是真正随机的,那么您将通过足够的迭代获得均匀分布

如果您谈论的是控制或操纵分布,那么这些值将不再是真正的随机值

因此,您可以选择:

  • 均匀分布的真正随机值,或
  • 受控分布,但不再是真正的随机分布

这取决于你真正想要什么

如果“随机”值是真正随机的,那么您将通过足够的迭代获得均匀分布

如果您谈论的是控制或操纵分布,那么这些值将不再是真正的随机值

因此,您可以选择:

  • 均匀分布的真正随机值,或
  • 受控分布,但不再是真正的随机分布

您正在尝试洗牌您的列表吗

如果是这样的话,可以通过对随机值进行排序来实现

试着这样做:

private Random random = new Random();
public int RandomSort(Queue q1, Queue q2)
{
  if (q1 == q2) { return 0; }
  return random.Next().CompareTo(random.Next());
}
然后使用RandomSort作为调用L的参数