I. Concept: like the greedy method, this method is used to design a solution algorithm for a combined optimization problem. What's different is that it searches for the entire possible solution space of the problem, although the time complexity of the designed algorithm is higher than that of the greedy algorithm, its advantage is similar to that of the exhaustive method, which ensures the optimal solution to the problem. Moreover, this method is not a blind exhaustive search, instead, you can use the boundary in the search to stop the subspaces that are impossible to obtain the optimal solution. Further search (similar to pruning in artificial intelligence) is more efficient than the exhaustive method. Ii. Basic Idea: The Branch restriction method is usually used to search the space tree for solving the problem in a breadth-first or least-consumed (maximum-benefit)-First manner. In the branch restriction method, each active node has only one chance to become an extension node. Once a dynamic node becomes an extended node, all its son nodes are generated at one time. In these son nodes, the son nodes that are not feasible or optimal are discarded, and the other son nodes are added to the dynamic node table. After that, remove a node from the active node table to become the current expansion node, and repeat the above node expansion process. This process continues until you find that the desired solution or dynamic knots table is null.
Two common branch Restriction Methods
(1) Queue (FIFO) Branch restriction Method
Select the next node as the expansion node based on the first-in-first-out (FIFO) Principle of the queue.
(2) priority queue branch restriction Method
Select the node with the highest priority as the current expansion node according to the priority set in the priority queue.
demo:
Boundary algorithm-problem (Knapsack Problem)
During previous noip competitions, four preliminary and five semi-finals all involved the problem of backpacking. The so-called backpacking problem can be described as follows:
A thief snatched a safe deposit box and found that there were N kinds of items of different sizes and values in the cabinet, but the thief had only one backpack with a volume of m to hold things, the problem with a backpack is that a thief chooses a combination of stolen items to maximize the total value of stolen items.
If there are four items, the volume is 3 4 5 8
Corresponding values: 4 5 7 10
The carrying capacity of the thief's backpack is 12.
Take the item numbered 1 2 3 and obtain the maximum value of 16.
* 0/1 branch and division algorithm of the knapsack problem */# include <stdio. h> # include <stdlib. h ># define maxnum 100 struct node {int step; double price; double weight; double Max, min; unsigned long Po ;}; typedef struct node datatype; struct seqqueue {/* sequence queue type definition */int f, R; datatype Q [maxnum];}; typedef struct seqqueue * queue qqueue; pseqqueue createemptyqueue_seq (void) {queue qqueue Paqu; paqu = (pseqqueue) malloc (sizeof (struct se Qqueue); If (Paqu = NULL) printf ("out of space !! \ N "); else Paqu-> F = Paqu-> r = 0; return Paqu;} int isemptyqueue_seq (pseqqueue Paqu) {return Paqu-> F = Paqu-> r;}/* Insert an element x in the queue */void enqueue_seq (pseqqueue Paqu, datatype X) {If (Paqu-> r + 1) % maxnum = Paqu-> F) printf ("Full queue. \ n "); else {Paqu-> q [Paqu-> r] = x; Paqu-> r = (Paqu-> r + 1) % maxnum ;}} /* Delete the queue Header element */void dequeue_seq (queue qqueue Paqu) {If (Paqu-> F = Paqu-> r) printf ("Empty queue. \ n "); else Paqu -> F = (Paqu-> F + 1) % maxnum;}/* for non-empty queues, locate the queue Header element */datatype frontqueue_seq (queue qqueue Paqu) {return (Paqu-> q [Paqu-> F]);}/* sort items in a cost-effective manner */void sort (int n, Double P [], double W []) {int I, j; for (I = 0; I <n-1; I ++) for (j = I; j <n-1; j ++) {double A = P [J]/W [J]; Double B = P [J + 1]/W [J + 1]; if (a> <B) {double temp = P [J]; P [J] = P [J + 1]; P [J + 1] = temp; temp = W [J]; W [J] = W [J + 1]; W [J + 1] = temp ;}}/ * calculate the maximum possible value */double up (int K, doub Le M, int N, Double P [], double W []) {int I = K; double S = 0; while (I> <n & W [I]> <m) {M-= W [I]; S + = P [I]; I ++ ;} if (I> <n & M> 0) {S + = P [I] * m/W [I]; I ++;} return s ;} /* minimum possible value */Double Down (int K, double M, int N, Double P [], double W []) {int I = K; double S = 0; while (I <n & W [I]> <= m) {M-= W [I]; S + = P [I]; I ++;} return s;}/* branch and demarcation algorithm using queues */Double solve (double M, int N, Double P [], double W [], unsigned long * Po ){ Double min; pseqqueue q = createemptyqueue_seq (); datatype x = {0, 0, 0, 0}; sort (N, P, W); X. max = up (0, M, N, P, W); X. min = min = down (0, M, N, P, W); If (min = 0) Return-1; enqueue_seq (Q, x); While (! Isemptyqueue_seq (q) {int step; datatype y; X = frontqueue_seq (Q); dequeue_seq (Q); If (X. max <min) continue; step = x. step + 1; if (step = n + 1) continue; Y. max = x. price + up (step, m-x.weight, N, P, W); If (Y. max> = min) {Y. min = x. price + down (step, m-x.weight, N, P, W); Y. price = x. price; Y. weight = x. weight; Y. step = step; Y. po = x. po <1; if (Y. min> = min) {min = y. min; If (step = N) * Po = y. po;} enqueue_seq (Q, Y);} If (X. weight + W [step-1] <= m) {Y. max = x. price + P [step-1] + up (step, m-x.weight-w [step-1], N, P, W); If (Y. max> = min) {Y. min = x. price + P [step-1] + down (step, m-x.weight-w [step-1], N, P, W); Y. price = x. price + P [step-1]; Y. weight = x. weight + W [step-1]; Y. step = step; Y. po = (X. po <1) + 1; if (Y. min> = min) {min = y. min; If (step = N) * Po = y. po;} enqueue_seq (Q, Y) ;}} return min ;}# define N 4 double M = 15; Double P [N] ={10, 10, 12, 18}; Dou Ble W [N] = {2, 4, 6, 9}; int main () {int I; double D; unsigned long po; D = solve (M, N, P, W, & po); If (D =-1) printf ("no solution! \ N "); else {for (I = 0; I <n; I ++) printf (" X % d is % d \ n ", I + 1, (PO & (1> <(n-i-1 )))! = 0); printf ("the max weight is % F \ n", d);} getchar (); Return 0 ;}