用分支限界法求解装载问题,用队列式求解c语言
时间: 2023-11-22 11:56:45 浏览: 110
装载问题是指在给定的一批货物中选择若干个装入给定容量的运输工具,使得装载的货物总重量最大。分支限界法是一种解决组合优化问题的方法。下面给出用队列式求解装载问题的C语言代码:
```
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 100
#define MAX_W 1000
typedef struct {
int w; // 货物重量
int p; // 货物编号
} goods;
int n, w; // 货物数量和运输工具容量
goods g[MAX_N]; // 货物数组
int max_weight; // 最大装载重量
// 队列结构体
typedef struct node {
int i; // 当前处理的货物编号
int weight; // 当前装载重量
int value; // 当前货物总价值
int bound; // 价值上界
} node;
// 求解装载问题
void knapsack() {
node u, v;
int q[MAX_N * 2], head = 0, tail = 0;
max_weight = 0;
// 初始化根节点
v.i = 0;
v.weight = 0;
v.value = 0;
v.bound = 0;
for (int j = 0; j < n; j++) {
v.bound += g[j].w;
}
// 将根节点入队
q[tail++] = 0;
// 分支限界法求解
while (head < tail) {
// 取出队首节点
int idx = q[head++];
u = v;
// 处理左子树
if (u.weight + g[idx].w <= w) {
v.i = idx + 1;
v.weight = u.weight + g[idx].w;
v.value = u.value + g[idx].p;
v.bound = u.bound - g[idx].p;
// 更新最大装载重量
if (v.weight > max_weight) {
max_weight = v.weight;
}
// 判断是否需要加入队列
if (v.bound > max_weight) {
q[tail++] = idx + 1;
}
}
// 处理右子树
v.i = idx + 1;
v.weight = u.weight;
v.value = u.value;
v.bound = u.bound - g[idx].p;
// 判断是否需要加入队列
if (v.bound > max_weight) {
q[tail++] = idx + 1;
}
}
}
int main() {
// 读入数据
scanf("%d %d", &n, &w);
for (int i = 0; i < n; i++) {
scanf("%d", &g[i].w);
g[i].p = i + 1;
}
// 按照货物重量从大到小排序
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (g[i].w < g[j].w) {
goods temp = g[i];
g[i] = g[j];
g[j] = temp;
}
}
}
// 求解装载问题
knapsack();
// 输出结果
printf("%d\n", max_weight);
return 0;
}
```
以上代码实现了分支限界法的队列式求解方法。具体思路是,将根节点入队,然后不断从队列中取出节点进行处理,计算其左右子树,如果左子树的装载重量小于等于运输工具容量,则将左子树节点入队,并更新最大装载重量;同时,如果右子树的价值上界大于当前的最大装载重量,则将右子树节点入队。这样不断扩展队列,直到队列为空为止。最终得到的最大装载重量即为所求解。
阅读全文