Backtracking and branch and bound

The simple description of the idea of ​​the backtracking method is: transform the solution space of the problem into a graph or tree structure representation, and then use the depth-first search strategy to traverse, record and find all feasible solutions or optimal solutions during the traversal process.

The basic idea is similar to:

  • Graph depth first search
  • Post-order traversal of binary tree

The backtracking method searches for the solution space tree of the problem according to the depth-first strategy. First, the solution space tree is searched from the root node. When the algorithm searches for a node of the solution space tree, first use the pruning function to determine whether the node is feasible (that is, you can get The solution of the problem). If it is not feasible, skip the search for the subtree rooted at the node, and backtrack to its ancestor node layer by layer; otherwise, enter the subtree and continue searching according to the depth-first strategy.

The basic behavior of the backtracking method is search. The search process uses pruning functions to avoid invalid searches. Pruning functions include two types: 1. Use constraint functions to cut paths that do not meet the constraints; 2. Use bound functions to cut Go to the path where the optimal solution cannot be obtained.

The key to the problem is how to define the solution space of the problem and transform it into a tree (ie, solution space tree). The solution space tree is divided into two types: subset tree and permutation tree. The two algorithms are roughly the same in structure and thinking.

[Example] 8 queen problem. There are 8 × 8 8 \times 88×Place 8 queens on a chessboard with 8 squares so that no two queens can attack each other, that is, there cannot be more than two queens in the same row and column. There can be no more than two queens on the parallel line. Try to give all the placement methods.

【solution】

Insert picture description here

Let xxx represents the row subscript,yyy represents the column subscript, then we can get the constraint: for any two positions(xi, yi) (x_i, y_i)(xi,Yi)(xj, yj) (x_j, y_j)(xj,Yj), 有
{xi ≠ xjyi ≠ yj ∣ xi - xj ∣ ≠ ∣ yi - yj ∣ \ begin {cases} x_i \ ne x_j \\ \\ y_i \ ne y_j \\ \\ | x_i-x_j | \ ne | y_i - y_j | \ end {cases}xi=xjYi=Yjxixj=yiYj
The following is to define the search strategy, and then branch and bound according to the constraints.

The most straightforward idea is to start placing the first queen until the eighth queen is placed.

We can specify that the first to eighth queens are in the first to eighth columns respectively, then we only need to solve the appropriate row number arrangement.

void queen(int row){
    
    
    if(row==8){
    
    
        total++;
    }else{
    
    
        for(int col=0; col!=8; col++){
    
    
            c[row]=col;
            if(is_ok(row)){
    
    
                queen(row+1);
            }
        }  
    }
}

Calls queen(0)to specific issues only minimal modification to the code will solve the problem.

Guess you like

Origin blog.csdn.net/dreaming_coder/article/details/114378802