分支界限法 | 裝載問題(先入先出隊列式分支限界法)
阿新 • • 發佈:2018-12-20
typedef 和集 \n n) 分享圖片 type amp nap include
輸入要求
有多組數據。
每組數據包含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\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) { 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 + 1; queuee[r].sw = node.sw + w[id]; // printf("%d %d %d\n",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\n",w[i], v[i]); } //printf("%d %d\n",w[2],v[2]); branchknap(); } return 0; }
分支界限法 | 裝載問題(先入先出隊列式分支限界法)