Получать уникальные номера и знать, когда они освобождены - PullRequest
4 голосов
/ 31 августа 2011

У меня есть физическое моделирование (с использованием Box2D), в котором тела с одинаковыми целыми идентификаторами не сталкиваются, например, тела, принадлежащие одному и тому же персонажу. У меня проблема, хотя в том, что мне нужно иметь возможность получить уникальный номер для каждого возможного объекта, чтобы никакие два символа случайно не получили один и тот же идентификатор. Существует конечное число тел, но они создаются и уничтожаются в соответствии с требованиями моделирования, поэтому необходимо освободить уникальные идентификаторы, как только тело, которому они принадлежали, исчезло.

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

До сих пор я думал о двух методах, но я не уверен, что будет лучше, если один из них вообще:

  • Сохраните vector<short>, где данные - это число обращений, а позиция в векторе - сам идентификатор. Недостатком этого метода является то, что он создает ненужную сложность при кодировании сущностей, которые манипулируют идентификаторами групп, поскольку им необходимо убедиться, что они сообщают World, сколько ссылок они извлекают.

  • Сохраните vector<bool>, с данными, если этот идентификатор свободен или нет, а позиция в векторе является самим идентификатором. Вектор будет расти с каждым новым вызовом уникального идентификатора, если не будет свободных слотов. Недостатком является то, что, как только вектор достигнет определенного размера, потребуется провести аудит всей симуляции, но преимущество заключается в том, что сущности могут получать уникальные числа без помощи в подсчете ссылок.

Как вы думаете, есть ли лучший способ?

Ответы [ 2 ]

8 голосов
/ 31 августа 2011

Вы можете поддерживать «свободный» список неиспользуемых идентификаторов в виде односвязного списка внутри вашего главного World объекта.

Когда объект уничтожается World (делая его идентификатор неиспользованным), вы можетевставьте этот идентификатор в верхнюю часть свободного списка.

Когда вы создаете новый объект, вы можете сделать следующее:

If the free list is non-empty: pop the head item and take that ID.
Else increment a global ID counter and assign it's current value.

В то время как у вас все еще могут заканчиваться идентификаторы (если выодновременно имея больше объектов, чем максимальное значение вашего счетчика), эта стратегия позволит вам перерабатывать идентификаторы и делать все с O(1) сложностью времени выполнения.

РЕДАКТИРОВАТЬ: Согласно комментариям @ Matthieu ниже, a *Контейнер 1013 * также может быть использован для ведения «свободного» списка.Этот контейнер также поддерживает операции push_front, pop_front со сложностью O(1).

Надеюсь, это поможет.

4 голосов
/ 31 августа 2011

Сколько там тел? Реально ли, что у вас когда-нибудь закончатся целые числа, если вы не переназначите их? Самое простое решение состоит в том, чтобы иметь одно целое число для хранения следующего идентификатора - это число будет увеличиваться при назначении нового идентификатора телу.

...