Common algorithm ideas - branch and bound method

Common algorithm ideas - branch and bound method

a brief introdction

The branch and bound method (Branch and Bound) is a commonly used algorithmic idea used to solve optimization problems, especially in the fields of combinatorial optimization, graph theory, and permutation and combination. It searches the solution space and uses upper and lower bound information to prune the branches of the search tree, thereby reducing the search space and improving the efficiency of the algorithm.

Algorithmic thinking

  1. Initialization: Set the initial value of the objective function to the minimum value (or maximum value).
  2. Construct a solution space tree: starting from the root node, generate child nodes according to the constraints of the problem.
  3. Prioritize node selection: Select a node for expansion. The expansion order is generally determined by calculating the upper and lower bounds of the node.
  4. Pruning: Based on the upper bound and lower bound information, prune nodes and their subtrees that no longer need to be searched to reduce the search space.
  5. Update objective function: If the current node is a feasible solution and is better than the current optimal solution, update the optimal solution.
  6. Continue searching: Return to step 3 and continue to select the next node for expansion until the entire solution space is searched.

Application examples

The following is an example program that uses the branch and bound method to solve the 0-1 knapsack problem, implemented in C++ language:

#include <iostream>
#include <vector>
#include <algorithm>

struct Item {
    
    
    int weight;
    int value;
};

bool compare(Item item1, Item item2) {
    
    
    double ratio1 = static_cast<double>(item1.value) / item1.weight;
    double ratio2 = static_cast<double>(item2.value) / item2.weight;
    return ratio1 > ratio2;
}

int bound(int n, int capacity, const std::vector<Item>& items, int level, int currentWeight, int currentValue) {
    
    
    int boundValue = currentValue;
    int remainingWeight = capacity - currentWeight;

    while (level < n && items[level].weight <= remainingWeight) {
    
    
        remainingWeight -= items[level].weight;
        boundValue += items[level].value;
        level++;
    }

    if (level < n) {
    
    
        boundValue += remainingWeight * static_cast<double>(items[level].value) / items[level].weight;
    }

    return boundValue;
}

int knapsack(int n, int capacity, const std::vector<Item>& items) {
    
    
    std::sort(items.begin(), items.end(), compare);

    int currentWeight = 0;
    int currentValue = 0;
    int maxValue = 0;
    int level = 0;
    std::vector<int> selected(n, 0);

    while (true) {
    
    
        if (level < n && currentWeight + items[level].weight <= capacity) {
    
    
            currentWeight += items[level].weight;
            currentValue += items[level].value;
            selected[level] = 1;
        } else {
    
    
            selected[level] = 0;
        }

        if (currentWeight == capacity) {
    
    
            maxValue = std::max(maxValue, currentValue);
        } else if (bound(n, capacity, items, level + 1, currentWeight, currentValue) > maxValue) {
    
    
            level++;
            continue;
        }

        while (level >= 0 && !selected[level]) {
    
    
            currentWeight -= items[level].weight;
            currentValue -= items[level].value;
            level--;
        }

        if (level < 0) {
    
    
            break;
        }

        currentWeight -= items[level].weight;
        currentValue -= items[level].value;
        level++;
    }

    return maxValue;
}

int main() {
    
    
    int capacity = 50;
    std::vector<Item> items = {
    
    {
    
    10, 60}, {
    
    20, 100}, {
    
    30, 120}};

    int maxValue = knapsack(items.size(), capacity, items);

    std::cout << "Maximum value: " << maxValue << std::endl;

    return 0;
}

The above example program demonstrates the use of the branch and bound method to solve the 0-1 knapsack problem. This problem requires that given the capacity of the backpack, select some items to put into the backpack so that the total value of the items in the backpack is maximized. The program implements the pruning and search process by calculating the upper bound (obtained through the greedy algorithm) and the lower bound (obtained through the relaxation problem), and finally outputs the maximum total value.

Article summary

The branch and bound method is an efficient algorithm for solving optimization problems. It uses pruning to reduce the search space and improve algorithm efficiency. In practical applications, appropriate upper and lower bound calculation methods can be designed based on the characteristics and constraints of specific problems to optimize the performance of the algorithm.

Guess you like

Origin blog.csdn.net/qq_45902301/article/details/131667556