Python: представляет квадратную сетку, которая оборачивается на себя (цилиндр) - PullRequest
3 голосов
/ 23 января 2011

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

Как лучше всего это смоделировать?

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

Или я должен создать класс, который описывает всю сетку, а не выставлять отдельные точки как независимые объекты?

Или я должен просто использовать обычные (x, y) кортежи и иметь методы в другом месте, которые позволяют искать соседей?

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

РЕДАКТИРОВАТЬ: Еще один вопрос: я должен приложить информацию о количестве ресурсов для каждого экземпляра Point; или я должен иметь отдельный класс, который содержит карту ресурсов, проиндексированных по Point?

Ответы [ 2 ]

2 голосов
/ 23 января 2011

Если вы хотите, чтобы хэш-класс Point работал без особой работы, кортеж подкласса и добавьте свои собственные методы соседей.

class Point(tuple):
    def r_neighbor(self):
        return Point((self[0] + 1, self[1]))
    def l_neighbor(self): 
        [...]

x = Point((10, 11))
print x
print x.r_neighbor()

Конструктор кортежей хочет итерацию, поэтому двойные парены в Point((10, 11));если вы хотите избежать этого, вы всегда можете переопределить __new__ (переопределение __init__ бессмысленно, потому что кортежи неизменны):

def __new__(self, x, y):
    return super(Point, self).__new__(self, (x, y))

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

def __new__(self, x, y, gridsize=100):
    return super(Point, self).__new__(self, (x % gridsize, y % gridsize))

или от включения сеток произвольных измерений, и вернитесь к использованию кортежей в __new__:

def __new__(self, tup, gridsize=100):
    return super(Point, self).__new__(self, (x % gridsize for x in tup))

Относительно вашего вопроса о ресурсах: поскольку Point является неизменным классом, он плохо подходит для хранения информации о ресурсах, которые могут измениться.Дефолдикт был бы удобен;Вы не должны были бы инициализировать это.

from collections import defaultdict

grid = defaultdict(list)
p = Point((10, 13))
grid[(10, 13)] = [2, 3, 4]
print grid[p]                  # prints [2, 3, 4]
print grid[p.r_neighbor]       # no KeyError; prints []

Если вы хотите большей гибкости, вы можете использовать dict вместо списка в defaultdict;но defaultdict(defaultdict) не сработает;Вы должны создать новую фабричную функцию defaultdict.

def intdict():
    return defaultdict(int)

grid = defaultdict(intdict)

или более кратко

grid = defaultdict(lambda: defaultdict(int))

затем

p = Point((10, 13))
grid[(10, 13)]["coins"] = 50
print grid[p]["coins"]              # prints 50
print grid[p.r_neighbor]["coins"]   # prints 0; again, no KeyError
1 голос
/ 23 января 2011

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

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

Единственная проблема заключается в том, что она занимает больше места, чем другие представления.

НаПлюс ко всему, вы можете использовать библиотеку графов для создания графа и, возможно, даже некоторые алгоритмы графов для вычисления направления работы агентов.

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