我需要一种算法来在 2D 网格上随机生成一个自回避多边形,大小在 (M x N) 以内。自回避多边形的定义在这里。那是网格上的闭合路径(环),它本身不交互。
如果可能,该算法将更好地以相同的概率生成任何可能的自我回避多边形。
我可以想出迷宫生成算法,使用深度优先搜索来生成树wiki-link,那么树的圆形周长只是一个自我回避的多边形。但是这种方法不能生成所有可能的自回避多边形,例如网格中最大的矩形(M x N)。
以下算法将生成 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)