切断结!

使用Java小程序的交互式专栏
亚历克斯·博戈莫尼

迷宫

2003年10月

很久以前,在爱荷华州的一家木匠店,我为我的第一台电脑买了一张未完工的桌子,这是IBM当地办事处的一笔赠款。我对35美元的价格感到惊讶。“撇开材料成本不谈,单是人工成本就应该比这高。”木匠自豪地回答道,“如果你知道如何切割和组装工件,那就不会了。”我总是记得这一集,当时我试图解决的一个问题有一个我一直没有找到的简单解决方案。

有很长一段时间,我想写一个电脑程序来画迷宫。我甚至也尝试了几次。但没有一个是令人满意或满意的。当它最终问世时,已经有了创建和解决迷宫的成熟技术,这可能是每个计算机科学专业本科生都知道的。事实上,网络上充斥着学生们在互联网上发布家庭作业的有据可查的例子。但当然。。。图形和迷宫是一回事,至少在某种意义上是一样的。需要注意的是,迷宫的表面复杂性不应该用肉眼来判断,而应该用肉眼来判断。可以称之为希尔伯特迷宫。(要查看该示例的所有精彩之处,请选中“迷宫”并继续单击下面的小程序。)


此小程序需要Sun的Java VM 2,您的浏览器可能会将其视为弹出窗口。事实并非如此。如果您想看到小程序的工作,请访问Sun的网站:https://www.java.com/en/download/index.jsp,下载并安装Java VM并使用小程序。


作为一个图表,希尔伯特的迷宫是微不足道的。只有两个顶点 图表由单个连接边缘,后者是著名的平面填充曲线的正则近似。类似的观察结果适用于皮亚诺迷宫,尽管有272其中之一。奇怪的是,许多历史迷宫[杜德尼,加德纳,劳斯·鲍尔]都是这样的。这条小路蜿蜒曲折,从入口到出口的路程很长,但不用担心——在树篱中是不会迷路的。(然而,关于皮亚诺和希尔伯特的迷宫,人们可能会考虑限制迷宫的特性。路径仍然在那里,但通道太窄,挤不过去。如果可以的话,这将是一段漫长而可怕的旅程。这一情况值得芝诺注意。)

在复杂性上仅次于琐碎的迷宫是由。树是从每个顶点到任何其他顶点都有一条路径的图。任何有联系的图形具有生成树也就是说,一棵树子图具有完全相同的顶点,但只有一些边。

有几种算法可以从给定的图中提取生成树。下面的小程序实现了其中两个。两者都有Prim的Kruskal的算法于1956年出版。两者都是迭代的,并举例说明了贪婪策略,但方式不同。Prim的算法从一个顶点开始生长一棵树,这是最简单的树。在每次迭代时,它都会向现有的树中添加一个分支——一个顶点和一条边,将顶点连接到树上,这样生成的图形仍然是一棵树。为此,顶点不是从树上的顶点集中选择的,而是通过至少一条边直接连接到树上的。自然,每次迭代都会更新候选顶点集[列维京第305-309页]。

