Lec7 Backtracking
基本概念
例题
- What makes the time complexity analysis of a backtracking algorithm very difficult is that the number of solutions that do satisfy the restriction is hard to estimate.(True)
- What makes the time complexity analysis of a backtracking algorithm very difficult is that the sizes of solution spaces may vary.(False)
alpha-beta剪枝
记 \(v\) 为节点的分数,\(\alpha\) 为返回分数的最大下界,\(\beta\) 为最小上界。
- 如果当前节点是max节点,带着当前的\(\alpha,\beta\)值递归搜索子节点,然后把返回值和父节点的\(\alpha\) 取max。父节点\(\beta\)不变
- 如果是min, 同理和\(\beta\) 取min
- 如果搜到\(\alpha\geq \beta\). 剩下的孩子就不用搜索了
int alpha_beta(int u, int alph, int beta, bool is_max) {
if (!son_num[u]) return val[u];
if (is_max) {
for (int i = 0; i < son_num[u]; ++i) {
int d = son[u][i];
alph = max(alph, alpha_beta(d, alph, beta, is_max ^ 1));
if (alph >= beta) break;
}
return alph;
} else {
for (int i = 0; i < son_num[u]; ++i) {
int d = son[u][i];
beta = min(beta, alpha_beta(d, alph, beta, is_max ^ 1));
if (alph >= beta) break;
}
return beta;
}
}
Code
请使用c++11标准编译
#include<bits/stdc++.h>
using namespace std;
vector<int>son[100];
int val[100];
int alpha_beta(int u, int alph, int beta, bool is_max) {
//输出当前节点编号+(max/min) alpha,beta,,格式要美观 如果值为inf,输出字母,不输出数值
auto print=[&](){
cout<<u<<(is_max?"(max)":"(min)")<<" "<< "alpha=";
if(alph==INT_MIN) cout<<"-inf";
else cout<<alph;
cout<<" beta=";
if(beta==INT_MAX) cout<<"inf";
else cout<<beta;
cout<<endl;
};
print();
if (!son[u].size()) return val[u];
if (is_max) {
for (int i=0;i<son[u].size();i++) {
alph = max(alph, alpha_beta(son[u][i], alph, beta, is_max ^ 1));
print();
if (alph >= beta){
//输出被剪掉
if(i<(int)son[u].size()-1)
cout<<son[u][i+1]<<" is pruned"<<endl;
break;
}
}
return alph;
} else {
for (int i=0;i<son[u].size();i++) {
beta = min(beta, alpha_beta(son[u][i], alph, beta, is_max ^ 1));
print();
if (alph >= beta){
if(i<(int)son[u].size()-1)
cout<<son[u][i+1]<<" is pruned"<<endl;
break;
}
}
return beta;
}
}
int main(){
int n,tot,flag;
//选择模式:完全二叉树/自定义树
cout<<"1 for complete binary tree, 2 for custom tree:";
cin>>n;
if(n==1){
cout<<"input number of leaf nodes:";
cin>>n;
tot=2*n-1;//总共有2n-1个节点 其中n个叶子节点
for(int i=n;i<=2*n-1;i++){
cin>>val[i];
}
//建完全二叉树
for(int i=1;i<=n-1;i++){
son[i].push_back(2*i);
son[i].push_back(2*i+1);
}
//输入根节点是min还是max
cout<<"1 for max, 0 for min:";
cin>>flag;
cout<<alpha_beta(1,INT_MIN,INT_MAX,flag)<<endl;
}
else{
cin>>n;
tot=n;
for(int i=1;i<=n;i++){
cin>>val[i];
}
for(int i=1;i<=n-1;i++){
int x,y;
cin>>x>>y;
son[x].push_back(y);
}
cout<<"1 for max, 0 for min:";
cin>>flag;
cout<<alpha_beta(1,INT_MIN,INT_MAX,flag)<<endl;
}
return 0;
}
/*
1
8
65 68 86 38 65 50 77 33
1
*/