Обеспечить равномерное (ish) распределение с генерацией случайных чисел - PullRequest
1 голос
/ 06 февраля 2009

У меня есть список объектов, и я хотел бы получить доступ к объектам в случайном порядке непрерывно.

Мне было интересно, был ли способ гарантировать, что случайное значение не всегда было одинаковым.

Пример.

Мой список - это список очередей, и я пытаюсь чередовать значения, чтобы создать реальный сценарий для тестирования.

Я не особо хочу, чтобы все предметы в очередях 1 и 2 были раньше любого другого предмета. Есть ли гарантированный способ сделать это?

Спасибо

РЕДАКТИРОВАТЬ :: Список очередей, который у меня есть, представляет собой список файлов, которые я передаю в веб-сервис. Файлы должны быть в определенном порядке, поэтому очереди.

Итак, у меня есть Queue1 = "set1_1.xml", set1_2.xml ", ..." set1_n.xml " Очередь2 ... ... QueueN

Хотя каждый файл должен передаваться по порядку с точки зрения других файлов в его очереди, я хотел бы смоделировать имитацию реального мира, в которой файлы будут приниматься из разных источников в разное время, и поэтому они чередуются.

В данный момент я просто использую простой ранд от 0 до (количество очередей), чтобы определить, какой файл будет удален в очередь следующим. Это работает, но я спрашивал, можно ли было добиться большей однородности, вместо того, чтобы иметь 50 файлов из очереди 1 и 2, а затем 5 файлов из очереди 3.

Хотя я понимаю, что изменение случайности больше не делает ее случайной.

Спасибо за все ваши ответы.

Ответы [ 4 ]

2 голосов
/ 06 февраля 2009

Это зависит от того, что вы действительно хотите ...

Если «случайные» значения действительно случайны, то вы получите равномерное распределение с достаточным количеством итераций.

Если вы говорите о управлении или манипулировании распределением, то значения больше не будут действительно случайными!

Итак, вы можете иметь:

  • Действительно случайные значения с равномерным распределением или
  • Контролируемое распределение, но больше не является действительно случайным
2 голосов
/ 06 февраля 2009

Ну, не совсем ясно, каков сценарий, но случайная вещь - , которую вы никогда не сможете сказать; -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;
}
0 голосов
/ 06 февраля 2009

Если элементы, которые должны быть поставлены в очередь, имеют алгоритм GetHashCode (), который распределяет значения равномерно по всем целым числам, вы можете использовать оператор модуля для значения хеш-функции, чтобы указать, в какую очередь добавлять элемент. По сути, это тот же принцип, который используют хеш-таблицы для обеспечения равномерного распределения значений.

0 голосов
/ 06 февраля 2009

Вы пытаетесь перетасовать свой список?

Если это так, вы можете сделать это, отсортировав его по случайному значению.

Попробуйте что-то вроде этого:

private Random random = new Random();
public int RandomSort(Queue q1, Queue q2)
{
  if (q1 == q2) { return 0; }
  return random.Next().CompareTo(random.Next());
}

А затем использовать RandomSort в качестве аргумента при вызове List.Sort ();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...