Многоагентная система в дизайне кода C ++ - PullRequest
4 голосов
/ 30 августа 2010

У меня есть симуляция, написанная на C ++, в которой мне нужно поддерживать переменное число агентов, и у меня возникают проблемы с выбором, как правильно ее реализовать.Каждый агент выглядит примерно так:

class Agent{
public:
    Vector2f pos;
    float health;
    float data[DATASIZE];
    vector<Rule> rules;
}

Мне нужно поддерживать переменное количество агентов в моей симуляции, такое что:

  1. Предпочтительно, нет верхней границы числаагентов
  2. Я могу легко добавить агента
  3. Я могу легко удалить любого агента при определенных условиях (скажем, здоровье <0) </li>
  4. Я могу легко перебрать все агенты и что-то сделать(скажем, здоровье -)
  5. Предпочтительно, я могу распараллелить работу, используя openMP, потому что многие обновления несколько дорогостоящие, но полностью независимы от других агентов.
  6. (редактировать) порядок агентовне имеет значения

Какой тип контейнера или принципы дизайна я должен использовать для агентов?До сих пор я использовал вектор, но я думаю, что довольно сложно стереть из этой структуры: что-то, что мне нужно делать довольно часто, потому что вещи умирают все время.Есть ли какие-то альтернативы, на которые я должен обратить внимание?Я думал о чем-то вроде List, но я не думаю, что они могут быть распараллелены, потому что они реализованы как связанные списки с объектами итератора?

Спасибо

Ответы [ 4 ]

5 голосов
/ 30 августа 2010

Вы можете оставить агента в списке, когда он мёртв, готов к повторному использованию. Не беспокойтесь об уменьшении вашего контейнера, и вы сохраняете преимущества вектора. Вы можете хранить отдельную стопку указателей для мертвых / повторно используемых агентов, просто нажимайте на нее, когда агент умирает, вытаскивайте одну, чтобы вернуть нового агента.

foreach Agent {
    if (agent.health > 0) // skip dead agents
        process rules
3 голосов
/ 30 августа 2010

До сих пор я использовал вектор, но я думаю, что довольно сложно стереть из этой структуры: что-то, что мне нужно делать довольно часто, потому что вещи умирают все время.

Сколько вы на самом деле ожидаете умереть за каждый шаг вашей симуляции?То, что человеку кажется «все время», все еще можно считать очень редким для компьютера.Например, если на каждом этапе вашей симуляции обрабатываются тысячи агентов, но в среднем только один агент умирает каждые несколько шагов, то смерть агента является незначительным инцидентом.С такими цифрами ваша программа тратит гораздо больше времени на обработку живых агентов, чем на мертвые агенты, и поэтому беспокоиться о производительности удаления мертвого агента может не стоить вообще.Если повышение эффективности удаления агента приведет к тому, что обычная итерация и обработка агента станут менее эффективными (хотя удаление агента является относительно редким), это, вероятно, будет плохим компромиссом.

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

Мой общий совет - продолжать использовать std :: vector (при условии, что он соответствует остальной части вашего дизайна), если только вы на самом делеожидать значительного числа смертей агентов за шаг по сравнению с количеством агентов в целом.

0 голосов
/ 30 августа 2010

Используйте quadtree, как в видеоиграх.Тогда поиск по pos будет быстрым, а удаление - быстрым.(Кроме того, вы можете распараллеливать дочерние узлы).

0 голосов
/ 30 августа 2010

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

Если вам не нужен обратный переход, slist так же хорош, как и список, и немного быстрее.

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

...