简体   繁体   English

2D网格的Python数据结构建议

[英]Python Data Structure Recommendations for a 2D Grid

I am looking to implement an Ant Colony Optimization algorithm in Python, though am new to both Python and Object Oriented Programming so the learning curve has been rather steep. 我希望在Python中实现一个蚁群优化算法,虽然它是Python和面向对象编程的新手,所以学习曲线相当陡峭。 At this point, I am stuck as to how to address the following situation: 在这一点上,我被困在如何解决以下情况:

  • As ants walk around a 2D grid, they will encounter obstacles, pheromone deposits by other ants, food, etc. What data structure do I use to represent this 2D world and the aforementioned properties of each cell? 当蚂蚁在2D网格中走动时,它们会遇到障碍物,其他蚂蚁的信息素沉积物,食物等。我用什么数据结构来表示这个2D世界以及每个细胞的上述属性?

I had tried a 2D array, thinking that array[x-coord][y-coord] could point to a {} (dictionary) with the appropriate properties (Obstacle: 'Yes / 'No', Pheromone Level: X %, etc.) . 我曾尝试过2D数组,认为array[x-coord][y-coord]可以指向具有适当属性的{} (dictionary) (Obstacle: 'Yes / 'No', Pheromone Level: X %, etc.) Unfortunately, though NumPy lets me create a 2D array, I cannot assign dictionary objects to the various coordinates. 不幸的是,尽管NumPy允许我创建一个2D数组,但我无法将字典对象分配给各种坐标。

from numpy import *

myArray = array([[1,2,3,4],
                 [5,6,7,8],
                 [9,10,11,12]])

myArray[2][2]={}

Returns: 返回:

Traceback (most recent call last):
  File "/Users/amormachine/Desktop/PythonTest.py", line 7, in <module>
    myArray[2][2]={}
TypeError: long() argument must be a string or a number, not 'dict'
[Finished in 0.6s with exit code 1]

I am not committed to either dictionaries or this paradigm for implementing this project and would certainly appreciate the wisdom of the group. 我不是致力于字典或这个实施这个项目的范例,并且肯定会欣赏该集团的智慧。

sure you can, you just cant if your dtype is int ... so make your array with objects and you can use objects... 确定你可以,你只是不知道你的dtype是否为int ...所以使用对象制作你的数组,你可以使用对象......

In [43]: a = [[{},{},{}],[{},{},{}]]

In [44]: a = numpy.array(a)

In [45]: a[1][1] = {'hello':'world','something':5}

In [46]: a
Out[46]:
array([[{}, {}, {}],
       [{}, {'hello': 'world', 'something': 5}, {}]], dtype=object)

although not sure whay you will gain using numpy with objects, you may be better off just leaving it as a list of lists 虽然不确定whay你会使用numpy与对象,你可能最好把它留作列表列表

In plain Python I would be going for the list-of-dicts approach but with NumPy I find it more natural to work with separate arrays for different attributes rather than trying to keep things in one structure. 在普通的Python中,我会选择list-of-dicts方法,但是对于NumPy,我发现使用不同属性的单独数组更自然,而不是试图将事物保存在一个结构中。

import numpy as np

grid_shape = (120,80)

# example of random initialization with this grid shape
pheremone_level = np.random.rand(*grid_shape)
obstacle = np.random.rand(*grid_shape) > 0.8

As @bitwise says it entirely depends on what operations you want to perform. 正如@bitwise所说,它完全取决于你想要执行的操作。 Generally the "correct" way in NumPy will be much closer to how you would write it in Matlab than non-NumPy Python. 通常,NumPy中的“正确”方式将更接近于在Matlab中编写它而不是非NumPy Python。 Unfortunately I'm not familiar with how Ant Colony Optimization works so I can't say what's more suitable. 不幸的是我不熟悉Ant Colony Optimization的工作方式,所以我不能说什么更合适。

I was looking for something related to structured 2D grids and google led me to this page. 我正在寻找与结构化2D网格相关的东西,谷歌引导我到这个页面。

Although my solution is not entirely related to grids for what has been asked in the question, and I didn't want to repeat a question for 'structured 2D grid' data structure, I'm posting my solution here. 虽然我的解决方案并不完全与问题中提到的网格相关,但我不想重复“结构化二维网格”数据结构的问题,我在这里发布我的解决方案。 I hope it will be useful to the audience searching for 2D structured grid and redirected here by search engines 我希望它对搜索2D结构化网格并在搜索引擎中重定向的观众有用

