【问题标题】:Generate paths on n*n grid在 n*n 网格上生成路径
【发布时间】:2012-10-19 22:08:33
【问题描述】:

我有n*n 网格,例如n=10。我必须用黑白元素填充它。每个黑色元素都必须有一个、两个或三个黑色邻居。不允许包含四个或零个邻居的黑色元素。

我应该如何构建这种网格?

编辑:

更具体地说,它是由两个for 循环构建的二维数组:

n = 10
array = [][];
for ( x = 0; x < n; x++ ) {
    for ( y = 0; y < n; y++ ) {
        array[x][y] = rand(black/white)
    }
}

这个伪代码构建了类似的东西:

而我的期望是:

【问题讨论】:

  • 还有其他限制吗?如果这就是你所要做的,只需用交替的白色和黑色行对其进行条纹,并给它一个纯黑色边框。
  • 对角线的单元格是否也被视为邻居,还是仅在其北、东、南和西的 4 个单元格中?
  • 是否允许将单个 2x1 黑色元素放在白色网格上?
  • 在您的预期图像中,您可以从任何黑色方块开始,通过仅遍历黑色方块到达任何黑色方块。对于您要生成的所有网格,此属性是否正确?或者是否允许生成单独的“岛屿”,两者之间的旅行是不可能的?
  • Prim's algorithm 的维基百科页面上有一个很好的迷宫生成演示。

标签: algorithm multidimensional-array


【解决方案1】:

显然,您正在尝试在写入网格上生成“黑色路径”形状。

所以我们就这样做吧。

  • 从白色网格开始。
  • 在上面随机放置一些海龟。
  • 然后,当您的网格不符合适当的白/黑单元格比例时,请执行以下操作
    • 将每只乌龟沿随机方向移动一个单元格并将其涂成黑色,除非这样做会违反“不超过三个黑色邻居”的规则。

【讨论】:

  • 您可以在描述中添加“如果找不到路线,请返回上一个” 此外,似乎从中间开始会得到更好的结果codepad.viper-7.com/FIoJn3
【解决方案2】:

使用您在此处显示的大小,您可以轻松地进行一些蛮力实施。

编写一个函数来检查您是否满足要求,只需遍历所有单元格并计算邻居数。

之后,执行以下操作:

Start out with a white grid.
Then repeatedly:
    pick a random cell
    If the cell is white:
        make it black
        call the grid checking routine.
        if the grid became invalid:
            color it gray to make sure you don't try this one again

do this until you think it took long enough, or there are no more white cells.
then make all gray cells white.

如果您的网格很大(数千像素),您可能应该寻找更有效的算法,但对于 10x10 的网格,这将在瞬间计算出来。

【讨论】:

    【解决方案3】:

    也许这个 python 代码会有一些用处。它的基本思想是对网格进行某种广度优先遍历,确保黑色像素遵守不超过 3 个黑色邻居的约束。与网格的黑色部分对应的图形是一棵树,就像您想要的结果一样。

    import Queue
    import Image
    import numpy as np
    import random
    
    #size of the problem
    size = 50
    
    #grid initialization
    grid = np.zeros((size,size),dtype=np.uint8)
    
    #start at the center
    initpos = (size/2,size/2)
    
    #create the propagation queue
    qu = Queue.Queue()
    
    #queue the starting point
    qu.put((initpos,initpos))
    
    #the starting point is queued
    grid[initpos] = 1
    
    
    #get the neighbouring grid cells from a position
    def get_neighbours(pos):
      n1 = (pos[0]+1,pos[1]  )
      n2 = (pos[0]  ,pos[1]+1)
      n3 = (pos[0]-1,pos[1]  )
      n4 = (pos[0]  ,pos[1]-1)
      return [neigh for neigh in [n1,n2,n3,n4] 
                      if neigh[0] > -1 and \
                         neigh[0]<size and \
                         neigh[1] > -1 and \
                         neigh[1]<size \
             ]
    
    
    while(not qu.empty()):
      #pop a new element from the queue
      #pos is its position in the grid
      #parent is the position of the cell which propagated this one
      (pos,parent) = qu.get()
    
      #get the neighbouring cells
      neighbours = get_neighbours(pos)
    
      #legend for grid values
      #0 -> nothing
      #1 -> stacked
      #2 -> black
      #3 -> white
    
      #if any neighbouring cell is black, we could join two branches
      has_black = False
      for neigh in neighbours:
        if neigh != parent and grid[neigh] == 2:
          has_black = True
          break
    
      if has_black:
        #blackening this cell means joining branches, abort
        grid[pos] = 3
      else:
        #this cell does not join branches, blacken it
        grid[pos] = 2
    
        #select all valid neighbours for propagation
        propag_candidates = [n for n in neighbours if n != parent and grid[n] == 0]
        #shuffle to avoid deterministic patterns
        random.shuffle(propag_candidates)
        #propagate the first two neighbours
        for neigh in propag_candidates[:2]:
          #queue the neighbour
          qu.put((neigh,pos))
          #mark it as queued
          grid[neigh] = 1
    
    #render image
    np.putmask(grid,grid!=2,255)
    np.putmask(grid,grid<255,0)
    im = Image.fromarray(grid)
    im.save('data.png')
    

    这是一个结果设置size = 50

    还有一个设置size = 1000

    你也可以玩树根。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多