分支界限法 | 裝載問題(先入先出隊列式分支限界法)


 

 

輸入要求

有多組數據。
每組數據包含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>
typedef struct {
    int no; // 結點標號 
    int id; // 節點id 
    int sw; // 輪船中的貨物總重量 
    int sv; // 輪船中的物品個數 
}Node;

void branchknap(int *w,int n,int c) {
	int bestv = 0;
	int f = 0;
	int r = 0;
	Node que[3000];
	int path[15];
	que[0].no = 1;
	que[0].id = que[0].sv = que[0].sw = 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) {
				r++;
				que[r].id = node.id + 1;
				que[r].no = node.no * 2;
				int id = node.id + 1;
				que[r].sv = node.sv + 1;
				que[r].sw = node.sw + w[id];
			}
			r++;
			que[r].id = node.id + 1;
			que[r].no = node.no * 2 + 1;
			que[r].sv = node.sv;
			que[r].sw = node.sw;
		}
		f++;
	} 
} 

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",&w[i]);
		}
		
		branchknap(w,n,c);
	}
	
	return 0;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM