分支界限法 | 0-1背包问题(优先队列式分支限界法)

 

 

 

 

 

 

 

 输入要求

有多组数据。
每组数据包含2部分。
第一部分包含两个整数C (1 <= C <= 10000)和 n (1 <= n <= 10,分别表示背包的容量和物品的个数。
第二部分由n行数据,每行包括2个整数 wi(0< wi <= 100)和 vi(0 < vi <= 100),分别表示第i个物品的总量和价值

输出要求

对于每组输入数据,按出队次序输出每个结点的信息,包括所在层数,编号,背包中物品重量和价值。
每个结点的信息占一行,如果是叶子结点且其所代表的背包中物品价值大于当前最优值(初始为0),则输出当前最优值 bestv 和最优解 bestx(另占一行)
参见样例输出

测试数据

输入示例

5 3
2 2
3 2
2 3

输出示例

1 1 0 0
2 2 2 2
3 5 2 2
4 10 4 5
bestv=5, bestx=[ 1 0 1 ]
4 11 2 2
3 4 5 4
2 3 0 0

小贴士

可采用如下的结构体存储结点:
typedef struct{
    int no; // 结点在堆中的标号 
    int sw; // 背包中物品的重量 
    int sv; // 背包中物品的价值 
    double prior; // 优先值 sv/sw 
}Node;

 

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include<stdio.h>
#include<math.h>
#include<string.h>
typedef struct {
    int no; // 结点标号
    int id; // 节点id
    int sw; // 背包中物品的重量
    int sv; // 背包中物品的价值
    double prior; //   sv/sw
}Node;
 
int surplusValue(int *v,int n,int y) {
    int sum = 0;
    for(int i = y; i <= n; i++) {
        sum += v[i];
    }
     
    return sum;
}
 
void qsort(Node *que,int l,int r) {
    int len = r - l + 1;
    int flag;
     
    for(int i = 0; i < len; i ++) {
        flag = 0;
        for(int j = l; j < l + len - i; j++) {
            if(que[j].prior < que[j+1].prior) {
                Node t = que[j];
                que[j] = que[j+1];
                que[j+1] = t;
                flag = 1;
            }
        }
        //if(!flag ) return;
    }
}
  
 void branchknap(int *w,int *v,int c,int n) {
    int bestv = 0;
    int f = 0;
    int r = 0;
    Node que[3000];
    memset(que,0,sizeof(que));
    int path[15];
    que[0].no = 1;
    que[0].id = que[0].sv = que[0].sw = que[0].prior = 0;
  
    while(f <= r) {
        Node node = que[f];
        printf("%d %d %d %d\n",node.id+1,node.no,node.sw,node.sv);
         
        if(node.no >= pow(2,n)) {
            if(node.sv > bestv) {
                bestv = node.sv;
                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(" ]\n");
             }
         } else {
            if((node.sw + w[node.id + 1]) <= c && surplusValue(v,n,node.id+1) + node.sv > bestv) {
                r++;
                que[r].id = node.id + 1;
                que[r].no = node.no*2;
                int id = node.id + 1;
                que[r].sv = node.sv + v[id];
                que[r].sw = node.sw + w[id];
                que[r].prior = que[r].sv / (que[r].sw*1.0);
             }
              
             if(surplusValue(v,n,node.id+2) + node.sv > bestv) {
                r++;
                que[r].id = node.id + 1;
                que[r].no = node.no*2 + 1;
                que[r].sv = node.sv;
                que[r].sw = node.sw;
                que[r].prior = node.prior;
             }
         }
         f++;
         qsort(que,f,r);
     }
     
 }
  
 int main() {
    int c,n;
    int w[15],v[15];   
    while(~scanf("%d %d",&c,&n)){
          
        for(int i = 1; i <= n; i++) {
            scanf("%d %d",&w[i],&v[i]);                 
        }
         
        branchknap(w,v,c,n);
    }
    return 0;
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include<stdio.h>
#include<math.h>
#include<string.h>
typedef int bool;
#define true 1
#define false 0
 
struct Node{
   int no; // ?áμ?±êo?
   int id; //jie dian id
    int sw; // ±3°ü?D???·μ???á?
    int sv; // ±3°ü?D???·μ????μ
    double prior;
};
struct Node queuee[2000];
int w[15],v[15];
int bestv = 0,c,n;
int path[15]; //lu jing
 
 
int surplusValue(int y) {
    int sum = 0;
    for(int i = y; i <= n; i++)
        sum += v[i];
         
    return sum;
}
void qsort(int l,int r) {
     
//  printf("------\n");
    int len = r - l + 1;
    //printf("----%d %d %d-----\n",l,r,len);
    bool flag;
    for(int i = 0; i < len  ; i++) {
        flag = false;
        for(int j = l; j <l+ len -i  ;j++) {
            if(queuee[j].prior < queuee[j+1].prior) {
                struct Node temp = queuee[j];
                queuee[j] = queuee[j+1];
                queuee[j+1] = temp;
                flag = true;
            }
            //if(!flag) return;
        }
    }
 
//  printf("---排序嘻嘻---\n");
    //for(int i = l; i <= r;i++ )
    //  printf("***%d : %.2lf\n",queuee[i].no,queuee[i].prior);
//  printf("\n------\n");
}
 
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;
      queuee[0].prior = 0;
    //  printf("f: %d r: %d\n",f,r);
      while(f <= r) {
            struct Node node = queuee[f];
            printf("%d %d %d %d\n",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(" ]\n");
                     
                  }
            } else {
                 
                if((node.sw + w[node.id+1]) <= c && surplusValue(node.id+1) + node.sv > bestv) {
                    r++;
                    //printf("%d\n",(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 + v[id];
                    queuee[r].sw = node.sw + w[id];
                    queuee[r].prior = queuee[r].sv/(queuee[r].sw*1.0);
                     
                        //printf("进队id: %d\n",queuee[r].no) ;
                     
                         
                    //printf("%d %d %d\n",id,v[id], w[id]);
                     
                }
             
                if(surplusValue(node.id+2) + node.sv > bestv) {
                    r++;
                    queuee[r].id = node.id+1;
                    queuee[r].no = node.no*2 + 1;
                    queuee[r].sv = node.sv ;
                    queuee[r].sw = node.sw ;
                    queuee[r].prior = node.prior;
                    //printf("进队id: %d\n",queuee[r].no) ;
                }
                 
            }
             
        f++;
        qsort(f,r);
      }
       
       
}
int main() {
    while(~scanf("%d %d",&c,&n)){
        memset(queuee,0,sizeof(queuee));
        for(int i = 1; i <= n; i++) {
            scanf("%d %d",&w[i],&v[i]);
        }
         
        branchknap();
    }
    return 0;
}

  

posted @   听说这是最长的名字了  阅读(7861)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示