Construct subset tree
pruning strategy
1. For a derived child node, if the sum of the price of the currently selected item and the minimum price of the unselected item is greater than C, it will be cut directly (for the price)
2. Another global variable is bestw, which records the minimum weight of the nodes (the sum of prices is less than C) that have all been selected and have not been pruned. For a derived child node, if the sum of the weight of the selected item and the minimum weight of the unselected item is greater than bestw, it can also be cut directly. (for weight)
Use the mountain climbing method according to the pruning strategy, because it can determine the bestw fastest to prune better.
Implement pruning strategy
#include <iostream> #include <queue> #include <stack> using namespace std; #define num_of_project 2 / / number of parts #define num_of_trade 3 / / number of suppliers int w[num_of_trade][num_of_project];//Component is column, supplier is row, weight matrix int c[num_of_trade][num_of_project];//Parts are columns, suppliers are rows, and price matrix int best_choice[num_of_project];//Component is column, supplier is row, selection matrix int bestw; int C;//Upper bound of price typedef struct node{ int cost;//Price int weight;//For weight, the stack is last in first out. Because the mountain climbing method selects the small weight, the smaller the weight should be later in and be preferentially expanded. Therefore, the larger the weight in the priority queue, the more first in the stack. According to the weight in the priority queue, the larger the weight, the more ahead, and the greater the priority int choice[num_of_project];//Indicates which supplier is selected for the ith part queue<int> X;//Unselected items, queue is convenient for access }node; bool operator<(node a, node b) { return a.weight < b.weight;//weight maximum priority } void init(node* child, node* parent) { child->cost = parent->cost; child->weight = parent->weight; child->X = parent->X; } void printk(int p[3][3]) { for (int i = 0; i < num_of_trade; i++) { for (int j = 0; j < num_of_project; j++) { cout << p[i][j]<<" "; } cout << '\n'; } } stack<node> S;//Maintain nodes and realize mountain climbing method int main() { cin >> C; for (int i = 0; i < num_of_trade; i++) { for (int j = 0; j < num_of_project; j++) { cin >> w[i][j]; cin>> c[i][j]; } } int cost_down = 0, weight_down = 0;//Price, weight, lower bound for (int i = 0; i < num_of_project; i++) { int cost_min = c[0][i], weight_min = w[0][i];//The lowest price and weight provided by each item supplier for (int j = 0; j < num_of_trade; j++) { if (cost_min > c[j][i]) { cost_min = c[j][i]; } if (weight_min > w[j][i]) { weight_min = w[j][i]; } } cost_down += cost_min; weight_down += weight_min; for (int j = 0; j < num_of_trade; j++) { w[j][i] -= weight_min; c[j][i] -= cost_min; } }//Deal with every item node parent_of_all; parent_of_all.cost = cost_down; parent_of_all.weight = weight_down; for (int i = 0; i < num_of_project; i++) { parent_of_all.X.push(i); } S.push(parent_of_all); bestw = 0x7fffffff;//The maximum value of int indicates that the minimum weight has not been found at the beginning while (!S.empty()) { priority_queue<node> q; node parent = S.top(); S.pop(); for (int i = 0; i < num_of_trade; i++) { node child; init(&child, &parent); int next_project = child.X.front(); child.X.pop(); child.cost += c[i][next_project]; child.weight += w[i][next_project]; child.choice[next_project] = i; if (child.cost > C)continue;//For price if (child.weight >= bestw)continue;//For the weight, it is equal to cutting faster if (child.X.empty()) { if (child.weight < bestw) { bestw = child.weight; for (int i = 0; i < num_of_project; i++) { best_choice[i] = child.choice[i]; } } continue; } q.push(child);//High priority will be put into the stack by the first out team }//To get the next from the i-th supplier_ Project contains items, with parts as columns and suppliers as rows while (!q.empty()) { S.push(q.top()); q.pop(); } } for (int i = 0; i < num_of_project; i++) { cout << best_choice[i] << " "; } cout << endl; cout << bestw; }