2009-02-06 6 views
1

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

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

Пример.

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

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

Благодаря

EDIT :: Список Очереди у меня есть это в основном список файлов, которые я передаю на веб-сервиса. Файлы должны быть в определенном порядке, следовательно, очереди.

Так что я queue1 = "set1_1.xml", set1_2.xml», ... "set1_n.xml" Queue2 ... ... QueueN

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

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

Я действительно понимаю, что изменение случайности больше не делает его случайным.

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

+0

Почему вы получаете «50 файлов из очереди 1 и 2, а затем 5 файлов из очереди 3»? Если очереди выбраны случайным образом, вы должны получить примерно равное распределение. Или я не понимаю проблему? – LukeH

+0

они выбираются случайным образом. Но ранд на 1-3 не всегда очень случайный, я нашел. – Rocco

+0

Можете ли вы опубликовать код, который используется для генерации ваших случайных значений? Я получаю довольно хорошее распространение даже при небольшом наборе значений. – LukeH

ответ

2

Ну, не все ясно, что такое сценарий, но вещь со случайным вы никогда не можете сказать ;-p. Все, что вы пытаетесь сделать, чтобы «гарантировать» thins, вероятно, уменьшит случайность.

Как вы это делаете? Лично я бы сделал что-то вроде:

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; 
} 
2

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

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

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

Таким образом, вы можете иметь:

  • Действительно случайных значения с распределением равномерным или
  • Controlled распределения, но больше не истинно случайного
0

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

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

попробовать что-то вроде этого:

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();

+0

Использование Random в этом случае очень ненадежно; в частности, он нарушает транзитивность и симметрию –

+0

(чтобы он работал, вам нужно было бы генерировать * и хранить * случайное значение для каждой записи, а затем сортировать по этому значению - чтобы при тестировании {a, b} вы получаете - {b, a} –

+0

Это правда, но до тех пор, пока он просто хочет перебирать список в случайном порядке и быть уверенным, что он получает все элементы, он должен работать достаточно хорошо. –

0

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