克鲁斯卡尔算法从所有顶点集和空边集开始。在每次迭代中,都会向集合中添加一条边。此过程中的唯一限制是添加边不应创建电路,一个路径以相同的顶点开始和结束。(设计了简单的结构和算法来加速验证,参见[列维京第314-317页)

事实上,情况比刚才描述的要复杂一些。两种算法都适用于权图,其中为每条边指定了权重。算法包括贪婪的在每次迭代中,他们从可用集中选择一条权重最小的边。生成的树称为最小生成树。(如果没有权重,产生的迷宫就没有吸引力。小程序几乎是随机分配权重的。)归纳法的简单证明表明算法确实有效。

解决迷宫的标准方法之一是深度优先搜索[列维京技术:从一个节点沿着一条路径走,直到到达一个死胡同。退回路径,直到第一次有机会检查另一个节点。从那里继续。重复该过程,直到访问完所有节点。

下面的小程序有四个选项卡-定义网格、定义形状、创建迷宫和求解迷宫。起点是尺寸范围为2到50的矩形网格。网格的形状可以通过删除一些顶点、将一些删除的顶点放回原处以及选择开始(蓝色)和结束(红色)顶点来更改。无论如何,必须单击顶点。如前所述,要创建迷宫,您可以选择Prim和Kruskal的算法。您可以通过单击“一步一步”按钮来观察它们的工作,或者使用“一步”键一次执行一步。您还可以观看迷宫的求解或一次执行一步(深度优先算法)。


此小程序需要Sun的Java VM 2,您的浏览器可能会将其视为弹出窗口。事实并非如此。如果您想看到小程序的工作,请访问Sun的网站:https://www.java.com/en/download/index.jsp,下载并安装Java VM并使用小程序。


英语单词“maze”,只有在14第个世纪与道路网络联系在一起[施瓦茨曼]与更长的形式“amaze”有关。古时候有这样的说法[杜德尼惊愕意味着“陷入沉思”,这可能会在迷宫中自然发生一次。如今,当我们面临困境时,“迷宫”这个词仍然会浮现在我们的脑海中。“惊奇”一词现在有了不同的含义。参考这个词后来的、现在的习惯用法,一旦“你知道怎么做”,事情就变得很简单了,这当然令人惊讶

工具书类

  1. H.E.Dudeney,数学中的乐趣1970年,多佛
  2. M.加德纳,第二本科学美国人的数学困惑与转移书芝加哥大学出版社,1987年
  3. A.莱维汀,算法的设计与分析,Addison Wesley,2003年
  4. W.W.Rouse Ball和H.S.M.Coxeter,数学娱乐和论文1987年,多佛
  5. S.Schwartzman,数学词汇,1994年5月

|联系人| |首页| |目录| |几何图形|

版权所有©1996-2018亚历山大·博戈莫尼

Prim和Kruskal的算法确实有效。

证明的基础首先是最小生成树的存在性。任何连通图都有生成树的子图。事实上,如果给定的连通图本身不是树,那么它就有一个回路。从图中删除此回路中的任何边都会使其与相同的顶点相连,但边更少。如果在这个阶段,剩下的图是一棵树,我们可以停止。否则,边缘去除过程将继续。但是,由于边的数量是有限的,它不可能永远持续下去。如果|S|表示集合S中的元素数,则当|V|=|E|+1,因为,正如很容易看到的那样,这个属性是树的特征:对于连通图|V|=|E|+1,移除任何边都会使其断开连接。

对于加权图,生成树的数量,无论多大,都是有限的。因此,在给定图的所有生成树中,存在可能具有最小权重的树。

现在让我们来看一下这两个算法实现了承诺的证明,即每个算法都会导致给定图的最小生成树。将给定图的顶点集表示为V,将其边集表示为E和E表示在i上聚集的顶点集和边集第个任一算法的步骤。我们给他们打电话<V,E> 可接受的如果它可以包含在最小生成树中。我们必须证明,在每一步,算法都会产生一个可接受的对。什么时候?|E类n个|+1=|V|,图一定是一棵树,它包含给定图的所有顶点,因此,它是它的生成树。

由于这两个算法的证明非常相似,我将把它们安排在两列中。证据由归纳.

普林演算法 克鲁斯卡尔算法
在算法的每一步上,我们都有一组由边连接的顶点,这样它们形成的图就是一棵树。  在算法的每一步,我们都有一组边,这样它们形成的图形是无回路的。
让V0由单个顶点(起点)和E组成0为空。  V(V)0=V和E0为空。
由于存在最小生成树,<V0,E0>是可接受的对。  由于存在最小生成树,<V,E0>是可以接受的一对。
假设这对<Vk个,Ek个>在k上生成第个步骤可以接受。为了完成证明,我们将展示这对<Vk+1(千分之一),Ek+1(千分之一)>也是可以接受的。  假设这对<V、Ek个>在k上生成第个步骤可以接受。为了完成证明,我们将展示这对<V、Ek+1(千分之一)>也是可以接受的。
相反,假设<Vk+1(千分之一),Ek+1(千分之一)>不可接受。  相反,假设<V、Ek+1(千分之一)>不可接受。
假设存在最小生成树<V,F>带Ek个F的子集。假设ek+1(千分之一)是Prim算法在(k+1)上选择的边标准步骤。相邻ek+1(千分之一)到F一定会产生一个电路。  假设存在最小生成树<V,F>带Ek个F的子集。假设ek+1(千分之一)是Kruskal算法在(k+1)上选择的边标准步骤。相邻ek+1(千分之一)到F一定会产生一个电路。
这意味着存在另一条边e,其权重至少为ek+1(千分之一)将其从F中删除将留下一棵树<V,F-{e}+{ek+1(千分之一)}>.后者的权重不能超过最小生成树的权重<V,F>因此,它也是最小生成树,但与我们的假设相矛盾的是,它的边集包含Ek+1(千分之一).  这意味着存在另一条边e,其权重至少为ek+1(千分之一)将其从F中删除将留下一棵树<V,F-{e}+{ek+1(千分之一)}>.后者的权重不能超过最小生成树的权重<V,F>因此,它也是最小生成树,但与我们的假设相矛盾的是,它的边集包含Ek+1(千分之一).

|联系人| |首页| |目录| |几何图形|

版权所有©1996-2018亚历山大·博戈莫尼

71882781