Transitive Closure算法笔记

2023-10-17 13:58

本文主要是介绍Transitive Closure算法笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

楔子

把一張圖想像成道路地圖,把圖上的點想像成地點,把圖上的邊想像成道路。現在我們在意的是:由某一點開始,走過 N 條道路後,可以到達哪些點?

最簡單的莫過於走過零條道路的情況了,哪裡都去不了。至於走過一條道路的情況,可以到達起點附近的點。

【註:讀過 Shortest Path 章節的讀者,應該很快就會聯想到:由一點到另一點最少需要走過幾條道路。但是這和此處所言不同。】

 N 很大時,各位可能會想到用 Graph Traversal來試試看──可是路線是環的話就沒轍了。環經過同一個點很多次,而 Graph Traversal 只能拜訪一個點一次。

Transitive Closure

中文譯作「遞移閉包」。一張圖的 Transitive Closure 是一張圖,用來紀錄由一點能不能走到另一點的關係,如果能走到,則兩點之間以邊相連。

要找出一張圖的 Transitive Closure ,也就是要找出圖上每一個點,走過一條、兩條、…… 、無限多條道路之後,會到達圖上哪些點。

然而,一張圖上最多只有 V 個點,要從一點走到另一點,走 V-1 條道路之內一定到得了,否則不論走多少條都一定到不了。另外還要考慮從一點走過 V 個邊回到原點的情況(經過圖上所有點的環)。

因此,要找出一張圖的 Transitive Closure ,只要找出圖上每一個點,走過一條、兩條、……  V 條道路之後,會到達圖上哪些點就可以了。

Transitive Closure: 一個普通的演算法

經過其他點

有個簡單的想法:如果一張圖上,由 i 點可以走到某一個 k 點、這個 k 點又可以走到 j 點,那麼就可以由 i點走到 j 點。

窮舉所有可能的 k 點,就可以判斷出由 i 點到 j 點是否相通了!

只要再計算一下圖上每一個 i 點和每一個 j 點,就可以判斷出圖上各點是否相通了。不過這樣只能找出走過兩條道路的情況。

p2(i, j) = p1(i, 0) && p1(0, j) || ... || p1(i, 9) && p1(9, j)pN(i, j):由i點能不能走到j點。N是走過的道路數目。

兩條加一條就是三條,三條加一條就是四條。走過三條道路、走過四條道路等等的情況,可以以逐次加一條道路的方式,慢慢累積而得。

pN+1(i, j) = pN(i, 0) && p1(0, j) || ... || pN(i, 9) && p1(9, j)pN(i, j):由i點能不能走到j點。N是走過的道路數目。

經過其他點 v.s. 矩陣相乘

點到 k 點, k 點到 j 點,窮舉所有 k 點──其實就和矩陣乘法的規則一樣。如果把一張圖儲存成 adjacency matrix ,那麼直接拿這張圖的 adjacency matrix 自己乘上自己,並且把加法改成 OR 運算,乘法改成 AND 運算,相乘的結果就是走過兩條道路的情況了!

同理,走過兩條道路的矩陣,再乘上一次原圖的adjacency matrix ,就會成為走過三條道路的情況。如此一來,若要求走過 N 條道路的情況,就是原圖的adjacency matrix  N 次方。

一個普通的演算法

現在回頭談 Transitive Closure 要怎麼求。既然一張圖的 Transitive Closure 只需要檢查一條、兩條、…… 條道路,所以一張圖的 Transitive Closure 就是此圖的adjacency matrix  1 次方、 2 次方、……  V 次方,然後統統 OR 起來就對了。

時間複雜度

矩陣相乘需要 O(V^3) (還可以更快)。矩陣的 V次方可藉由 Divide and Conquer  O(logV) * O(V^3) = O(logV * V^3) 求得。(請參考本站文件「 Divide and Conquer  Fast Exponentiation 」)

Transitive Closure: Warshall's Algorithm

Warshall's Algorithm

Warshall 不用「走過幾條道路」的觀點來思考,反而是用「中繼點」的觀點來思考:如果一張圖上可以由 i點開始,走過一些中繼點,最後走到 j 點,那麼就可以由 i 點走到 j 點。這和上一個章節的「經過其他點」的概念類似。

中繼點有可能是第 0 點、第 1 點、…… 、等等。中繼點也不見得只有一點。儘管聽起來很複雜,不過Warshall 卻利用 Divide and Conquer ,分割原問題成容易解決的小問題了!

Warshall 把由 i 點到 j 點的路線分成兩種:經過第 0點的、未經過第 0 點的。接著分別遞迴下去,再分為經過第 1 點的、未經過第 1 點的,如此不斷分下去,直到最後一點。

tc(i, j, k) = tc(i, k, k+1) && tc(k, j, k+1) || tc(i, j, k+1)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^經過第k點                    沒有經過第k點tc(i, j ,k):紀錄由i點走不走的到j點,當中繼點遞迴到第k點的時候。

找出一張圖的 Transitive Closure

使用 Dynamic Programming 紀錄每個小問題的答案。另外,由於計算順序以及 OR 運算的關係,造成記憶體可以重複使用,只需要開二維陣列。請見程式碼:

  1. bool map[9][9]; // 一張圖,資料結構為adjacency matrix。
  2. bool tc[9][9];  // Transitive Closure
  3.  
  4. void warshall()
  5. {
  6.     // 先把原圖複製到要進行DP計算的陣列
  7.     for (int i=0i<9i++)
  8.         for (int j=0j<9j++)
  9.             tc[i][j] = map[i][j];
  10.  
  11.     for (int k=0k<9k++) // 嘗試每一個中繼點
  12.         for (int i=0i<9i++) // 計算每一個i點與每一個j點
  13.             for (int j=0j<9j++)
  14.                 if (tc[i][k] && tc[k][j])
  15.                     tc[i][j] = true;
  16. }

徵求練習題。

这篇关于Transitive Closure算法笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/225846

相关文章

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费