• 沒有找到結果。

Data structure and algorithm in Python Graph

N/A
N/A
Protected

Academic year: 2021

Share "Data structure and algorithm in Python Graph"

Copied!
82
0
0

加載中.... (立即查看全文)

全文

(1)

Data structure and algorithm in Python

Graph

Xiaoping Zhang

School of Mathematics and Statistics, Wuhan University

(2)

Table of contents

1. Graphs

2. Data Structures for Graphs

3. Graph Traversals

(3)

Graphs

(4)

Graphs

Example : Graphs

A graph G is simply a set V of verticesand a collection E of pairs of vertices from V , called edges. A graph is a way of representing connections or relationships between pairs of objects from some set V.

(5)

Graphs

Edges in a graph are either directed or undirected.

• An edge (u,v ) is said to bedirected from u to v if the pair (u,v ) is ordered, with u preceding v .

• An edge (u,v ) is said to beundirectedif the pair (u,v ) is not ordered.

Undirected edges are sometimes denoted with set notation, as{u,v}, but for simplicity we use the pair notation (u,v ), noting that in the

undirected case (u,v ) is the same as (v,u).

3

(6)

Graphs

Definition : undirected, directed and mixed graph

• If all the edges in a graph are undirected, then we say the graph is an undirected graph.

• Likewise, a directed graph, also called a digraph, is a graph whose edges are all directed.

• A graph that has both directed and undirected edges is often called a mixed graph.

An undirected or mixed graph can be converted into a directed graph by replacing every undirected edge (u,v ) by the pair of directed edges (u,v ) and (v,u).

(7)

Graphs

• The two vertices joined by an edge are called theend vertices (or endpoints)of the edge.

• If an edge is directed, its first endpoint is its originand the other is thedestinationof the edge.

• Two vertices u and v are said to beadjacentif there is an edge whose end vertices are u and v .

5

(8)

Graphs

• An edge is said to be incident to a vertex(关联于某顶点)if the vertex is one of the edge’s endpoints.

• Theoutgoing edges(出边)of a vertex are the directed edges whose origin is that vertex.

• Theincoming edges(入边)of a vertex are the directed edges whose destination is that vertex.

(9)

Graphs

• Thedegree(度)of a vertex v , denoteddeg (v ), is the number of incident edges of v .

• Thein-degree(入度)andout-degree(出度)of a vertex v are the number of the incoming and outgoing edges of v , and are denoted indeg (v )andoutdeg (v ), respectively.

7

(10)

Graphs

• The definition of a graph refers to the group of edges as acollection, not a set, thus allowing two undirected edges to have the same end vertices, and for two directed edges to have the same origin and the same destination. Such edges are calledparallel edges(平行边)or multiple edges(多重边).

• Another special type of edge is one that connects a vertex to itself.

Namely, we say that an edge (undirected or directed) is aring(环) or a self-loop(自回路)if its two endpoints coincide.

(11)

Graphs

• With few exceptions, graphs do not have parallel edges or self-loops.

Such graphs are said to besimple.

• Thus, we can usually say that the edges of asimple graph(简单图) area set of vertex pairs(and not just a collection).

Throughout this chapter, we assume that a graph is simple unless otherwise specified.

9

(12)

Graphs

• Apath(路径)is a sequence of alternating vertices and edges that starts at a vertex and ends at a vertex such that each edge is incident to its predecessor and successor vertex.

• Acycle(环路)is a path that starts and ends at the same vertex, and that includes at least one edge.

1. A path is simple (简单路径)if each vertex in the path is distinct.

2. A cycle is simple (简单环路)if each vertex in the cycle is distinct, except for the first and last one.

3. A directed path is a path such that all edges are directed and are traversed along their direction.

4. A directed cycle is similarly defined.

(13)

Graphs

• A directed graph isacyclic(无环)if it has no directed cycles.

• If a graph is simple, we may omit the edges when describing path P or cycle C , as these are well defined, in which case P is a list of adjacent vertices and C is a cycle of adjacent vertices.

11

(14)

Graphs

• Given vertices u and v of a (directed) graph G , we say thatu reaches v (u 到达 v ), and thatv is reachable from u (v 可从 u 到 达), if G has a (directed) path from u to v .

• In an undirected graph, the notion of reachability is symmetric, that is to say, u reaches v if an only if v reaches u.

