1

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

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

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

一个例子

4

1 回答 1

0

以下算法将生成 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)
于 2019-03-24T09:47:49.973 回答