【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法
Graph Search and Connectivity
Generic Graph Search
Goals 1. find everything findable
2. don't explore anything twice
Generic Algorithm (given graph G, vertex S)
--- initialize S explored (all others unexplored)
--- while possible:
--- choose an edge(u, v) with u explored and v unexplored
--- mark v explored
1. Breadth-First Search (BFS) O(m+n) time using a queue
--- explore nodes in 'layers'
--- can compute shortest paths
--- can compute connected components of an undirected graph
The basics:pseudocode
BFS(Graph G, start vertex s)
(all nodes initially unexplored)
mark s as explored
let Q = queue data structure(FIFO), initialized with s
while Q != 0:
remove the first node of Q, call it v
for each edge(v, w):
if w unexplored
mark w as explored
add into Q (at the end)
Shortest Paths:
Goal: compute dist(v), the fewest # of edges on a path from s to v
Extra code:
initialize dist(v) = 0 if v == s
when considering edge(v, w):
if w unexplored then set dist(w) = dist(v) + 1
claim: at termination, dist(v) = i <=> v in ith layer
Undirected Connectivity
let G = (V, E) be an undirected graph
Connected components == the 'pieces' of G
Goal: compute all connected components(why? check if network is disconnected, graph visualization, clustering, similarity)
all nodes unexplored
(assume labelled 1 to n)
for i = 1 to n
if i not yet explored
BFS(G, i) //discovers precisely i's connected components
2. Depth-First Search (DFS) O(m+n) time using a stack
--- explore aggressively like a maze, backtrack only when necessary
--- compute topological ordering of directed acycle graph(DAG)
--- compute connected components in directed graphs
pseudocode:
use a stack instead of a queue
recursive version:
DFS(Graph G, start vertex s)
mark s as explored
for every edge(s,v)
if v unexplored
DFS(G,v)
Application: Topological Sort (DAG)
Definition: A topological ordering of a directed graph G is a labelling f of G's node's such that:
1. the f(v)'s are the set{1,2,...,n}
2. (u,v) => f(u) < f(v)
note that if G has directed cycle => no topological ordering
Straightforward solution to Topological Sort
note: every directed acyclic graph has a sink vertex(入度为0的node,无前驱)
To compute topological ordering:
let v be a sink vertex of G
set f(v) = n
recurse on G - {v}
(1) 从有向图中选一个没有前驱的顶点
(2) 从图中删去该点,并删去从该点出发的所有边
(3) 重复上两步,直到图中再没有有前驱的点为止
Topological Sort via DFS
DFS(G, s)
mark s explored
for every edge(s, v)
if v not yet explored
DFS(G, v)
set f(s) = current_label
current_label --
DFS-loop(Graph G)
mark all node unexplored
current_label = n
for each vertex v:
if v unexplored
DFS(G, v)
3. Computing Strong Components: The Algorithm
Strongly connected Components
Formal Definition: the strongly connected Components(SCCs) of a directed graph G are the equivalance classes of the relation:
u~v <=> u ->v and v -> u in G
Kosaraju's Two-Pass Algorithm 2*DFS = O(m+n)
1. let Gr = G with all arcs reversed
2. run DFS-loop on Gr <---------- Goal: compute 'magical ordering' of nodes
let f(v) = 'finishing time' of each v
3. run DFS-loop on G <---------- Goal: discover the SCCs one-by-one
processing nodes in decreasing order of finishing times
SCCs = nodes with the same 'leader'
pseudocode:
DFS(G, i)
make i as explored
set leader(i) = node s
for each arc(i, j):
if j not yet explored:
DFS(G, j)
t++
set f(i) = t // i's finishing time
DFS-loop(Graph G)
global variable t = 0 // # of nodes pressed so far (for finishing times in 1st pass)
global variable s = Null // current source vertex (for leaders in 2nd pass)
Assume nodes labelled 1 to n
for i = n down to 1
if i not yet explored
s = i
DFS(G, i)
Python Code:
import sys
import threading
import copy threading.stack_size(67108864)
sys.setrecursionlimit(300000) def DFS(edges, i, index):
global t, vertices, new_vertices, s, compare
if index == 1: # 1st pass
vertices[i-1][1] = True # mark it explored
if index == 2: # 2nd pass
vertices[compare[i]-1][1] = True
vertices[compare[i]-1].append(s) # set leader(i) = node s
if i in edges:
for v in edges[i]:
if index == 1:
if vertices[v-1][1] == False:
DFS(edges, vertices[v-1][0], index)
if index == 2:
if vertices[compare[v]-1][1] == False:
DFS(edges, vertices[compare[v]-1][0], index) if index == 1:
t = t + 1 # i's finishing time
vertices[i-1].append(t)
temp = vertices[i-1].copy()
temp[1] = False
new_vertices.append(temp)
compare[vertices[i-1][0]] = t def DFS_loop(edges, index):
global t, vertices, new_vertices, s
t = 0 #for finishing times in 1st pass
n = len(vertices)
for i in range(1, n+1):
v = vertices[n-i]
if v[1] == False:
s = v[0]
DFS(edges, v[0], index) def main():
global vertices, new_vertices, compare
f = open('SCC.txt')
_f = list(f)
vertices = list() #[number, False] false indicates unexplored
new_vertices = list() #[number, False, t, s]
edges = dict() # {1:[2,5,6...]...}
edges_rev = dict() # {2:[8,9,5...]...}
compare = dict()
for i in range(0, 875714): #875714 initialize V
vertices.append([i+1, False])
for edge in _f: # initialize E
temp = edge.split()
edge_temp = [int(temp[0]), int(temp[1])]
edge_rev_temp = [edge_temp[1], edge_temp[0]]
if edge_temp[0] not in edges:
edges[edge_temp[0]] = [edge_temp[1]]
else:
edges[edge_temp[0]].append(edge_temp[1])
if edge_rev_temp[0] not in edges_rev:
edges_rev[edge_rev_temp[0]] = [edge_rev_temp[1]]
else:
edges_rev[edge_rev_temp[0]].append(edge_rev_temp[1]) DFS_loop(edges_rev, 1)
vertices = copy.deepcopy(new_vertices)
DFS_loop(edges, 2) result = dict()
for item in vertices: # nodes with the same 'leader'
if item[3] not in result:
result[item[3]] = 1
else:
result[item[3]] = result[item[3]] + 1 r = list() #output the sizes of the 10 largest SCCs
for key in result:
r.append(result[key])
r = sorted(r, reverse = True)
print(r[0:9]) if __name__ == '__main__':
thread = threading.Thread(target = main)
thread. start()
【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法的更多相关文章
- python 实现图的深度优先和广度优先搜索
在介绍 python 实现图的深度优先和广度优先搜索前,我们先来了解下什么是"图". 1 一些定义 顶点 顶点(也称为"节点")是图的基本部分.它可以有一个名称 ...
- C语言数据结构与算法之深度、广度优先搜索
一.深度优先搜索(Depth-First-Search 简称:DFS) 1.1 遍历过程: (1)从图中某个顶点v出发,访问v. (2)找出刚才第一个被顶点访问的邻接点.访问该顶点.以这个顶点为新的顶 ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 基于visual Studio2013解决算法导论之046广度优先搜索
题目 广度优先搜索 解决代码及点评 // 图的邻接表表示.cpp : 定义控制台应用程序的入口点. // #include <iostream> #include <stac ...
- 算法学习记录-图——应用之拓扑排序(Topological Sort)
这一篇写有向无环图及其它的应用: 清楚概念: 有向无环图(DAG):一个无环的有向图.通俗的讲就是从一个点沿着有向边出发,无论怎么遍历都不会回到出发点上. 有向无环图是描述一项工程或者系统的进行过程的 ...
- 有向图的强联通tarjan算法(判断是否为强联通模板)(hdu1269)
hdu1269 迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法
强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...
- POJ 3180-The Cow Prom (图论-有向图强联通tarjan算法)
题目大意:有n个牛在一块, m条单项绳子, 有m个链接关系, 问有多少个团体内部任意两头牛可以相互可达 解题思路:有向图强连通分量模版图 代码如下: #include<stdio.h> # ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
随机推荐
- Android Log介绍
android.util.Log常用的方法有以下5个:Log.v() ,Log.d() ,Log.i() ,Log.w() ,Log.e() .按照日志级别从高到低为ERROR, WARN, INFO ...
- JavaScript parseInt() toString()函数
parseInt(string, radix) string:必需.要被解析的字符串 radix:可选.表示要解析的数字的基数.该值介于 2 ~ 36 之间. 如果省略该参数或其值为 0,则数字将以 ...
- Odoo10尝鲜: 退货
Odoo sale / purchase 在 v9 改进之后, 开立发票的入口 不再像之前的版本,有多个来源,例如 订单 交货单 记工单 分析分录 现在只有一个入口,只需要在 订单上开票,这样 ...
- 关于collapsed margin(外边距合并)
这是前面写postion定位时写到最后面的例子的时候发现的一个问题,于是专门写一篇随笔来解释记录一下,毕竟两个知识点同时写在一篇文章里面有点混乱的感觉.. 上篇随笔position定位遇到的问题在这里 ...
- nodejs:csv模块解析
Nodejs最大的特点就是基于事件驱动和异步并发操作.大多数人知道nodejs是用于网络后台服务的新平台,可以很方便的提供后台服务:除了用于网络开发外,其实nodejs对于线下文件并发处理也是很方便的 ...
- node四大优势 转
1. Nodejs基于Javascript语言,不用再单独新学一门陌生的语言,从而减低了学习的门槛.同时,Javascript语言在Web前端开发中至关重要,特别HTML5的应用必须要使用,所以前后台 ...
- 【03_136】Single Number
感谢:http://www.cnblogs.com/changchengxiao/p/3413294.html Single Number Total Accepted: 103007 Total S ...
- postgresql 配置文件优化
postgresql 配置文件优化 配置文件 默认的配置配置文件是保存在/etc/postgresql/VERSION/main目录下的postgresql.conf文件 如果想查看参数修改是否生效, ...
- OkHttp使用介绍
版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4001708.html 为什么需要一个HTTP库 Androi ...
- [ASE][Daily Scrum]11.26
今天主要是修复一些历史遗留问题以及bug, 在task上进展不是很明显, 在地图与客户端同步之后产生了一些bug,例如一发子弹会消掉很多砖块,服务器地图与本地地图不同步等等... 目前的大方向分工是这 ...