• However, in a directed graph, it is possible that u reaches v but v does not reach u, because a directed path must be traversed according to the respective directions of the edges.

(15)

• A graph isconnected(连通)if, for any two vertices, there is a path between them (任意两顶点间都存在路径).

• A directed graphG isstrongly connected(强连通)if for any two vertices u and v ofG , u reaches v and v reaches u.

13

(16)

• Asubgraph(子图)of a graph G is a graph H whose vertices and edges are subsets of the vertices and edges of G , respectively.

• Aspanning subgraph(生成子图)of G is a subgraph of G that contains all the verticesof the graph G .

• If a graph G is not connected, itsmaximal connected subgraphs(最 大连通子图)are called theconnected components(连通分支)of G .

• Aforest(森林)is a graph without cycles.

• Atree(树) is a connected forest, that is, a connected graph without cycles.

• Aspanning tree(生成树)of a graph is a spanning subgraph that is a tree.

(17)

Graphs

Proposition

If G is a graph with m edges and vertex setV , then

v∈V

deg (v )=2m.

15

(18)

Graphs

Proposition

If G is a directed graph with m edges and vertex set V , then

v∈V

indeg (v )=

v∈V

outdeg (v )=m.

(19)

Graphs

Proposition

Let G be a simple graph with n vertices and m edges.

• If G is undirected, then

mn(n1) 2

• If G is directed, then

mn(n1).

17

(20)

Graphs

Proposition

Let G be a undirected graph with n vertices and m edges.

• If G is connected, then

mn1.

• If G is a tree, then

m=n1.

• If G is a forest, then

mn1.

(21)

Graphs

The Graph ADT

(22)

The Graph ADT

Since a graph is a collection of vertices and edges, we model the abstraction as a com- bination of three data types:

• Vertex

• Edge

• Graph

(23)

The Graph ADT

AVeretexis lightweight object that stores an arbitrary element provided by the user, supporting the method:

• element(): Retrieve the stored element.

20

(24)

The Graph ADT

AnEdgestores an associated object, supporting the following methods:

• element(): Retrieve the stored element.

• endpoints(): Return a tuple (u,v ) such that vertex u is the origin of the edge and vertex v is the destination; for an undirected graph, the orientation is arbitrary.

• opposite(v): Assuming vertex v is one endpoint of the edge (either origin or destination), return the other endpoint.

(25)

The Graph ADT

The primary abstraction for a graph is theGraphADT. We presume that a graph can be either undirected or directed, with the designation declared upon construction; recall that a mixed graph can be represented as a directed graph, modeling edge{u,v}as a pair of directed edges (u,v ) and (v,u).

22

(26)

The Graph ADT

The Graph ADT includes the following methods

• vertex_count(): Return the number of vertices.

• vertices(): Return aniterationof all vertices.

• edge_count(): Return the number of edges.

• edges(): Return aniterationof all edges.

• get_edge(u,v): Return the edge from vertex u to v , if one exists;

otherwise return None.

• degree(v, out=True):

• For an undirected graph, return the number of edges incident to vertex v .

• For a directed graph, return the number of outgoing (resp. incoming) edges incident to vertex v , as designated by the optional parameter.

(27)

The Graph ADT

• incident_edges(v, out=True):

• Return an iteration of all edges incident to vertex v .

• In the case of a directed graph,

• report outgoing edges by default;

• report incoming edges if the optional parameter is set to False.

• insert_vertex(x=None): Create and return a new Vertex storing element x .

• insert_edge(u, v, x=None): Create and return a new Edge from vertex u to vertex v , storing element x (None by default).

• remove_vertex(v): Remove vertex v and all its incident edges from the graph.

• remove_edge(e): Remove edge e from the graph.

24

(28)

Data Structures for Graphs

(29)

Data Structures for Graphs

• Edge List

• Adjacency List

• Adjacency Map

• Adjacency Matrix

25

(30)

Edge List

(31)

Adjacency List

27

(32)

Adjacency Map

(33)

Adjacency Matrix

29

(34)

Data Structures for Graphs

Python Implementation

(35)

Python Implementation

c l a s s G r a p h : c l a s s V e r t e x :

_ _ s l o t s _ _ = ’ _ e l e m e n t ’ def _ _ i n i t _ _ ( self , x ) :

