Data structure and algorithm design analysis - commonly used search algorithms

1. Exhaustive search

The exhaustive search method is also called the exhaustive method. Its basic idea is to enumerate all candidate solutions to the problem, and then enumerate and test the candidate solutions one by one in a certain order, and from them Find candidate solutions that meet the requirements of the problem as the solution to the problem. Its advantage is that 实现简单且易于理解 is suitable for 规模较小 problems. However, when the scale of the problem is large, it takes a lot of time to run all candidate solutions to the problem, resulting in The efficiency of the algorithm is greatly reduced.

2. Graph traversal algorithm

The graph traversal algorithm is suitable for undirected graphs and directed graphs. There are two methods that can be divided into depth-first search (DFS) and breadth-first search (BFS).

(1) Depth First Search (DFS)

The definition of depth-first search
Simply put, the depth-first search of a graph can be summarized as尽可能深地去搜索一个图, which is a recursive process (need to use storage), search a graph deeply by traversing the adjacency list or adjacency matrix until all connected vertices are visited. If the current branch has already been visited, it will backtrack to the previous vertex and continue. Search other branch vertices until all vertices are visited.

  • Recursion is similar to树的先序遍历, first visit the node, then recursively traverse the outer nodes, search a graph as deeply as possible, and use the backtracking algorithm.

The depth-first search of the graph first selects a certain vertex vi in the graph. After accessing, select any vertex v i is adjacent to the vertex, and the vertex has not been visited,..., continue to repeat the process until all the vertices in the graph are related to vi All connected vertices have been visited; if there are still vertices that have not been visited, select another unvisited vertex as the starting point again, repeat the above steps, and continue until all nodes in the graph are reached. point is visited.

For example, for the following graph, perform a depth-first traversal of the graph with vertex a as the source point, and find a traversal sequence:
Insert image description here
First, select any one adjacent to a Vertex, since the vertices adjacent to a are b, c, e, there can be the following three access sequences {a, b,...} or {a, c,...} or {a, e,...}, as follows :
Insert image description here
Then, select the visited vertex d, or you can select a vertex that has not yet been visited. Since the previously selected sequence to visit is {a, d}, now we visit the vertex f adjacent to the vertex d, and get the sequence {a, d, f}; then visit the vertex c adjacent to the vertex f, and get the sequence {a , d, f, c}; Since both vertices a and f adjacent to c have been visited at this time, go back to f and continue to check d. The vertices adjacent to d have also been visited,..., and finally until the vertex d It has not been accessed yet. Accessing it will get a sequence{a,e,d,f,c,b}. [The sequence is not unique]
Insert image description here

It can be seen that the parts a, e, d, f, and c are the obvious manifestation of searching a graph as deeply as possible in the graph.

Space complexity and time complexity of depth-first search
For a graph G = (V, E), it consists of a vertex set V and an edge set E.
1. Space complexity

  • Since the DFS algorithm is a recursive algorithm, that is, it recursively traverses the vertex set V, the space complexity of DFS traversal is O(|V|).

2. Time complexity

  • The time complexity depends on the storage structure of the graph. If the graph is represented by an adjacency matrix, the time required to find the adjacent vertices of a vertex is O(|V|), and the total time complexity is O(|V|) (the adjacency matrix is ​​a square matrix n×n); if the graph is represented by an adjacency list, the time required to find the adjacent vertices of all vertices is O( |E|), the time required to access the vertex is O(|V|), that is, the total time complexity is O(|V|+|E|). 2

(2) Breadth First Search (BFS)

Definition of breadth-first search
Breadth-first search uses 队列 to store vertices to achieve traversal (queues are used to avoid repeated accesses and store already visited Each adjacent vertex), you can use the adjacency list or adjacency matrix search. First, start accessing from the starting point, and add its adjacent vertices into the queue in sequence until the queue is empty, thereby accessing all vertices, that is, 逐层遍历All vertices until all nodes are traversed

  • Traversing layer by layer is similar to树的层序遍历, traversing outward layer by layer.

In the breadth-first search of the graph, a starting point vertex vi is first selected. After accessing it, it is enqueued and marked as visited. When the queue is not empty, all adjacent vertices of the dequeued vertex are checked, and unvisited adjacent vertices are accessed and marked as visited. It joins the queue,..., and continues to repeat this process until all vertices connected to vi in ​​the graph have been visited; when the queue is empty, the loop is jumped out, and the traversal is completed at this time.

