1.4 Something About Graphs

1.4 Figure

Like trees, graphs are nonlinear structures. Graph theory has many extensive application backgrounds, and there are many classic algorithms.

1.4.1 Basic Concepts of Graphs

A graph can be expressed as G=(V, E), where V is a collection of vertices, which are usually represented by names or labels; E is a collection of edges, and each edge in E is a set of vertices in V. A connection between a bunch of vertices, expressed as e=(vi,vj). The number of vertices is recorded as |E|. A graph with a small number of edges is called a sparse graph, and a graph with a large number of edges is called a dense graph. A graph with the most edges is called a complete graph.

If the edge of the graph is limited to point from one vertex to another, it is called a directed edge, otherwise it is called an undirected edge. An undirected edge can be viewed as a bunch of directed edges in opposite directions. If all the edges in the graph are directed, then the graph is called a directed graph. If all the edges in a graph are undirected, it is called an undirected graph. If there are directed edges and undirected edges on the way, each undirected edge is converted into a pair of directed edges with opposite directions, and the graph becomes a directed graph. A graph in which all vertices are connected by edges is called a complete graph.

If the undirected edge e=(vi,vj)∈E, the vertices vi and vj are said to be adjacent, and they are called adjacent points to each other, and the edge e is associated with the vertices vi and vj.

1.4.2 Graph storage and basic operations

1. Adjacency matrix method

For the graph G=(V, E), |V|=n, the adjacency matrix of the graph is a two-dimensional array A[n][n], which is defined as follows: A[i][j]={0,(vi, vj) Opposite side 1, (vi,vj)∈E}

The adjacency matrix of a weighted graph is defined as follows:

A[i][j]=A[i][j]={0,(vi,vj) the opposite side 1,(vi,vj)∈E, W is the weight of the side (vi,vj)}

2. Adjacency list method

Both arrays and linked lists are used in the adjacency list method.

For each Vi ∈ V, use a singly linked list to save all adjacent points of Vi, and each adjacent point is stored in a node of the list. The table node structure is defined as

Vertex number pointer

The structure of the weighted graph adjacency list node is defined as

Fixed-point serial number Weight pointer

For an undirected graph, if (vi, vj)∈E, the nodes including Vj appear in the adjacency table corresponding to vi, and similarly, the nodes including vi appear in the adjacency table corresponding to vi. Each edge is stored twice in the adjacency list. The sum of the number of nodes in all adjacency lists is twice the number of vertices in the graph. The number of nodes in the adjacency list corresponding to vertex vi is the degree of vi.

For a directed graph, the number of nodes in the adjacency table corresponding to the vertex vi is the out-degree of Vi, and all adjacency tables need to be traversed to find its in-degree value.

3. Adjacent to multiple lists, cross-linked lists.

Each edge in the undirected graph is saved twice in its adjacency graph, but only once in the adjacency multitable, which is very beneficial for applications that require processing of each edge.

In the adjacency multitable, each node saves the information of one edge, and the node structure is defined as follows:

mark vertex1 link1 vertex2 link2

Among them, vertex1 and vertex2 are the two vertices attached to the edge, link1 points to the next edge attached to vertex1, link2 points to the next edge attached to vertex2, and the processing result of this edge can be marked by mark.

Like an adjacency list, an adjacency multilist uses a bunch of arrays to hold information about all the vertices in the graph. Each array unit includes two fields: vertex and first, where vertex stores the information of each vertex, and first points to the first edge attached to vertex.

Similarly, a directed graph can be represented as a cross-linked list. Each node in the cross-linked list stores information about a directed edge, and the node structure is defined as

mark vertex1 link1 vertex2 link2

Among them, vertex1 and vertex2 are the start point and end point of the edge respectively, link1 points to the next edge with vertex1 as the start point, and link2 points to the next edge with vertex2 as the end point.

Similarly, use a one-dimensional array to store vertex information, and the structure of the array unit is

vertex oven firout

Among them, firout points to the first edge starting from vertex, and firin points to the first edge ending at vertex.

The cross-linked list combines the characteristics of the adjacency list and the negative spirit world table, that is, it is convenient to find the out-degree of the vertex, and it is also convenient to find the in-degree of the vertex.

1.4.3 Graph traversal

A graph is composed of vertices and edges, and its traversal also has two categories: one is to traverse all the vertices in the graph, and the other is to traverse all the edges in the graph. Here we mainly discuss the first type of traversal situation, that is, to list all vertices in the graph without repetition. There are two main traversal strategies: depth-first search (DFS) and breadth-first search (BFS).

1. Depth-first search

In the process of depth-first search, after outputting a vertex, it recursively visits and outputs all its adjacent points that have not been outputted.