se l f . _ e l e m e n t = x def e l e m e n t ( s e l f ) :

r e t u r n s e l f . _ e l e m e n t def _ _ h a s h _ _ ( s e l f ) :

r e t u r n h a s h(id( s e l f ) ) def _ _ s t r _ _ ( s e l f ) :

r e t u r n str( s e l f . _ e l e m e n t )

30

(36)

Python Implementation

c l a s s Ed g e :

_ _ s l o t s _ _ = ’ _ o r i g i n ’ , ’ _ d e s t i n a t i o n ’ , ’ _ e l e m e n t ’

def _ _ i n i t _ _ ( self , u , v , x ) : se l f . _ o r i g i n = u

se l f . _ d e s t i n a t i o n = v se l f . _ e l e m e n t = x def e n d p o i n t s ( s e l f ) :

r e t u r n ( s e l f . _origin , s e l f . _ d e s t i n a t i o n )

(37)

Python Implementation

def o p p o s i t e ( self , v ) :

if not i s i n s t a n c e( v , G r a p h . V e r t e x ) : r a i s e T y p e E r r o r ( ’ v m u s t be a V e r t e x ’ ) r e t u r n s e l f . _ d e s t i n a t i o n if v is se l f . _ o r i g i n el s e s e l f . _ o r i g i n

r a i s e V a l u e E r r o r ( ’ v not i n c i d e n t to e d g e ’ )

32

(38)

Python Implementation

def e l e m e n t ( s e l f ) : r e t u r n s e l f . _ e l e m e n t def _ _ h a s h _ _ ( s e l f ) :

r e t u r n h a s h( ( s e l f . _origin , s e l f . _ d e s t i n a t i o n ) )

def _ _ s t r _ _ ( s e l f ) :

r e t u r n ’ ( { 0 } , { 1 } , { 2 } ) ’ .f o r m a t( s e l f . _origin , s e l f . _ d e s t i n a t i o n , s e l f . _ e l e m e n t )

(39)

Python Implementation

def _ _ i n i t _ _ ( self , d i r e c t e d = F a l s e ) : s e l f . _ o u t g o i n g = {}

s e l f . _ i n c o m i n g = {} if d i r e c t e d e l s e s e l f . _ o u t g o i n g

def _ v a l i d a t e _ v e r t e x ( self , v ) :

if not i s i n s t a n c e( v , s e l f . V e r t e x ) : r a i s e T y p e E r r o r ( ’ V e r t e x e x p e c t e d ’ ) if v not in se l f . _ o u t g o i n g :

r a i s e V a l u e E r r o r ( ’ V e r t e x d o e s not b e l o n g to t h i s g r a p h . ’ )

34

(40)

Python Implementation

def i s _ d i r e c t e d ( s e l f ) :

r e t u r n s e l f . _ i n c o m i n g is not se l f . _ o u t g o i n g def v e r t e x _ c o u n t ( s e l f ) :

r e t u r n len( s e l f . _ o u t g o i n g )

def v e r t i c e s ( s e l f ) :

r e t u r n s e l f . _ o u t g o i n g . k e y s ()

(41)

Python Implementation

def e d g e _ c o u n t ( s e l f ) :

t o t a l = sum(len( s e l f . _ o u t g o i n g [ v ]) for v in s e l f . _ o u t g o i n g )

r e t u r n t o t a l if se l f . i s _ d i r e c t e d () el s e t o t a l // 2

def e d g e s ( s e l f ) : r e s u l t = set()

for s e c o n d a r y _ m a p in se l f . _ o u t g o i n g . v a l u e s () :

r e s u l t . u p d a t e ( s e c o n d a r y _ m a p . v a l u e s () ) r e t u r n r e s u l t

36

(42)

Python Implementation

def g e t _ e d g e ( self , u , v ) : s e l f . _ v a l i d a t e _ v e r t e x ( u ) s e l f . _ v a l i d a t e _ v e r t e x ( v )

r e t u r n s e l f . _ o u t g o i n g [ u ]. get ( v ) def d e g r e e ( self , v , o u t g o i n g = T r u e ) :

s e l f . _ v a l i d a t e _ v e r t e x ( v )

adj = s e l f . _ o u t g o i n g if o u t g o i n g el s e se l f . _ i n c o m i n g

r e t u r n len( adj [ v ])

(43)

