2023年8月1日发(作者:)
C++数据结构与算法分析——分⽀限界法(BFS求解01背包问题)分⽀限界法介绍分⽀限界,⼜叫分⽀定界,是⼀种系统搜索解空间的⽅法。它是的⼀种剪枝。在中我们已经知道,在DFS中有隐含的搜索树存在,BFS中同样也有(分析题⽬时⽤)分⽀限界,分为两个剪枝:分⽀和限界。1. 分⽀:即可⾏性剪枝,当遍历到⼀个点时,判断它是否符合题意,如果不符合,那么则将这个分⽀剪去。2. 限界:即最优性剪枝,这需要⼀个估价函数来判断当前遍历到的点是否有可能得到最优解,如果不可能得到最优解,那么该分⽀也可剪去。这么说也许有些抽象,当前我们选择01背包作为例⼦:题⽬描述有N件物品和⼀个容量是V的背包。每件物品只能使⽤⼀次。第i件物品的体积是vi,价值是wi。求解将哪些物品装⼊背包,可使这些物品的总体积不超过背包容量,且总价值最⼤。输出最⼤价值。输⼊格式第⼀⾏两个整数,N,V,⽤空格隔开,分别表⽰物品数量和背包容积。接下来有N⾏,每⾏两个整数vi,wi,⽤空格隔开,分别表⽰第i件物品的体积和价值。输出格式输出⼀个整数,表⽰最⼤价值。数据范围0
struct good{ int idx,c,r,tv; // idx表⽰选法下标,c表⽰该选法的当前总价值,r表⽰当前选法的剩余总价值,tv表⽰该选法的当前总体积 bool operator > (const good& W) const{ return W.c + W.r > c + r; }}goods[N];int bfs(){ goods[1] = {1,0,0,0}; priority_queue
假如已经是⼦节点,则更新答案 res = max(res,t.c); continue; } if(goods[idx].tv <= m && goods[idx].c + goods[idx].r > res) (goods[idx]); //
假如当前选法的总体积不超过背包容量,且当前价值+剩余价值 >
当前最优解,则装⼊背包 if(goods[idx + 1].tv <= m && goods[idx + 1].c + goods[idx + 1].r > res) (goods[idx + 1]); } return res;}int main(){ cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i],s[i] = s[i - 1] + w[i];//// for(int i = 2; i < 1 << n + 1; i ++){// goods[i] = {i,goods[i >> 1].c + (i&1)*w[(int)log2(i)],s[n] - s[(int)log2(i)],goods[i >> 1].tv + (i&1)*v[(int)log2(i)]};// }//// for(int i = 1; i < 1 << n + 1; i ++) printf("i = %d,c[i] = %d,r[i] = %d,tv[i] = %dn",goods[i].idx,goods[i].c,goods[i].r,goods[i].tv); cout << bfs() << endl; return 0;}运⾏截图
2023年8月1日发(作者:)
C++数据结构与算法分析——分⽀限界法(BFS求解01背包问题)分⽀限界法介绍分⽀限界,⼜叫分⽀定界,是⼀种系统搜索解空间的⽅法。它是的⼀种剪枝。在中我们已经知道,在DFS中有隐含的搜索树存在,BFS中同样也有(分析题⽬时⽤)分⽀限界,分为两个剪枝:分⽀和限界。1. 分⽀:即可⾏性剪枝,当遍历到⼀个点时,判断它是否符合题意,如果不符合,那么则将这个分⽀剪去。2. 限界:即最优性剪枝,这需要⼀个估价函数来判断当前遍历到的点是否有可能得到最优解,如果不可能得到最优解,那么该分⽀也可剪去。这么说也许有些抽象,当前我们选择01背包作为例⼦:题⽬描述有N件物品和⼀个容量是V的背包。每件物品只能使⽤⼀次。第i件物品的体积是vi,价值是wi。求解将哪些物品装⼊背包,可使这些物品的总体积不超过背包容量,且总价值最⼤。输出最⼤价值。输⼊格式第⼀⾏两个整数,N,V,⽤空格隔开,分别表⽰物品数量和背包容积。接下来有N⾏,每⾏两个整数vi,wi,⽤空格隔开,分别表⽰第i件物品的体积和价值。输出格式输出⼀个整数,表⽰最⼤价值。数据范围0
struct good{ int idx,c,r,tv; // idx表⽰选法下标,c表⽰该选法的当前总价值,r表⽰当前选法的剩余总价值,tv表⽰该选法的当前总体积 bool operator > (const good& W) const{ return W.c + W.r > c + r; }}goods[N];int bfs(){ goods[1] = {1,0,0,0}; priority_queue
假如已经是⼦节点,则更新答案 res = max(res,t.c); continue; } if(goods[idx].tv <= m && goods[idx].c + goods[idx].r > res) (goods[idx]); //
假如当前选法的总体积不超过背包容量,且当前价值+剩余价值 >
当前最优解,则装⼊背包 if(goods[idx + 1].tv <= m && goods[idx + 1].c + goods[idx + 1].r > res) (goods[idx + 1]); } return res;}int main(){ cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i],s[i] = s[i - 1] + w[i];//// for(int i = 2; i < 1 << n + 1; i ++){// goods[i] = {i,goods[i >> 1].c + (i&1)*w[(int)log2(i)],s[n] - s[(int)log2(i)],goods[i >> 1].tv + (i&1)*v[(int)log2(i)]};// }//// for(int i = 1; i < 1 << n + 1; i ++) printf("i = %d,c[i] = %d,r[i] = %d,tv[i] = %dn",goods[i].idx,goods[i].c,goods[i].r,goods[i].tv); cout << bfs() << endl; return 0;}运⾏截图
发布评论