For example, in the graph shown below, start from vertex 1 to find a breadth-first search traversal sequence:
Insert image description here
First, select all vertices adjacent to vertex 1 for visit, there are 2 and 3. The sequence {1, 2, 3} or {1, 3, 2} can be obtained; then, visit other vertices adjacent to 2 and 3 until all vertices are visited. For example, after visiting vertices 2 and 3, visit its adjacent vertex 4, then visit vertex 4's adjacent vertices 5 and 6, and finally visit vertex 7, obtaining {1,2,3,4,5,6,7}. [The sequence is not unique]
The space complexity and time complexity of breadth-first search
For a graph G = (V, E), the vertex set V and It consists of edge set E.
1. Space complexity of BFS algorithm

  • Like the space required for deep search, the space complexity of traversal through BFS is also O(|V|).

2. Time complexity of BFS algorithm

  • The time complexity depends on the storage structure of the graph. If the graph is represented by an adjacency matrix, the time required to find the adjacent vertices of a vertex is O(|V|), and the total time complexity is O(|V|) (the adjacency matrix is ​​a square matrix n×n), which is the same time complexity as the DFS algorithm; if the graph is represented by an adjacency list, then Each vertex is entered into the queue once, that is, the time required is O(|V|), the time required to search the adjacent vertices of the vertex is O(|E|), and its time complexity is O(|V|+|E| ). 2

3. Backtracking method

(1) Definition of lookback method

The backtracking method uses the idea of ​​深度优先搜索(DFS) above. First, by exhaustively enumerating all possible solutions (clear search scope), starting from the initial state, search for the problem with depth-first search If the current node does not satisfy the solution, it will take a step back to the previous node to try other options until it finally finds the node containing the solution to the problem. Similarly, if the scale of the problem is large, the search efficiency of the backtracking method is low because all possible solutions need to be exhausted. [Find all solutions that satisfy the constraints in the solution space tree]

Note: The recursive algorithm and the backtracking method are not the same idea. The backtracking method is a search algorithm idea that exhausts the solution space tree to find a solution that satisfies the conditions, while recursion is dividing a large problem into small problems and then solving the small problems through recursion. To achieve the solution to the final problem, the idea of ​​divide and conquer is used.

The algorithm framework of the backtracking method can be divided into three parts:
1. For the given problem, define the solution space of the problem;

2. Determine the solution space organization structure that is easy to search;

3. Search the solution space depth-first, and use pruning functions (implicit constraints) during the search process to avoid invalid searches.

There are two types of implicit constraints, one is the constraint condition, which is used to determine whether a feasible solution can be obtained, and the other is the boundary condition, which is used to determine whether the optimal solution can be obtained. Therefore, from an algorithmic point of view, the backtracking method is a depth-first search method with a constraint function (constraint condition) or a bounding function (bounding condition).

(2) Application of backtracking method

The backtracking method is commonly used to solve permutation problems, combination problems, subset problems, path problems, etc.
1. Combination problem (combination tree/full m-tree)
There are several elements in a set of elements. If these elements 组合To satisfy a certain property together, all combinations (solution space trees) of this problem are a 满m叉树 or 组合树. For example, a full binary tree is as follows (m=2):
Insert image description here
For example, an example of a full m-tree:
For a road with 4 traffic lights, each There are three possible choices for a traffic light (red, yellow, green). You need to find a choice that makes the road suitable for a certain activity. This scenario can use a full ternary tree to represent the selection of each element (traffic light). On each node of the full ternary tree, there are three child nodes, and each child node represents the selection of an element (traffic light). If one of the elements (a traffic light) is selected, its corresponding child node can be marked as visited and added to the result set. When the entire full ternary tree is traversed, all possible combinations of traffic lights can be obtained, each of which satisfies a certain property, thereby finding the target property that satisfies the activity.

2. Arrangement problem (permutation tree)
In the arrangement of several elements, when one 排列 that satisfies a certain property is determined, this problem All permutations (solution space trees) of are a排列树. For example, the number of permutations of n elements is n! (factorial of n). If n=3 and the three elements are {1, 2, 3}, the permutation tree is as follows:
Insert image description here
where The root node of the tree is empty, indicating the initial state.

