【问题标题】:Randomly generate a Self-Avoiding Polygon on an M-by-N-sized grid在 M×N 大小的网格上随机生成一个自回避多边形
【发布时间】:2019-03-24 07:44:57
【问题描述】:

我需要一种算法来在 2D 网格上随机生成一个自回避多边形,大小在 (M x N) 以内。 自回避多边形的定义位于here。 那是网格上的闭合路径(环),它本身不交互。

如果可能,该算法会更好地以相同的概率生成任何可能的自我回避多边形。

我可以想出迷宫生成算法使用深度优先搜索来生成一棵树wiki-link,那么这棵树的圆形周长只是一个自回避的多边形。 但是这种方法不能生成所有可能的自回避多边形,例如网格中最大的矩形(M x N)。

【问题讨论】:

  • 算法需要全部生成还是随机生成一个
  • @RanikaNisal 创建一个没问题。

标签: algorithm polygon


【解决方案1】:

以下算法将生成 1 个闭合多边形。它虽然没有使用任何图论概念。由于没有提到一种语言,我已经用 python 编写了代码。如果需要,可以轻松更改以查找所有多边形。

import random

currentpath = [(0,0)]
length = 2 #any actual grid is 3x3 length is 2 however
height = 2
initial = (0,0)
allpaths = []

def backtrack(currentpath,currentnode):
    if(currentnode == (0,0) and len(currentpath)>1):
        return True
    directions = [0,1,2,3]
    while(len(directions) > 0):
        x = random.choice(directions)
        if(x == 0):
            #left
            nextnode = (currentnode[0] + 1, currentnode[1])
            if(currentnode[0] == length or (nextnode in currentpath and nextnode != (0,0)) or (nextnode ==(0,0) and len(currentpath)<4)):
                directions.remove(x)
                continue
            else :
                currentpath.append(nextnode)
                if(backtrack(currentpath,nextnode)):
                    return True
                else :
                    directions.remove(x)
                    currentpath.remove(nextnode)
                    continue
        if(x == 1):
            #right
            nextnode = (currentnode[0] - 1, currentnode[1])
            if (currentnode[0] == 0 or (nextnode in currentpath and nextnode != (0,0)) or (nextnode ==(0,0) and len(currentpath)<4)):
                directions.remove(x)
                continue
            else:
                currentpath.append(nextnode)
                if(backtrack(currentpath,nextnode)):
                    return True
                else :
                    directions.remove(x)
                    currentpath.remove(nextnode)
                    continue
        if(x == 2):
            #up
            nextnode = (currentnode[0], currentnode[1] + 1)
            if (currentnode[1] == height or (nextnode in currentpath and nextnode != (0,0)) or (nextnode ==(0,0) and len(currentpath)<4)):
                directions.remove(x)
                continue
            else:
                currentpath.append(nextnode)
                if(backtrack(currentpath,nextnode)):
                    return True
                else :
                    directions.remove(x)
                    currentpath.remove(nextnode)
                    continue
        if(x == 3):
            #down
            nextnode = (currentnode[0], currentnode[1] - 1)
            if (currentnode[1] == 0 or (nextnode in currentpath and nextnode != (0,0)) or (nextnode ==(0,0) and len(currentpath)<4)):
                directions.remove(x)
                continue
            else:
                currentpath.append(nextnode)
                if(backtrack(currentpath,nextnode)):
                    return True
                else :
                    directions.remove(x)
                    currentpath.remove(nextnode)
                    continue
    if(len(directions)==0):
        return False

backtrack(currentpath,initial)
print (currentpath)

【讨论】:

  • 好!但是有一点,随机游走方法似乎生成了具有高概率的较小多边形和具有较低概率的较大多边形。如何提高大而复杂的多边形的机会?
  • 这种方法最坏的情况是极其昂贵的。想想这种情况,如果空间是 100 X 100,如果从一个漩涡状的形状开始运气不好,除非遍历所有可能的路径直到回溯,否则尾巴永远不会遇到头部。
  • 此算法基于的是约束满足问题 (CSP)。如果您希望降低时间复杂度,可以向约束列表中添加更多约束。例如,如果您有一种算法方法来查找您是否肯定处于漩涡中。这种方法的优点是您可以根据需要添加约束并避免进入路径。至于寻找更小的路径,我真的没有答案。选择随机方向是为了找到一条真正随机的路径。
  • 到目前为止,每个方向都有 2 个约束。 (1) 检查我们是否处于阻止我们前往该方向的边缘;(2) 检查我们是否已经在当前路径中拥有下一个节点。
  • 在实践中运行@Ranika Nisal 的代码时,如果length &gt;= 4 height &gt;= 4 经常出现死循环。
猜你喜欢
  • 2012-11-25
  • 2022-01-05
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 2011-10-09
  • 2016-01-15
相关资源
最近更新 更多