Starting from any vertex v1 of graph G=(V,E), output vertex vi. Take vi as the current vertex, find the adjacent point vj of the current vertex, and make the following judgment:

  • If vj has not been output yet, output vj.vj to become the new current vertex, and continue this process.

  • If vj has been exported, check another neighbor of vi.

  • If all adjacent points of vi have been exported, return to the previous vertex of vi.

    The depth-first search process is a recursive process. When the program is implemented, the stack is used to record the traversal path. When traversing a vertex, the vertex is pushed into the stack; Current vertex, continue the traversal process. When the stack is empty, check if all vertices in the graph have been traversed. If yes, the graph is a connected graph, otherwise, the graph is not connected, and a connected component of the graph is obtained at this time. Select any vertex in another connected component that has not been traversed as the current vertex, and restart the traversal process. The deep optimization search algorithm can get each connected component of the graph.

    Intuitively, the depth-first search process starts from a certain vertex v, and traverses along a path until it cannot reach an unvisited vertex, and then returns along the original path to the "fork" that can be found as the visited vertex .

    When the number of vertices in the graph is greater than 1, there are multiple depth-first search sequences in the graph. There are many impossibilities when choosing a different vertex to start, or choosing an adjacent point of a vertex. The tree traversal and the solution of the maze problem all adopt the depth-first search strategy.

2. Breadth-first search

The breadth-first search process is an iterative process, similar to the binary tree sequence traversal process.

Starting from any vertex vi of the graph G=(V,E), enqueue the vertex vi. When the queue is not empty, the loop executes: dequeue, and output the vertex, mark the vertex as output, and put all the adjacent points of the vertex that have not been output into the queue.

Intuitively, the breadth-first search process starts from a certain vertex V, and traverses according to the order of V from near to far. First, traverse the vertices that are one step away from v, then traverse the vertices that are one step away from v, and then traverse the vertices that are two steps away from v, and so on.

Similar to the depth-first search process, when the number of vertices in the graph is greater than 1, there are also multiple breadth-first search sequences. During the traversal process, a one-dimensional array is also needed to mark the vertices. The breadth-first search algorithm can also get the connected components of the graph.

Unlike the stack used in the depth-first search process, the breadth-first search process uses a queue to temporarily store vertices waiting to be output.

1.4.4 Basic applications of graphs

1. Minimum (cost) spanning tree

1) Definition and characteristics of minimum spanning tree

All the edges passed in the depth-first search process of the graph become a depth-first spanning tree, and all the edges passed in the breadth-first process are called a breadth-first spanning tree.

In fact, the spanning tree of a connected graph is a connected subgraph containing all vertices and the least number of edges in the graph. If the number of vertices in graph G=(V, E) |V|=n, then the number of edges of the spanning tree of G is n-1. This is the minimum number of edges that make G connected.

If the number of edges of the connected graph G=(V, E) |E|>|V|-1, it indicates that there are loops in the graph and the spanning tree is not unique. When |E|=|V|-1, the graph itself is a spanning tree. If the graph is disconnected, there is a spanning forest for each spanning tree of connected components.

For the weighted connected graph G=(V, E), the sum of the weights of the edges contained in the spanning tree can be calculated, which is called the cost of the spanning tree.

If there are multiple spanning trees in the weighted connected graph G=(V,E), the cost of different spanning trees may be different, and the spanning tree with the smallest cost is called the minimum (cost) spanning tree, or the minimum spanning tree for short. The sum of the weights of the edges contained in the minimum spanning tree is less than or equal to the sum of the weights of the edges contained in any spanning tree in the graph. The smallest spanning tree may not be unique.

2) Prim's Algorithm