Note: the method returns only the cell vertices and the vertex connectivity of each cells. 注意:该方法仅返回单元格顶点和每个单元格的顶点连接。 Other quantities like cell volume, cell centroid, circumcircle, incircle, etc as needed for the application can be easily generated by adding additional routines 通过添加其他例程,可以轻松生成应用程序所需的其他数量,如单元体积,单元质心,外接圆,外圆等

import numpy as np
import matplotlib.pyplot as plt

def create_structured_grid(corner1=None, corner2=None, nx=5, ny=5, plt_=True, annotate=True):
   """
   creates a structured grid of rectangular lattice

   input:
   ------
       corner1 : [x_start, y_start]
       corner2 : [x_end, y_end]
       nx      : numpts in x
       ny      : numpts in y
       plt_    : boolean whether to plot or not
       annotate: whether to annotate the grid points or not
   output:
   -------
       vertex_array : numpy.array((numpts, dim),dtype=float) of vertices
       connectivity : numpy.array((num_cells, 2**dim), dtyp=int) of
                   vertex connectivity for each cell
       plots   : additionally plots if boolean values are true
   """
   #corner1 = np.array([0.0, 0.0])
   #corner2 = np.array([1.0, 1.0])
   dim = len(corner1) #currently only for 2D,
   x_pts = np.linspace(corner1[0], corner2[0], nx)
   y_pts = np.linspace(corner1[1], corner2[1], ny)

   Xv, Yv = np.meshgrid(x_pts, y_pts)
   numpts = nx*ny
   vertex_array = np.zeros((numpts, 2), dtype=float)

   vertex_array[:,0] = np.reshape(Xv, numpts)
   vertex_array[:,1] = np.reshape(Yv, numpts)

   num_cells = int(nx-1)*(ny-1)
   connectivity = np.zeros((num_cells, int(2**dim)), dtype=int)

   rows = ny-1
   cols = nx-1
   for row in range(rows):
       for col in range(cols):
           num = nx*row + col
           connectivity[cols*row + col] = [num+0, num+1, num+nx, num+nx+1]

   if plt_:
       X,Y = vertex_array.T
       fig = plt.figure()
       ax = fig.add_subplot(111)
       ax.set_aspect('equal')
       plt.scatter(X,Y, marker='o', s=50, color='g', alpha=1.0)
       plt.plot(Xv,Yv, linewidth=2, color='k')
       plt.plot(Yv,Xv, linewidth=2, color='k')
       if annotate:
           for idx, cc in enumerate(vertex_array):
               plt.text(cc[0], cc[1],  str(idx), color='k', verticalalignment='bottom', horizontalalignment='right', fontsize='medium')
       plt.show(block=False)

   return vertex_array, connectivity

A call to function can be like this: 对函数的调用可以是这样的:

c1 = np.array([0.0, 0.0])
c2 = np.array([1.0, 1.0])
vertices, connctivity = create_structured_grid(corner1=c1, corner2=c2, nx=4, ny=4)

vertices = array([[ 0.        ,  0.        ],
                  [ 0.33333333,  0.        ],
                  [ 0.66666667,  0.        ],
                  [ 1.        ,  0.        ],
                  [ 0.        ,  0.33333333],
                  [ 0.33333333,  0.33333333],
                  [ 0.66666667,  0.33333333],
                  [ 1.        ,  0.33333333],
                  [ 0.        ,  0.66666667],
                  [ 0.33333333,  0.66666667],
                  [ 0.66666667,  0.66666667],
                  [ 1.        ,  0.66666667],
                  [ 0.        ,  1.        ],
                  [ 0.33333333,  1.        ],
                  [ 0.66666667,  1.        ],
                  [ 1.        ,  1.        ]])
connectivity = array([[ 0,  1,  5,  6],
                      [ 1,  2,  6,  7],
                      [ 2,  3,  7,  8],
                      [ 4,  5,  9, 10],
                      [ 5,  6, 10, 11],
                      [ 6,  7, 11, 12],
                      [ 8,  9, 13, 14],
                      [ 9, 10, 14, 15],
                      [10, 11, 15, 16]])

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM