分支界限法 | 装载问题(先入先出队列式分支限界法)
Posted jj81
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分支界限法 | 装载问题(先入先出队列式分支限界法)相关的知识,希望对你有一定的参考价值。
输入要求
有多组数据。
每组数据包含2行。
第一行包含2个整数 C(1 <= C <= 1000)、和 n(1 <= n <= 10),分别表示的轮船的载重量和集装箱的个数。
第二行包含n个整数,依次表示n个集装箱的重量w。(0 <= w <= 1000)
输出要求
对于每组输入数据,按出队次序输出每个结点的信息,包括所在层数,编号,已装载重链,轮船上集装箱的个数
每个结点的信息占一行,如果是叶子结点且其所代表的装上轮船的集装箱的个数大于当前最优值(初始为0),则输出当前最优值 bestv 和最优解 bestx(另占一行)
参见样例输出
测试数据
输入示例
4 3
2 3 2
输出示例
1 1 0 0
2 2 2 1
2 3 0 0
3 5 2 1
3 6 3 1
3 7 0 0
4 10 4 2
bestv=2, bestx=[ 1 0 1 ]
4 11 2 1
4 13 3 1
4 14 2 1
4 15 0 0
小贴士
可采用如下的结构体存储结点:
typedef struct{
int no; // 结点标号
int sw; // 轮船上集装箱的重量
int sum; // 轮船上集装箱的数量
}Node;
#include<stdio.h> #include<math.h> struct Node{ int no; // ?áμ?±êo? int id; //jie dian id int sw; // ±3°ü?D???·μ???á? int sv; // ±3°ü?D???·μ????μ }; struct Node queuee[3000]; int w[15],v[15]; int bestv = 0,c,n; int path[15]; //lu jing void branchknap() { bestv = 0; int f = 0; int r = 0; queuee[0].no = 1; queuee[0].id = 0; queuee[0].sv = 0; queuee[0].sw = 0; while(f <= r) { struct Node node = queuee[f]; printf("%d %d %d %d ",node.id+1,node.no,node.sw,node.sv); if(node.no >= pow(2,n)) { if(node.sv > bestv) { bestv = node.sv; //TODO printf("bestv=%d, bestx=[",bestv); int temp = node.no; int i = 0; while(temp > 1) { if(temp%2 == 0) path[i] = 1; else path[i] = 0; temp /= 2; i++; } i--; while(i >= 0) { printf(" %d",path[i]); i--; } printf(" ] "); } } else { if((node.sw + w[node.id+1]) <= c) { r++; //printf("%d ",(node.sw + w[node.id+1])); queuee[r].id = node.id+1; queuee[r].no = node.no*2; int id = node.id+1; queuee[r].sv = node.sv + 1; queuee[r].sw = node.sw + w[id]; // printf("%d %d %d ",id,v[id], w[id]); } r++; queuee[r].id = node.id+1; queuee[r].no = node.no*2 + 1; queuee[r].sv = node.sv ; queuee[r].sw = node.sw ; } f++; } } int main() { while(~scanf("%d %d",&c,&n)){ for(int i = 1; i <= n; i++) { scanf("%d",&w[i]); //printf("%d %d ",w[i], v[i]); } //printf("%d %d ",w[2],v[2]); branchknap(); } return 0; }
以上是关于分支界限法 | 装载问题(先入先出队列式分支限界法)的主要内容,如果未能解决你的问题,请参考以下文章