• 分支界限法 | 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;

      

    #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
    ",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(" ]
    ");
    			 }
    		 } 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;
    }
    

      

    #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("------
    "); 
    	int len = r - l + 1;
    	//printf("----%d %d %d-----
    ",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("---排序嘻嘻---
    "); 
    	//for(int i = l; i <= r;i++ )
    	//	printf("***%d : %.2lf
    ",queuee[i].no,queuee[i].prior);
    //	printf("
    ------
    "); 
    } 
    
    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
    ",f,r);
          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 && surplusValue(node.id+1) + node.sv > bestv) {
    					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 + v[id];
    					queuee[r].sw = node.sw + w[id];
    					queuee[r].prior = queuee[r].sv/(queuee[r].sw*1.0);
    					
    						//printf("进队id: %d
    ",queuee[r].no) ;
    					
    						
    					//printf("%d %d %d
    ",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
    ",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;
    }
    

      

  • 相关阅读:
    关于js中"window.location.href"、"location.href"、"parent.location.href"、"top.location.href"的用法
    对于json数据的应用01
    关于session应用(1)session过期时间设置
    关于session应用(2)JAVA中怎么使用session
    Jquery常用技巧(3)
    0101对称二叉树 Marathon
    0112路径之和 & 0113所有路径之和 Marathon
    0106105从中序与后序遍历序列中构造二叉树 Marathon
    0110平衡二叉树 Marathon
    0513找树左下角的值 Marathon
  • 原文地址:https://www.cnblogs.com/jj81/p/10146555.html
Copyright © 2020-2023  润新知