Prim's algorithm is one of the classic algorithms for finding the minimum spanning tree, and the algorithm is quite simple. The specific process of Prim's algorithm is as follows:

  1. initialization

    Let T be the minimum spanning tree of graph G, U be the vertex set of the minimum spanning tree, start from vertex V1, T=⭕/, U={v1};

  2. Select an edge (ui, uj) with the smallest weight value among all edges (u, v) ∈ E of u∈U, v∈VU, add vj to U, U=Uu{uj}, and add edge (ui,uj ) into T, T=TU{(ui,uj)};

  3. Repeat (2) until U=V.

    The time complexity of Prim's algorithm is O(n2), which is suitable for finding the minimum spanning tree of sparse edge graphs.

    3) Kruskal algorithm

    The Kruskal algorithm is another classic algorithm for seeking the minimum maturity.

    Initially, the minimum spanning tree is a non-connected graph T=(V, {}) containing only n vertices, and each vertex in the graph forms a connected component. Select the edge with the smallest weight in E, if the two vertices attached to the edge fall on different connected components in T, then add this edge to T, otherwise discard the edge and choose the next one with the smallest weight side. And so on, until all vertices in T are on the same connected component.

    The Kruskal algorithm scans at most e edges each time, and uses the heap to save all the edges in the graph, so it only takes O(log2e) time to select the edge with the smallest weight each time. Each connected component of the spanning tree T can be called an equivalence class. The process of adding a new edge to T is similar to the process of merging two equivalence classes into one equivalence class. The time complexity is O(log2e), Therefore, the time complexity of Kruskal's algorithm is O(elog2e).

    2. The shortest path

    For graph G, the breadth-first search is based on the "near to far" traversal strategy, and the "shortest path" from one point to another can be obtained.

    For a weighted graph G=(V,E), the path length is defined as the sum of the weights of the edges contained in the path, rather than the number of edges contained in the path. The path with the smallest path length between two vertices Vi, vj is called the shortest path between two vertices.

    There are two shortest path problems: one is the single-source shortest path, and the other is the shortest path between all vertices.

    1) Single-source shortest path

    The algorithm for finding the single-source shortest path of a weighted graph is called Dijkstra's algorithm, which generates the shortest path in the order of non-decreasing path length.

    The basic idea of ​​Dijkstra's algorithm is: Divide all the vertices in the graph into two sets, let S represent the set of vertices whose shortest path has been found, and the remaining vertices whose shortest path has not been determined form another symbol VS. Initially, S contains only source points. Add the vertices in the second set Vs to S one by one in the order that the height of the shortest path is not reduced, and continuously expand the set of vertices that have obtained the shortest path until all vertices that can be reached from the source point are in S. .

    Define a distance value dist for each vertex in the graph, and there are two cases: the distance value dist corresponding to the vertex in the S set is the shortest path length from the source point to this vertex; the distance value dist corresponding to the vertex in the second set VS It is the shortest path length from the source point to this vertex; the distance value corresponding to the vertex in the second set Vs is the length of the shortest path from the source point to this vertex, and the path only includes the vertex in S as the intermediate vertex.

    If the dist value does become smaller, replace the original value with the changed value; if the dist value does not become smaller, keep the original value unchanged.

    dist[i]={The weight on the arc, if there is an arc from the source point V0 to Vi

    ​ {∞, else

The steps of Dijkstra's algorithm are as follows:

  1. initialization

    1. Suppose the weighted adjacency matrix cost is used to represent the weighted directed graph G=(V,E);

    2. cost[i][j] is the weight on the arc (ui,uj);

    3. S is the set of endpoints that have found the shortest path starting from the source point V0, and initially only contains the source point Vo;

    4. The distance from Vo to the rest of the vertices Vi in the graph is:

      dist[i] =cost[vo][vi] A vi∈V

The final A(n)[i][j] is the length of the shortest path from vertex Vi to J.

  1. topological sort

    A directed graph without cycles is called a directed acyclic graph, or DAG for short.

    In the directed graph, the vertex represents the activity, and the directed edge represents the priority relationship between the activities. Such a directed graph is called the network whose vertex represents the activity, or AOV network for short.

    Loops are not allowed in the AOV network, because if there is a loop, it means that an activity is based on itself, that is, there is an activity Vi, and vi is its own predecessor and its successor, which is obviously a contradiction. of. Therefore AOV net is a directed acyclic graph.

    Topological sorting can arrange various activities in the AOV network. It takes each vertex of the AOV network into a linear sequence according to the relationship between them, and this sequence becomes a topologically ordered sequence. In the AOV network, if there is a directed path from vertex Vi to vertex Vj, then in the topologically ordered sequence, Vi must be in front of Vj; if there is no directed path from vertex vi to vertex uj, then in topological order In the ordered sequence, the sequence of Vi and Vj can be arbitrary.

    Use the breadth-first search algorithm to find the in-degree values ​​of all vertices in the AOV network;

    (1) Initialization ----- record the in-degree value of all vertices in the AOV network

    (2) Select a vertex with an in-degree of 0 (no predecessor) and output it

    (3) Delete the vertex and all arcs tailing from it from the graph.

    Repeat steps (2), (3) until all vertices are output; or not all vertices have been output, but no vertices with an in-degree of 0 can be found. The first case indicates that the topological sort has been completed, and the second case indicates that the original directed graph contains cycles.

    The topologically ordered sequence of the AOV network may not be unique.

4. Critical path

In a weighted directed graph, events are represented by vertices, activities are represented by radians, and the duration of activities is represented by weights. The network formed in this way is called a network with activities represented by edges, or AOE network for short. In the AOE network, there is usually only one point with an in-degree of O and one point with an out-degree of O, because a project has only one start and finish point. A point with an in-degree of O is called a starting point or a source point, and a point with an out-degree of O is called an end point or a sink point.

Certain subactivities in a project can be performed in parallel; the length of the longest path from source to sink, that is, the sum of the durations of all activities on that path, is the minimum time required to complete the entire project. The path with the maximum length from the source point to the sink point is called the critical path. All activities on the critical path are called critical activities.

In the AOE network, the longest path length from the source point Vi to any vertex Vi is called the earliest occurrence time of time Vi.

Guess you like

Origin blog.csdn.net/weixin_53073551/article/details/131105051