Algorithm 生成由10个正交连接点形成的所有可能形状的最有效方法是什么?
我需要在二维空间中生成10个点的所有有效组合 在这种情况下,有效形状表示:Algorithm 生成由10个正交连接点形成的所有可能形状的最有效方法是什么?,algorithm,combinatorics,Algorithm,Combinatorics,我需要在二维空间中生成10个点的所有有效组合 在这种情况下,有效形状表示: 所有点相互连接,不允许对角连接 如果我们在点周围绘制一个外部边界,那么形状内部应该没有空点 以下是一些有效和无效组合的示例: 我尝试了几种算法,但它们都效率低下,而且计算时间太长。生成和存储所有有效组合的最有效方法是什么 我需要它的生成性设计的目的。组合表示建筑楼层平面中的房间形状。 首选的语言是Python。我不确定您想做什么,但我认为您可以通过以下方式生成由10个点组成的所有形状: 从任意像素开始,标记它并尝试在
首选的语言是Python。我不确定您想做什么,但我认为您可以通过以下方式生成由10个点组成的所有形状:
- 从任意像素开始,标记它并尝试在四个基本方向上移动
- 在下一个像素处,标记它并尝试在四个基本方向上移动,前提是像素未标记
- 递归地继续,直到达到允许的像素数。如果你到达了初始像素的邻居,你有一个有效的形状
- 当递归回溯时,取消标记要离开的像素
作为一种可能有用的优化,您可以通过避免不可能返回的移动(曼哈顿距离太大)来避免远离初始像素的路径。下面的代码打印通过正交连接
n
点可以生成的所有可能结构。对于您的用例来说,它非常有效,对于n=10,它在我的笔记本电脑中运行大约4秒钟,并进行有效性检查(房间中没有间隙)。基于n=8、9、10、11的运行时间,时间复杂度似乎是O(4^n),考虑到四个基本方向,这是有意义的
这个想法是先放一点,然后反复考虑可以放置点的位置,这样就可以满足任何约束。在每个步骤中,我们考虑结构中的任何点的外边界,这些点以前没有考虑过任何部分,并且考虑将这些空间填充到我们已经留下的任意数量的点的所有可能组合。
房间内无间隙的约束通过从刚选定点旁边的空单元格进行深度优先搜索进行验证。如果在DFS过程中的任何一点,它到达墙壁或走得足够远,则它是有效的
下面是代码(需要Python 3.6+用于yield from
和f-string
):
#-*-编码:utf-8-*-
"""
2019年8月2日
生成所有可能的平面布置图。
https://stackoverflow.com/questions/57310325/
"""
#导入语句
来自_u未来_;导入打印功能,分区
导入系统
从argparse导入ArgumentParser
从pprint导入pprint
从itertools导入组合
def邻居(行、列):
“”“生成点的所有邻居”“”
结果=[]
对于dir_行,dir_col in[(-1,0)、(0,-1)、(0,1)、(1,0)]:
新建行,新建列=行+方向行,列+方向列
结果.追加((新行,新列))
返回结果
def生成_结构(n):
“”“主生成器,用于生成可由n个正交连接的
点数
#设置网格
#假设第一个点是最左边的点,在最左边的点中,
#它是最顶级的。这可以防止重复结构,因为所有结构都有
#唯一的最左边最上面的点。
网格=['.]*n表示范围内的uuu(2*n-2)]
对于范围内的r(透镜(网格)):
网格[r]。追加('X')
网格[r]。插入(0,'X')
grid.append(['X']*(n+2))
插入(0,['X']*(n+2))
行,列=n-1,1
对于范围内的r(行):
网格[r][1]=“X”
网格[行][col]=“O”
_生成_结构的产量(网格,n-1,[(行,列)],(行,列),n-1)
定义生成结构(网格、n、最后一个点、源、最大距离):
“”“递归函数,生成剩余n个点的所有可能结构,
其中last_points是最后添加的点。
验证检查中使用了source和max_dist,使其稍微快一点。
"""
如果n==0:
#没有更多要放置的点,返回当前结构
屈服网格
提出停止迭代
def get_展开(点,字符集='。):
“”“使用给定的字符集获取选定点周围的所有点。”“”
扩展=集合()
对于行、列和点:
如果网格[行][列]!='O':
#仅从点展开
持续
对于新行,邻居中的新列(行,列):
如果网格[新行][新列]不在字符集中:
持续
扩展.添加((新行,新列))
扩展=列表(已排序(扩展))
回流膨胀
扩展=获取扩展(最后的点)
#对于可以指定给边界的所有可能点数
#最后添加的点数(1到n)
对于范围(1,n+1)内的i:
考虑所有可能的组合(空格数的选择)
#点数)
对于组合中的组合指数(范围(len(扩展)),i):
includeds=[False]*len(扩展)
包含的_点=[]
对于组合指数中包含的指数:
includeds[包含索引]=真
对于zip中包含的(行、列)(包含,扩展):
如果包括:
网格[行][col]=“O”
包含的_点。附加((行、列))
其他:
网格[行]
Structure ID: 0
.O
.O
.O
OO
Structure ID: 1
.OO
.O.
OO.
Structure ID: 2
..O
.OO
OO.
Structure ID: 3
.OOO
OO..
Structure ID: 4
.O.
.OO
OO.
Structure ID: 5
..O
..O
OOO
Structure ID: 6
..OO
OOO.
Structure ID: 7
...O
OOOO
Structure ID: 8
OOOOO
Structure ID: 9
OOOO
...O
Structure ID: 10
OOO.
..OO
Structure ID: 11
OOO
..O
..O
Structure ID: 12
..O.
OOOO
Structure ID: 13
..O
OOO
..O
Structure ID: 14
OOOO
..O.
Structure ID: 15
OO..
.OOO
Structure ID: 16
OO.
.OO
..O
Structure ID: 17
OO
.O
OO
Structure ID: 18
OO.
.O.
.OO
Structure ID: 19
OO
.O
.O
.O
Structure ID: 20
OO.
.OO
.O.
Structure ID: 21
.O.
.O.
OOO
Structure ID: 22
.OO
OOO
Structure ID: 23
.O..
OOOO
Structure ID: 24
.O.
OOO
..O
Structure ID: 25
.O
.O
OO
.O
Structure ID: 26
.OO
OO.
.O.
Structure ID: 27
.O.
OO.
.OO
Structure ID: 28
.O
OO
.O
.O
Structure ID: 29
..O
OOO
.O.
Structure ID: 30
OOOO
.O..
Structure ID: 31
OOO
.OO
Structure ID: 32
OOO
.O.
.O.
Structure ID: 33
.O.
OOO
.O.
Structure ID: 34
O.O
OOO
Structure ID: 35
O...
OOOO
Structure ID: 36
O..
OOO
..O
Structure ID: 37
O..
OO.
.OO
Structure ID: 38
O.
OO
.O
.O
Structure ID: 39
O..
OOO
.O.
Structure ID: 40
O..
O..
OOO
Structure ID: 41
O.
O.
OO
.O
Structure ID: 42
O.
O.
O.
OO
Structure ID: 43
O
O
O
O
O
Structure ID: 44
O.
O.
OO
O.
Structure ID: 45
O..
OOO
O..
Structure ID: 46
O.
OO
OO
Structure ID: 47
O.
OO
O.
O.
Structure ID: 48
.O
.O
OO
O.
Structure ID: 49
.OO
OO.
O..
Structure ID: 50
..O
OOO
O..
Structure ID: 51
OOOO
O...
Structure ID: 52
OOO
O.O
Structure ID: 53
OO.
OOO
Structure ID: 54
OO
OO
.O
Structure ID: 55
OO
O.
OO
Structure ID: 56
OO
O.
O.
O.
Structure ID: 57
.O.
OOO
O..
Structure ID: 58
.O
OO
OO
Structure ID: 59
.O
OO
O.
O.
Structure ID: 60
OOO
OO.
Structure ID: 61
OOO
O..
O..
Structure ID: 62
OO
OO
O.