3. Subset problem (subset tree)
When a set S composed of several elements is determined to satisfy a certain property子集 , all subsets (solution space trees) of the problem correspond to a子集树. For example, in the 0-1 knapsack problem, the subset to be found that satisfies the property is that the weight of the items in the subset does not exceed the knapsack capacity, and the total value in the knapsack is the largest. The solution space tree of this problem is a subset tree. The subset tree usually has 2n leaf nodes, and the total number of nodes is 2(n+ 1)-1, is a complete binary tree.

In the backtracking method, the solution vector <x1, Collection of trees.

4. Branch and Bound Method

(1) Upper bound and lower bound

For a problem to be solved, the upper and lower bounds are对问题的可能解进行限制和估计的方法, which are used to solve the problem. The upper bound is equivalent to the current highest requirement, which means that the optimal solution to the problem will not exceed a certain known value. The lower bound is equivalent to the current minimum requirement, which means that the optimal solution to the problem will not be lower than a certain known value.

This can be used to prune the branches of the search tree to avoid searching for branches where the optimal solution is impossible, thereby reducing the search space and improving the efficiency of the algorithm.

(2) Definition of branch-and-bound method

  • The branch and bound method is also a search algorithm. Simply put, the 限界 of the branch and bound method is 利用上界和下界来提高搜索效率. In the search solution space tree, the upper and lower bound information is used to prune the branches of the search tree, and branches that lead to infeasible solutions or non-optimal solutions are discarded. [Find a solution that satisfies the constraints in the solution space tree]

Branch and bound method is usually used广度优先搜索(BFS), which searches the solution space tree in the way of maximum benefit (minimum cost). The steps are as follows:
① First, add the root node to the live node table, and then take it out to make it an extension node;
② Generate all branches of the extension node in sequence, that is, its child nodes; < /span>
③Judge each child node. By calculating the upper and lower bounds of the child node, and deciding whether to continue searching for the branch based on these limits, if the limit of a branch satisfies that the upper bound is less than or equal to the lower bound, the branch can be pruned; otherwise, continue to search for the branch. , until a solution that meets the requirements is found or all branches are searched (continue by expanding the node).

(3) Application of branch-and-bound method

The application scenarios of the branch and bound method are:
1. 0-1 knapsack problem
2. Traveling salesman problem
The traveling salesman problem refers to finding the shortest path between a given set of cities so that each city is visited exactly once and eventually returns to the starting point.
3. Container loading problem
The traveling salesman problem is a classic combinatorial optimization problem that can be solved using the branch and bound method. By searching all possible path combinations, find the path with the shortest total distance.
4. Wiring problems in circuit design
Wiring problems in circuit design can be solved using the branch and bound method. By searching all possible wiring methods, the optimal one can be found. untie. For example, in an M×N grid, specify the midpoint of one grid as a and the midpoint of the other grid as b, and find the shortest path from a to b (only straight lines or right-angled edges can be used during wiring). By cutting out the wiring, the squares that can be routed are added to the slip node table, and the grid is expanded until the target point is found or the slip node table is empty.

5. Comparison between backtracking method and branch-and-bound method

  • The advantage of the backtracking method is that it can find all possible solutions, not just the optimal solution. For large-scale problems, the backtracking method may be less efficient because it needs to exhaustively enumerate all possible solutions; the advantage of the branch-and-bound method is that it can effectively reduce the search space through pruning when the problem is large, thereby quickly Find the optimal solution, but there is no guarantee that all possible solutions will be found.
Search algorithm name Backtracking branch and bound method
Search solution space tree way Depth First Search (DFS) Breadth First Search (BFS)
Solve the solution space tree purpose Find all solutions that satisfy constraints Find a solution that satisfies the constraints
Slipknot becomes an extension node one or more times once

Applicable scenarios for the backtracking method include: n queens problem, subset tree (0-1 knapsack problem, maximum clique problem), permutation tree (traveling salesman problem, batch job scheduling problem), combination tree (m coloring problem of graph), etc. wait;

The applicable scenarios of the branch and bound method include: 0-1 knapsack problem, traveling salesman problem, container loading problem, wiring problems in circuit design, etc.

Guess you like

Origin blog.csdn.net/qq_43085848/article/details/134363847