关系传递闭包Warshall算法之思想的一种解说

周晓炜
(西安邮电学院计算机系网络0407班  西安  710121)

注:本文已发表在“中国科技论文网”(http://www.kjlw.cn),网址为http://www.kjlw.cn/show2.asp?newsid=763(需注册成为会员才能浏览)

摘要:Warshall算法是求二元关系传递闭包的一种高效的算法。在左孝凌等编著的《离散数学》中提到了该算法,但并未对此算法作出解释,本文对该算法的思想作出一种比较通俗的解说。
关键词:Warshall算法;矩阵;Floyd算法

1、引言

Warshall在1962年提出了一个求关系的传递闭包的有效算法。其具体过程如下,设在n个元素的有限集上关系R的关系矩阵为M:
    (1)置新矩阵A=M;
    (2)置k=1;
    (3)对所有i如果A[i,k]=1,则对j=1..n执行:
                      A[i,j]←A[i,j]∨A[k,j];
    (4)k增1;
    (5)如果k≤n,则转到步骤(3),否则停止。
    所得的矩阵A即为关系R的传递闭包t(R)的关系矩阵。
    在左孝凌等编著的《离散数学》中提到了该算法,但并未对此算法作出解释。下面本文将对该算法的思想作出一种比较通俗的解说。

2、对Warshall算法的解说

设关系R的关系图为G,设图G的所有顶点为v1,v2,…,vn,则t(R)的关系图可用该方法得到:若G中任意两顶点vi和vj之间有一条路径且没有vi到vj的弧,则在图G中增加一条从vi到vj的弧,将这样改造后的图记为G’,则G’即为t(R)的关系图。G’的邻接矩阵A应满足:若图G中存在从vi到vj路径,即vi与vj连通,则A[i,j]=1,否则A[i,j]=0。
   
    这样,求t(R)的问题就变为求图G中每一对顶点间是否连通的问题。
   
    定义一个n阶方阵序列A(0),A(1),A(2),…,A(n),每个方阵中的元素值只能取0或1。A(m)[i,j]=1表示存在从vi到vj且中间顶点序号不大于m的路径(m=1..n),A(m)[i,j]=0表示不存在这样的路径。而A(0)[i,j]=1表示存在从vi到vj的弧,A(0)[i,j]=0表示不存在从vi到vj的弧。
   
    这样,A(n)[i,j]=1表示vi与vj连通,A(n)[i,j]=0表示vi与vj不连通。故A(n)即为t(R)的关系矩阵。
   
    那么应如何计算方阵序列A(0),A(1),A(2),…,A(n)呢?
   
    很显然,A(0)=M(M为R的关系矩阵)。
   
    若A(0)[i,1]=1且A(0)[1,j]=1,或A(0)[i,j]=1,当且仅当存在从vi到vj且中间顶点序号不大于1的路径,此时应将A(1)[i,j]置为1,否则置为0。
   
    一般地,若A(k-1)[i,k]=1且A(k-1)[k,j]=1,或A(k-1)[i,j]=1,当且仅当存在从vi到vj且中间顶点序号不大于k的路径,此时应将A(k)[i,j]置为1,否则置为0(k=1..n)。用公式表示即为:
    (k)[i,j]=(A(k-1)[i,k]∧A(k-1)[k,j])∨A(k-1)[i,j]  i,j,k=1..n
   
    这样,就可得计算A(k)的方法:先将A(k)赋为A(k-1);再对所有i=1..n,若A(k)[i,k]=1(即A(k-1)[i,k]=1),则对所有j=1..n,执行:
    (k)[i,j]←A(k)[i,j]∨A(k-1)[k,j]
   
    但这与前述Warshall算法中的第(3)步还有一定距离。若将上式改为:
    A(k)[i,j]←A(k)[i,j]∨A(k)[k,j]  (即把A(k-1)[k,j]改为A(k)[k,j])
   
    就可将上标k去掉,式子就可进一步变为:
    A[i,j]←A[i,j]∨A[k,j]
   
    这样可以只用存储一个n阶方阵的空间完成计算,且与前述Warshall算法中第(3)步的式子一致。那么,可不可以把A(k-1)[k,j]改为A(k)[k,j]呢?答案是肯定的。下面将证明在计算A(k)的过程中A(k-1)[k,j]与A(k)[k,j]相等(A(k)被赋初值A(k-1)后)。考察计算A(k)的方法 只有当i=k时A(k)[k,j]的值才有可能改变,此时将式A(k)[i,j]←A(k)[i,j]∨A(k-1)[k,j]中的i换为k,得A(k)[k,j]←A(k)[k,j]∨A(k-1)[k,j],对某一j,执行该式的赋值操作前A(k)[k,j]=A(k-1)[k,j],因为计算A(k)开始时A(k)被赋为A(k-1),故它们相或的结果等于A(k-1)[k,j],故赋值操作不改变A(k)[k,j]的值。这样,就没有操作会改变A(k)[k,j]的值,故A(k-1)[k,j]与A(k)[k,j]相等。
   
    综上,就可得到计算A(n)的算法,且该算法与前述的Warshall算法完全一致。
   
    由上面的分析,不难看出,Warshall算法类似于求图中每对顶点间最短路径的Floyd算法。其实,用Floyd算法也能求关系的传递闭包,方法为令关系R的关系图G中的每条弧的权值都为1,这样得一有向网G1,设G1的邻接矩阵为D(-1)(若vi无自回路,则D(-1)(i,i)=∞),对G1用Floyd算法求其每对顶点间最短路径,得结果矩阵D(n-1)。因若G中vi与vj连通,当且仅当D(n-1)[i,j]≠∞,故将矩阵D中的∞都改为0,其它值都改为1,得矩阵A,则矩阵A即为t(R)的关系矩阵。Floyd算法和Warshall算法的时间复杂度都为O(n3),但明显用Floyd算法求关系的传递闭包绕了弯子。

参考文献:

[1]左孝凌,李为鑑,刘永才,《离散数学》,上海:上海科学技术文献出版社,1982

[2]严蔚敏,吴伟民,《数据结构 C语言版》,北京:清华大学出版社,1997

关系传递闭包Warshall算法之思想的一种解说相关推荐

  1. 离散数学 传递闭包 Warshall算法

    老师布置一个作业,要写Warshall算法课后,这里给写出来了. 这个算法本身很简单,倒是学习了一下参数为二维数组的传递方法,正确代码如下: /* Warshall算法 */ #include < ...

  2. WarShall算法求矩阵传递闭包关系

    离散知识 给了你一个矩阵,你如何求他的传递闭包呢? //求出如下矩阵的传递闭包 1 0 1 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 利用WarShall ...

  3. Warshall算法求有向图的传递闭包

    1定义是这样给出的,传递闭包:对于任何关系 R,R 的传递闭包总是存在的.传递关系的任何家族的交集也是传递的.进一步的,至少存在一个包含 R 的传递关系,也就是平凡的: X × X.R 传递闭包给出自 ...

  4. C语言用warshall算法求传递闭包transitive closure(附完整源码)

    用warshall算法求传递闭包transitive closure warshall算法求传递闭包完整源码 warshall算法求传递闭包完整源码 #include <stdbool.h> ...

  5. WarShall算法求传递闭包(可达矩阵)

    最近在复习离散数学,顺便记录记录自己对warshall算法的理解. 1.传递闭包(可达矩阵) 传递闭包是有向图的一个重要性质,它指的是在有向图中从任意一个节点出发,可以到达的所有节点的集合.在某些应用 ...

  6. Warshall 算法(离散数学传递闭包)

    Warshall 算法 算法思路: (1)先初始化一个二维数组 (2)利用循环输入N*N的矩阵 (3)进行矩阵的运算 M0的第0列的1和第0行进行逻辑加.比如[1,0]+[0,1]=[1,1]=1 M ...

  7. War-shall 算法 【求传递闭包】 离散数学记录

    学离散数学时遇到到第一个算法,记录一下: 代码思路: warshall(A[1...n,1...n] r(0)<-A; for(k=1;k<=n;k++)for(i=1;i<=n;i ...

  8. 浅谈Warshall算法

    Warshall算法 ​ 今天的离散数学课后作业里有需要求传递闭包的题目,不懂上课没听,本来想用matlab偷一下懒,但是搜到了Warshall算法,故参考百科及其它博客后写水篇博客. 传递性 ​ 了 ...

  9. 离散复习资料之一(Warshall算法)

    我们先对R(n)进行解释一下,不然你们看不太懂. 就是R(n)表示,通过从 1...n 个点绕到到达所求点,注意原来的位置的点,发生改变的就是刚才的含义去解释. 给一个例子解释一下. 其中的R(i). ...

  10. 基于Warshall算法的连通图及欧拉图判定方法

    1736年欧拉解决了哥尼斯堡七桥问题.他在这一具体问题的基础上进一步研究,最终找到了一个简便的原则可以鉴别一个图(多重图)能否一笔画成. 本文中,笔者使用布尔矩阵来存储一个无向图,并结合集合论中&qu ...

最新文章

  1. python中 pip的安装方法
  2. 双系统 win10 时间不对
  3. Java中正则Matcher类的matches()、lookAt()和find()的差别
  4. .net core dll 套壳加密_BCVP开发者说第4期:Remember.Core
  5. DM365 dvsdk_2_10_01_18开发环境搭建
  6. Python爬虫实战之(五)| 模拟登录wechat
  7. linux 命令下删除字符,【Linux基础】tr命令替换和删除字符
  8. android 字符串 转公式,java – 在android中将字符串转换为bigdecimal
  9. SpringMVC 应用配置
  10. 小心Lombok用法中的坑
  11. Python列表常用函数使用详解(内附详细案例)
  12. (25)软件工程开发规范
  13. 神奇的数字之回文数c语言,奇妙的数字
  14. 计算机配置35%卡住不动了,win7配置更新35%不动怎么办
  15. 学习笔记:数据分析之上海一卡通乘客刷卡数据分析
  16. 中国工程师如何获 Google 的工作机会?
  17. ps如何快速消除黑眼圈或者眼袋
  18. 安卓自定义布局显示流式搜索记录
  19. 在JavaScript实现基于原型的继承
  20. 图像自动裁剪和角度矫正

热门文章

  1. 年度最强浏览器插件来袭,打造个人完美生产力
  2. Java实现UDP功能
  3. 《图书管理系统》—需求分析报告
  4. python的unicode编码表_Python-编码
  5. Excel 数据透视表入门教程
  6. 几种RIA技术(富互联网应用程序)比较
  7. 如何获取网络标准时间
  8. 国际版(英文版)Skype使用国内卡打电话(转)
  9. 去掉txt文本某些字符
  10. Android实战开发小米主题下载工具