Блог пользователя eins

Автор eins, история, 6 лет назад, По-русски

Всем привет!

Есть следующая задача. Существует множество объектов, пронумерованных от 1 до n. Необходимо из него выбрать случайный объект такой, который не был выбран ранее (нужно выбрать не более n объектов). Сама задача заключается в том, чтобы сделать это с O(1) памяти и менее, чем за O(n) времени.

То есть, в идеале нужно написать функцию с параметрами вида next_object_id(n, current_id, seed), возвращающую идентификатор следующего ранее не выбранного случайного элемента.

Решаема ли задача с такими требованиями?

Если по этой теме уже есть наработки, дайте, пожалуйста, подсказку, по какому запросу искать.

  • Проголосовать: нравится
  • -20
  • Проголосовать: не нравится

»
6 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Может быть я чего-то не понимаю, но нельзя ли выбрать сначала объект с номером 1, потом с номером 2, 3, 4 ...,n.

»
6 лет назад, # |
Rev. 4   Проголосовать: нравится -8 Проголосовать: не нравится

The following is a simple C++14 implementation using std::vector< int > and std::mt19937_64 pseudo-random number generator. The code is self-documented, and the time-complexity of the class random_object_selection_t constructor as well as to each call to its member function next() should be O(n).

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Thank you for the answer. But it looks like that solution have more than constant memory consumption and O(n) time complexity per query, that does not satisfy the conditions of the problem.

    • »
      »
      »
      6 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      With pleasure.

      Please check this update to the suggested solution. The next() member function has been updated to use the vector::pop_back function whose time complexity is constant, and one local variable only is used to store the ID of the selected object. Therefore, the memory and time complexities per query are constant.

      Note that the memory and time complexities of the class constructor are O(n), as n integer items are needed to store the object IDs, and the time complexity of the std::random_shuffle function is O(n) as well.