Python Implementation

def i n c i d e n t _ e d g e s ( self , v , o u t g o i n g = T r u e ) : s e l f . _ v a l i d a t e _ v e r t e x ( v )

adj = s e l f . _ o u t g o i n g if o u t g o i n g el s e se l f . _ i n c o m i n g

for ed g e in adj [ v ]. v a l u e s () : y i e l d e d g e

def i n s e r t _ v e r t e x ( self , x = N o n e ) : v = s e l f . V e r t e x ( x )

s e l f . _ o u t g o i n g [ v ] = {}

if s e l f . i s _ d i r e c t e d () : se l f . _ i n c o m i n g [ v ] = {}

r e t u r n v

38

(44)

Python Implementation

def i n s e r t _ e d g e ( self , u , v , x = N o n e ) : if s e l f . g e t _ e d g e ( u , v ) is not N o n e :

r a i s e V a l u e E r r o r ( ’ u and v are a l r e a d y a d j a c e n t ’ )

e = s e l f . E d g e ( u , v , x ) s e l f . _ o u t g o i n g [ u ][ v ] = e s e l f . _ i n c o m i n g [ v ][ u ] = e

(45)

Graph Traversals

(46)

Graph Traversals

Definition : Graph Traversals

A traversal is a systematic procedure for exploring a graph by exam- ining all of its vertices and edges.

A traversal is efficient if it visits all the vertices and edges in time proportional to their number, that is, in linear time.

(47)

Graph Traversals

Definition : Graph Traversals

A traversal is a systematic procedure for exploring a graph by exam- ining all of its vertices and edges.

A traversal is efficient if it visits all the vertices and edges in time proportional to their number, that is, in linear time.

40

(48)

Graph Traversals

Graph traversal algorithms are key to answering many fundamental questions about graphs involving the notion ofreachability, that is, in determining how to travel from one vertex to another while following paths of a graph.

(49)

Graph Traversals

Interesting problems that deal with reachability in anundirected graph G include the following:

• Computing a path from vertex u to vertex v , or reporting that no such path exists.

• Given a start vertex s of G , computing, for every vertex v of G , a path with the minimum number of edges between s and v , or reporting that no such path exists.

• Testing whether G is connected.

• Computing a spanning tree of G , if G is connected.

• Computing the connected components of G .

• Computing a cycle in G , or reporting that G has no cycles.

42

(50)

Graph Traversals

Interesting problems that deal with reachability in a directed graph⃗G include the following:

• Computing a directed path from vertex u to vertex v , or reporting that no such path exists.

• Finding all the vertices of⃗G that are reachable from a given vertex s.

• Determine whether⃗G is acyclic.

• Determine whether⃗G is strongly connected.

(51)

Graph Traversals

Depth-First Search

(52)

Depth-First Search

Depth-first search (DFS)is useful for testing a number of properties of graphs, including whether there is a path from one vertex to another and whether or not a graph is connected.

(53)

Depth-First Search

Procedure of DFS

1. Begin at a specific starting vertex s in G , and set s as “visited”. The vertex s is now our “current” vertex - call our current vertex u.

2. Traverse G by considering an edge (u,v ) incident to the current vertex u.

• If (u,v ) leads to a visited vertex v , ignore that edge.

• If (u,v ) leads to an unvisited vertex v , go to v .

• Set v as “visited”, and make it the current vertex, repeated the computation above.

• Eventually, we will get to a “dead end”, that is, a current vertex v such that all the edges incident to v lead to visited vertices.

• To get out of this impasse(僵局), we backtracking(由原路返回) along the edge that brought to v , going back to a previously visited vertex u.

• We then make u our current vertex and repeat the computation above for any edges incident to u that we have not yet considered.

45

(54)

Depth-First Search

• If all of u’s incident edges lead to visited vertices, then we backtrack to the vertex we came from to get to u, and repeat the procedure at that vertex.

• Thus, we continue to backtrack along the path that we have traced so far until we find a vertex that has yet unexplored edges, take one such edge, and continue the traversal.

• The process terminates when our backtracking leads us back to the start vertex u, and there are no more unexplored edges incident to s.

(55)

Depth-First Search

47

(56)

Depth-First Search

图 1: Example of depth-first search traversal on an undirected graph starting at vertex A. Assume thata vertex’s adjacencies are considered in alphabetical order.

