回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我需要帮助来实现一个允许生成建筑平面图的算法,这是我最近在阅读Kostas Terzidis教授的最新出版物:<a href="https://books.google.com/books/about/Permutation_Design.html?id=govtnQEACAAJ&source=kp_book_description&redir_esc=y" rel="noreferrer"><em>Permutation Design: Buildings, Texts and Contexts</em></a>(2014)时偶然发现的。在</p>
<p><strong>上下文</strong></p>
<ul>
<li>考虑一个被划分为网格系统(a)的站点(b)。在</li>
<li>让我们也考虑一个空间列表,在场地的限制(c)和邻接矩阵,以确定这些空间(d)的放置条件和相邻关系</li>
</ul>
<p><a href="https://i.stack.imgur.com/mCkiS.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/mCkiS.jpg" alt="enter image description here"/></a></p>
<p>引用Terzidis教授的话:</p>
<blockquote>
<p>"A way of solving this problem is to stochastically place spaces within the grid until all spaces are fit and the constraints are satisfied"</p>
</blockquote>
<p>上图显示了这样一个问题和一个示例解决方案(f)。在</p>
<p><strong>算法(如书中所述)</strong></p>
<p>1/“每个空间都与一个列表相关联,该列表包含根据所需邻域度排序的所有其他空间。”</p>
<p>2/”然后从列表中选择每个空间的每个单元,然后逐个随机放置在场地中,直到它们适合场地并且满足相邻条件。(如果失败,则重复该过程)”</p>
<p>九个随机生成的计划示例:</p>
<p><a href="https://i.stack.imgur.com/35i4I.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/35i4I.jpg" alt="enter image description here"/></a></p>
<p>我要补充的是,作者稍后解释了<strong>该算法不依赖于暴力技术</strong>。在</p>
<p><strong>问题</strong></p>
<p>如您所见,解释相对模糊,<strong>步骤2</strong>也相当不清楚(就编码而言)。到目前为止,我只有“拼图碎片”:</p>
<ul>
<li>“站点”(所选整数的列表)</li>
<li>邻接矩阵(嵌套列表)</li>
<li>“空格”(列表用语)</li>
</ul>
<p>对于每个单元:</p>
<ul>
<li>返回其直接邻居的函数</li>
<li>其理想邻居的列表,其索引按排序顺序排列</li>
<li><p>基于实际邻居的健康评分</p>
<pre><code>from random import shuffle
n_col, n_row = 7, 5
to_skip = [0, 1, 21, 22, 23, 24, 28, 29, 30, 31]
site = [i for i in range(n_col * n_row) if i not in to_skip]
fitness, grid = [[None if i in to_skip else [] for i in range(n_col * n_row)] for e in range(2)]
n = 2
k = (n_col * n_row) - len(to_skip)
rsize = 50
#Adjacency matrix
adm = [[0, 6, 1, 5, 2],
[6, 0, 1, 4, 0],
[1, 1, 0, 8, 0],
[5, 4, 8, 0, 3],
[2, 0, 0, 3, 0]]
spaces = {"office1": [0 for i in range(4)],
"office2": [1 for i in range(6)],
"office3": [2 for i in range(6)],
"passage": [3 for i in range(7)],
"entry": [4 for i in range(2)]}
def setup():
global grid
size(600, 400, P2D)
rectMode(CENTER)
strokeWeight(1.4)
#Shuffle the order for the random placing to come
shuffle(site)
#Place units randomly within the limits of the site
i = -1
for space in spaces.items():
for unit in space[1]:
i+=1
grid[site[i]] = unit
#For each unit of each space...
i = -1
for space in spaces.items():
for unit in space[1]:
i+=1
#Get the indices of the its DESIRABLE neighbors in sorted order
ada = adm[unit]
sorted_indices = sorted(range(len(ada)), key = ada.__getitem__)[::-1]
#Select indices with positive weight (exluding 0-weight indices)
pindices = [e for e in sorted_indices if ada[e] > 0]
#Stores its fitness score (sum of the weight of its REAL neighbors)
fitness[site[i]] = sum([ada[n] for n in getNeighbors(i) if n in pindices])
print 'Fitness Score:', fitness
def draw():
background(255)
#Grid's background
fill(170)
noStroke()
rect(width/2 - (rsize/2) , height/2 + rsize/2 + n_row , rsize*n_col, rsize*n_row)
#Displaying site (grid cells of all selected units) + units placed randomly
for i, e in enumerate(grid):
if isinstance(e, list): pass
elif e == None: pass
else:
fill(50 + (e * 50), 255 - (e * 80), 255 - (e * 50), 180)
rect(width/2 - (rsize*n_col/2) + (i%n_col * rsize), height/2 + (rsize*n_row/2) + (n_row - ((k+len(to_skip))-(i+1))/n_col * rsize), rsize, rsize)
fill(0)
text(e+1, width/2 - (rsize*n_col/2) + (i%n_col * rsize), height/2 + (rsize*n_row/2) + (n_row - ((k+len(to_skip))-(i+1))/n_col * rsize))
def getNeighbors(i):
neighbors = []
if site[i] > n_col and site[i] < len(grid) - n_col:
if site[i]%n_col > 0 and site[i]%n_col < n_col - 1:
if grid[site[i]-1] != None: neighbors.<a href="https://www.cnpython.com/list/append" class="inner-link">append</a>(grid[site[i]-1])
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if site[i] <= n_col:
if site[i]%n_col > 0 and site[i]%n_col < n_col - 1:
if grid[site[i]-1] != None: neighbors.append(grid[site[i]-1])
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if site[i]%n_col == 0:
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if site[i] == n_col-1:
if grid[site[i]-1] != None: neighbors.append(grid[site[i]-1])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if site[i] >= len(grid) - n_col:
if site[i]%n_col > 0 and site[i]%n_col < n_col - 1:
if grid[site[i]-1] != None: neighbors.append(grid[site[i]-1])
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
if site[i]%n_col == 0:
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
if site[i]%n_col == n_col-1:
if grid[site[i]-1] != None: neighbors.append(grid[site[i]-1])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
if site[i]%n_col == 0:
if site[i] > n_col and site[i] < len(grid) - n_col:
if grid[site[i]+1] != None: neighbors.append(grid[site[i]+1])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
if site[i]%n_col == n_col - 1:
if site[i] > n_col and site[i] < len(grid) - n_col:
if grid[site[i]-1] != None: neighbors.append(grid[site[i]-1])
if grid[site[i]+n_col] != None: neighbors.append(grid[site[i]+n_col])
if grid[site[i]-n_col] != None: neighbors.append(grid[site[i]-n_col])
return neighbors
</code></pre></li>
</ul>
<p><a href="https://i.stack.imgur.com/xRN87.png" rel="noreferrer"><img src="https://i.stack.imgur.com/xRN87.png" alt="enter image description here"/></a></p>
<p>如果有人能帮我把这些问题联系起来并向我解释一下,我将不胜感激:</p>
<ul>
<li><strong>如何根据单元的理想邻域度重新排序?</strong></li>
</ul>
<p><strong>编辑</strong></p>
<p>正如你们中的一些人所注意到的,该算法基于某些空间(由单元组成)相邻的可能性。根据逻辑,每个单元在现场范围内随机放置:</p>
<ul>
<li>我们事先检查它的直接邻居(上、下、左、右)</li>
<li>如果至少有2个邻居,则计算一个适合度得分。(=这2+邻居的权重之和)</li>
<li>最后,如果邻接概率很高的话,就把这个单元放进去</li>
</ul>
<p>大致可以理解为:</p>
^{pr2}$
<p>考虑到大部分单元不会在第一次运行时放置(因为相邻概率很低),我们需要反复迭代,直到找到所有单元都可以拟合的随机分布。在</p>
<p><a href="https://i.stack.imgur.com/SARen.png" rel="noreferrer"><img src="https://i.stack.imgur.com/SARen.png" alt="enter image description here"/></a></p>
<p>经过几千次迭代后,找到了一个合适的,并且所有相邻的需求都得到了满足。在</p>
<p><strong>但是注意这个算法是如何产生分离的组而不是像所提供的示例中那样的非分割和统一的堆栈</strong>。我还应该补充说,近5000次迭代远远超过了Terzidis先生在他的书中提到的274次迭代。在</p>
<p><strong>问题:</strong></p>
<ul>
<li>我处理这个算法的方式有问题吗?在</li>
<li>如果没有,那么我缺少什么隐含条件?在</li>
</ul>