博客
关于我
好理解的基于二叉树的0-1背包求解问题
阅读量:495 次
发布时间:2019-03-07

本文共 2864 字,大约阅读时间需要 9 分钟。

建立一个二叉树,我们约定左结点表示选择装入物品,右结点表示不装入物品。假设有5个物品,物品重量是{2, 2, 6, 5, 4},对应价值是{6, 3, 5, 4, 6}。背包的容量为10。

对于第一个物品,我们可以选择装入或者不装入。若装入,总重量为2,总价值为6。若不装入,总重量为0,总价值为0。

对于第二个物品,我们可以选择装入或者不装入。若第一个物品已经装入,则若装入第二个物品,总重量为4,总价值为9。若不装入第二个物品,总重量为2,总价值为6。若第一个物品没有装入,则若装入第二个物品,总重量为2,总价值为3。若不装入第二个物品,总重量为0,总价值为0。

依此类推,我们可以构造出这样的二叉树。通过先序遍历,即可获得背包中物品的最大总价值。

在代码实现中,我们可以使用递归的方式构建二叉树,并在遍历过程中记录最大价值。每次处理一个节点时,计算当前路径的总重量和价值。如果总重量超过背包容量,则返回空,否则继续处理左右子节点。处理完所有节点后,返回最大价值。

以下是代码示例:

#include 
#include
using namespace std;
typedef struct TreeNode {
long long int val;
long long int weight;
bool left;
bool right;
TreeNode *LChild;
TreeNode *RChild;
TreeNode *Parent;
} TreeNode;
TreeNode *init(TreeNode *node) {
node->weight = 0;
node->val = 0;
node->left = false;
node->right = false;
node->LChild = NULL;
node->RChild = NULL;
node->Parent = NULL;
return node;
}
TreeNode *addNode(TreeNode *parented, int w, int val) {
TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));
node = init(node);
if (parented->weight + w <= c) {
node->weight = w + parented->weight;
node->val = val + parented->val;
node->Parent = parented;
} else {
node = NULL;
}
return node;
}
int main(int argc, char const *argv[]) {
TreeNode *head = (TreeNode *)malloc(sizeof(TreeNode));
head = init(head);
int n, c;
cin >> n >> c;
int w[1001], p[1001];
for (int i = 0; i < n; i++) {
cin >> w[i] >> p[i];
}
head = init(head);
int i = 0;
while (1) {
if (head->left && head->right && head->Parent == NULL) {
cout << "结束" << endl;
break;
}
if (head->left && head->right) {
cout << "回退" << endl;
i--;
head = head->Parent;
continue;
}
if (i >= n || head->weight >= c) {
cout << "加完数据了或者已经装满了" << endl;
if (MAX < head->val) {
MAX = head->val;
}
head->left = true;
head->right = true;
continue;
}
if (!head->left) {
cout << "加左结点 i = " << i << endl;
head->left = true;
head->LChild = addNode(head, w[i], p[i]);
if (head->LChild != NULL) {
i++;
head = head->LChild;
}
} else if (!head->right) {
cout << "加右结点 i = " << i << endl;
head->right = true;
head->RChild = addNode(head, 0, 0);
if (head->RChild != NULL) {
i++;
head = head->RChild;
}
}
}
cout << MAX << endl;
}

通过先序遍历,我们可以找到背包中物品的最大总价值。代码中使用了递归的方式构建二叉树,并在遍历过程中记录最大价值。每次处理一个节点时,计算当前路径的总重量和价值。如果总重量超过背包容量,则返回空,否则继续处理左右子节点。处理完所有节点后,返回最大价值。

在实际应用中,可以根据需要调整递归深度和性能优化措施,确保程序能够高效运行。

转载地址:http://xjccz.baihongyu.com/

你可能感兴趣的文章
NN&DL4.1 Deep L-layer neural network简介
查看>>
NN&DL4.3 Getting your matrix dimensions right
查看>>
NN&DL4.7 Parameters vs Hyperparameters
查看>>
NN&DL4.8 What does this have to do with the brain?
查看>>
nnU-Net 终极指南
查看>>
No 'Access-Control-Allow-Origin' header is present on the requested resource.
查看>>
NO 157 去掉禅道访问地址中的zentao
查看>>
no available service ‘default‘ found, please make sure registry config corre seata
查看>>
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
查看>>
no connection could be made because the target machine actively refused it.问题解决
查看>>
No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
查看>>
No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
查看>>
No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
查看>>
No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
查看>>
No mapping found for HTTP request with URI [/logout.do] in DispatcherServlet with name 'springmvc'
查看>>
No module named 'crispy_forms'等使用pycharm开发
查看>>
No module named cv2
查看>>
No module named tensorboard.main在安装tensorboardX的时候遇到的问题
查看>>
No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
查看>>
No new migrations found. Your system is up-to-date.
查看>>