(57)

Depth-First Search

图 2: Example of depth-first search traversal on an undirected graph starting at vertex A. Assume thata vertex’s adjacencies are considered in alphabetical order.

49

(58)

Depth-First Search

图 3: Example of depth-first search traversal on an undirected graph starting at vertex A. Assume thata vertex’s adjacencies are considered in alphabetical

(59)

Properties of DFS

Proposition

Let G be an undirected graph on which a DFS traversal starting at a vertex s has been performed. Then the traversal visits all vertices in theconnected component (连通分支)of s, and the discovery edges form aspanning tree (生成树)of connected component of s.

51

(60)

Properties of DFS

Proposition

Let ⃗G be an directed graph. DFS onG starting at a vertex s visits all the vertices of G that are reachable from s. Also, the DFS tree contains directed paths from s to every vertex reachable from s.

(61)

Graph Traversals

DFS Implementation and Extensions

(62)

DFS Implementation and Extensions

def DFS ( g , u , d i s c o v e r e d ) : for e in g . i n c i d e n t _ e d g e s ( u ) :

v = e . o p p o s i t e ( u )

if v not in d i s c o v e r e d : d i s c o v e r e d [ v ] = e DFS ( g , v , d i s c o v e r e d )

• In order to track which vertices have been visited, and to build a representation of the resulting DFS tree, the implementation introduces a third parameter, named discovered.

• This parameter should be a Python dictionary that maps a vertex to the tree edge that was used to discover that vertex.

(63)

DFS Implementation and Extensions

def DFS ( g , u , d i s c o v e r e d ) : for e in g . i n c i d e n t _ e d g e s ( u ) :

v = e . o p p o s i t e ( u )

if v not in d i s c o v e r e d : d i s c o v e r e d [ v ] = e DFS ( g , v , d i s c o v e r e d )

• In order to track which vertices have been visited, and to build a representation of the resulting DFS tree, the implementation introduces a third parameter, named discovered.

• This parameter should be a Python dictionary that maps a vertex to the tree edge that was used to discover that vertex.

53

(64)

DFS Implementation and Extensions

As a technicality, assume that the source vertex u occurs as a key of the dictionary, with None as its value.

A caller might start the traversal as follows: r e s u l t = { u : N o n e }

DFS ( g , u , r e s u l t )

(65)

DFS Implementation and Extensions

As a technicality, assume that the source vertex u occurs as a key of the dictionary, with None as its value.

A caller might start the traversal as follows:

r e s u l t = { u : N o n e } DFS ( g , u , r e s u l t )

54

(66)

DFS Implementation and Extensions

The dictionary result serves two purposes.

• Internally, the dictionary provides a mechanism for recognizing visited vertices, as they will appear as keys in the dictionary.

• Externally, the DFS function arguments this dictionary as it

proceeds, and thus the values within the dictionary are the DFS tree edges at the conclusion of the process.

(67)

Reconstructing a Path from u to v

We can use the basic DFS function as a tool to identify the (directed) path leading from vertex u to v , if v is reachable from u. This path can easily bereconstructedfrom the information that was recorded in the discovery dictionaryduring the traversal.

56

(68)

Reconstructing a Path from u to v

To reconstruct the path, excecute the following steps:

1. Begin at the end of the path, examining the discovery dictionary to determine what edge was used to reach a vertex v , and then what the other endpoint of that edge is.

2. Add that vertex to a list, and the repeat the process to determine what edge was used to discover it.

3. Once we have traced the path all the way back to the starting vertex u, we can reverse the list so that its is properly oriented from u to v , and return it to the caller.

(69)

Reconstructing a Path from u to v

def c o n s t r u c t _ p a t h ( u , v , d i s c o v e r e d ) : p a t h = []

if v in d i s c o v e r e d : p a t h . a p p e n d ( v ) w a l k = v

w h i l e wa l k is not u : e = d i s c o v e r e d [ w a l k ] p a r e n t = e . o p p o s i t e ( w a l k ) pa t h . a p p e n d ( p a r e n t )

wa l k = p a r e n t p a t h . r e v e r s e () r e t u r n p a t h

58

(70)

Computing all Connected Components

When a graph is not connected, the next goal we may have is to identify all ofconnected components of an undirected graph, or thestrongly connected components of a directed graph.

