We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
The community reviewed whether to reopen this question 2 years ago and left it closed:
Original close reason(s) were not resolved
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
来自http://www.astrolog.org/labyrnth/algrithm.htm
它们仅产生 10% 的死胡同
是该方法生成的迷宫的示例。
From http://www.astrolog.org/labyrnth/algrithm.htm
They produce only 10% dead ends
is an example of a maze generated by that method.
一个非常简单的解决方案可能是为图的边缘分配随机权重,并应用 Kruskal 算法找到最小生成树。
关于迷宫生成算法的最佳讨论:http://www.jamisbuck.org/presentations/rubyconf2011 /index.html(几天前在 HN 上)。
A pretty straightforward solution could be to assign random weights to the graph edges and apply Kruskal's algorithm to find a minimum spanning tree.
Best discussion ever on maze generation algorithms: http://www.jamisbuck.org/presentations/rubyconf2011/index.html (was on HN a couple days ago).
我最喜欢的方法是使用 Kruskal 算法,但是当随机选择并删除边缘时,根据其连接的边缘类型对选择进行加权。
通过改变不同边缘类型的权重,您可以生成具有许多不同特征或“个性”的迷宫。 请参阅我的示例:
https://mtimmerm.github.io/webStuff/maze.html
My favorite way is to use Kruskal's algorithm, but when randomly choosing and edge to remove, weight the choice based on the types of edges it's connected to.
By varying the weights for different edge types, you can generate mazes with lots of distinct characteristics or "personalities". See my example here:
https://mtimmerm.github.io/webStuff/maze.html
奇怪的是,通过稍微改变“规范”规则并从随机配置开始,康威的生命游戏 似乎生成了非常漂亮的迷宫!
(我不记得确切的规则,但这是一个非常简单的修改,往往会“致密”细胞群......)
Strangely enough, by slightly changing the 'canonical' rules and starting from a random configuration, Conway's Game of Life seems to generate pretty nice mazes!
(I don't remember the exact rule, but it's a very simple modification that tends to 'densify' the population of cells...)
递归回溯是最容易实现的算法。
这是一个 Java 实现:
这里 Cell 是一个表示 2D 网格中单元格的类,cells 是 Cell 对象的 2D 数组。 Cell 有布尔变量 top、bottom、left 和 right 来指示是否单元格的这些侧面都有墙,一个布尔变量visited来检查我们是否已经遍历它,两个整数变量row和col来指示它的位置在网格中。
Recursive Backtracking is the easiest algorithm to implement.
Here's a Java implementation:
Here Cell is a class representing a cell in a 2D grid and cells is a 2D array of Cell objects. Cell has boolean variables top, bottom, left and right to indicate whether a cell has walls on these sides, a boolean variable visited to check whether we have traversed it and two integer variables row and col to indicate its position in the grid.
事实证明,有 11 种经典算法可以生成“完美”迷宫。 如果迷宫只有一种解决方案,那么它就是完美的。 以下是每个算法的一些链接,按照我的偏好大致顺序排列。
有关更多信息,请查看 mazelib GitHub,一个实现所有标准迷宫生成/求解算法的 Python 库。
It turns out there are 11 classic algorithms to generate "perfect" mazes. A maze is perfect if it has one, and only one, solution. Here are some links to each algorithm, in rough order of my preference.
For more info, check out mazelib on GitHub, a Python library implementing all the standard maze generating/solving algorithms.
生成迷宫的方法之一是 Prim 算法的随机版本。
从充满墙壁的网格开始。
选择一个单元格,将其标记为迷宫的一部分。 将单元格的墙壁添加到墙壁列表中。
当列表中有墙时:
从列表中随机选择一堵墙。 如果对面的单元格尚未进入迷宫:
(i) 将墙壁设为通道,并将对面的单元格标记为迷宫的一部分。
(ii) 将单元格的相邻墙壁添加到墙壁列表中。
如果对面的单元格已经在迷宫中,则从列表中删除墙。
One of the methods to generate a maze is the randomized version of Prim's algorithm.
Start with a grid full of walls.
Pick a cell, mark it as part of the maze. Add the walls of the cell to the wall list.
While there are walls in the list:
Pick a random wall from the list. If the cell on the opposite side isn't in the maze yet:
(i) Make the wall a passage and mark the cell on the opposite side as part of the maze.
(ii) Add the neighboring walls of the cell to the wall list.
If the cell on the opposite side already was in the maze, remove the wall from the list.
这是用伪代码编写的 DFS 算法:
创建一个 CellStack (LIFO) 来保存单元位置列表
设置 TotalCells = 网格中的单元格数量
随机选择一个单元格并将其命名为 CurrentCell
设置 VisitedCells = 1
当 VisitedCells < 时 细胞总数
找到 CurrentCell 的所有邻居且所有墙壁都完好无损
如果找到一个或多个
随机选择一个
推倒它和 CurrentCell 之间的墙
将 CurrentCell 位置推送到 CellStack
使新单元格成为 CurrentCell
将 1 添加到 VisitedCells
别的
从 CellStack 中弹出最新的单元条目
使其成为当前单元格
万一
结束时
Here's the DFS algorithm written as pseudocode:
create a CellStack (LIFO) to hold a list of cell locations
set TotalCells = number of cells in grid
choose a cell at random and call it CurrentCell
set VisitedCells = 1
while VisitedCells < TotalCells
find all neighbors of CurrentCell with all walls intact
if one or more found
choose one at random
knock down the wall between it and CurrentCell
push CurrentCell location on the CellStack
make the new cell CurrentCell
add 1 to VisitedCells
else
pop the most recent cell entry off the CellStack
make it CurrentCell
endIf
endWhile
我更喜欢递归除法算法的一个版本。 此处详细描述。
< strong>我将快速概述:
原始递归除法算法的工作原理如下。 首先,从迷宫的空白区域开始。 添加一堵直墙将房间一分为二,并在该墙上的某处打一个洞。 然后,在两个新室中的每一个上递归地重复此过程,直到达到所需的通道尺寸。 这很简单并且效果很好,但是存在明显的瓶颈,使得迷宫很容易解决。
该变体通过绘制随机的“弯曲”墙而不是直墙来解决这个问题,从而使瓶颈不那么明显。
I prefer a version of the Recursive Division algorithm. It is described in detail here.
I will give a quick overview:
The original recursive division algorithm works as follows. First, start with an empty area for the maze. Add one straight wall to divide the chamber in two, and put one hole in that wall somewhere. Then, recursively repeat this process on each of the two new chambers until the desired passage size is reached. This is simple and works well, but there are obvious bottlenecks which make the maze easy to solve.
The variant solves this problem by drawing randomized, "curved" walls rather than straight ones, making the bottlenecks less obvious.