If an initial call to DFS fails to reach all vertices of a graph, we can restart a new call to DFS at one of those unvisited vertices.

(71)

Computing all Connected Components

When a graph is not connected, the next goal we may have is to identify all ofconnected components of an undirected graph, or thestrongly connected components of a directed graph.

If an initial call to DFS fails to reach all vertices of a graph, we can restart a new call to DFS at one of those unvisited vertices.

59

(72)

Computing all Connected Components

def D F S _ c o m p l e t e ( g ) : f o r e s t = {}

for u in g . v e r t i c e s () : if u not in f o r e s t :

f o r e s t [ u ] = N o n e DFS ( g , u , f o r e s t ) r e t u r n f o r e s t

(73)

Graph Traversals

Breadth-First Search

(74)

Breadth-First Search

The advancing and backtracking of a depth-first search defines a traversal that could bephysically traced by a single person exploring a graph.

Now, we consider another algorithm for traversing a connected component of a graph, known as abreadth-first search (BFS).

(75)

Breadth-First Search

The advancing and backtracking of a depth-first search defines a traversal that could bephysically traced by a single person exploring a graph.

Now, we consider another algorithm for traversing a connected component of a graph, known as abreadth-first search (BFS).

61

(76)

Breadth-First Search

A BFS proceedsin rounds (轮次)and subdivides the vertices intolevels.

BFS starts at vertex s, which is at level 0.

• In the first round, we set all vertices adjacent to the start vertex s as

“visited”. These vertices are one step away from the beginning and are placed into level 1.

• In the second round, we allow allexplorers (探测器)to go two steps away from the starting vertex. These new vertices, which are adjacent to level 1 vertices and not previously assigned to a level, are placed into level 2 and marked as “visited”.

• This process continues in similar fashion, terminating when no new vertices are found in a level.

(77)

Breadth-First Search

图 4: Example of breadth-first search traversal, where the edges incident to a vertex are considered inalphabetical orderof the adjacent vertices.

63

(78)

Breadth-First Search

图 5: Example of breadth-first search traversal, where the edges incident to a vertex are considered inalphabetical orderof the adjacent vertices.

(79)

Breadth-First Search

图 6: Example of breadth-first search traversal, where the edges incident to a vertex are considered inalphabetical orderof the adjacent vertices.

65

(80)

Breadth-First Search

图 7: Example of breadth-first search traversal, where the edges incident to a vertex are considered inalphabetical orderof the adjacent vertices.

(81)

Breadth-First Search

def BFS ( g , s , d i s c o v e r e d ) : l e v e l = [ s ]

w h i l e len( l e v e l ) > 0:

n e x t _ l e v e l = []

for u in l e v e l :

for e in g . i n c i d e n t _ e d g e s ( u ) : v = e . o p p o s i t e ( u )

if v not in d i s c o v e r e d : d i s c o v e r e d [ v ] = e n e x t _ l e v e l . a p p e n d ( v ) l e v e l = n e x t _ l e v e l

67

(82)

Breadth-First Search

def B F S _ c o m p l e t e ( g ) : f o r e s t = {}

for u in g . v e r t i c e s () : if u not in f o r e s t :

f o r e s t [ u ] = N o n e BFS ( g , u , f o r e s t ) r e t u r n f o r e s t

參考文獻

相關文件

6 《中論·觀因緣品》,《佛藏要籍選刊》第 9 冊,上海古籍出版社 1994 年版,第 1

The first row shows the eyespot with white inner ring, black middle ring, and yellow outer ring in Bicyclus anynana.. The second row provides the eyespot with black inner ring

• The order of nucleotides on a nucleic acid chain specifies the order of amino acids in the primary protein structure. • A sequence of three

Especially, the additional gauge symmetry are needed in order to have first order differential equations as equations

Define instead the imaginary.. potential, magnetic field, lattice…) Dirac-BdG Hamiltonian:. with small, and matrix

Miroslav Fiedler, Praha, Algebraic connectivity of graphs, Czechoslovak Mathematical Journal 23 (98) 1973,

Given a connected graph G together with a coloring f from the edge set of G to a set of colors, where adjacent edges may be colored the same, a u-v path P in G is said to be a

In order to solve the problems mentioned above, the following chapters intend to make a study of the structure and system of The Significance of Kuangyin Sūtra, then to have