裝載問題-分支限界法-優先佇列式分支限界法
阿新 • • 發佈:2019-01-30
裝載問題實質: 裝載問題是一個子集選取問題,因此其解空間樹是一顆子集樹。
這裡實現優先佇列式分支限界法。
#include <bits/stdc++.h> using namespace std; class MaxHeapQNode { public: MaxHeapQNode *parent; int lchild; int weight; int lev; }; struct cmp { bool operator()(MaxHeapQNode *&a, MaxHeapQNode *&b) const { return a->weight < b->weight; } }; int n; int c; int bestw; int w[100]; int bestx[100]; void InPut() { scanf("%d %d", &n, &c); for(int i = 1; i <= n; ++i) scanf("%d", &w[i]); } void AddAliveNode(priority_queue<MaxHeapQNode *, vector<MaxHeapQNode *>, cmp> &q, MaxHeapQNode *E, int wt, int i, int ch) { MaxHeapQNode *p = new MaxHeapQNode; p->parent = E; p->lchild = ch; p->weight = wt; p->lev = i + 1; q.push(p); } void MaxLoading() { priority_queue<MaxHeapQNode *, vector<MaxHeapQNode *>, cmp > q; // 大頂堆 //定義剩餘重量陣列r int r[n + 1]; r[n] = 0; for(int j = n - 1; j > 0; --j) r[j] = r[j + 1] + w[j + 1]; int i = 1; MaxHeapQNode *E; int Ew = 0; while(i != n + 1) { if(Ew + w[i] <= c) { AddAliveNode(q, E, Ew + w[i] + r[i], i, 1); } AddAliveNode(q, E, Ew + r[i], i, 0); //取下一節點 E = q.top(); q.pop(); i = E->lev; Ew = E->weight - r[i - 1]; } bestw = Ew; for(int j = n; j > 0; --j) { bestx[j] = E->lchild; E = E->parent; } } void OutPut() { printf("最優裝載量為 %d\n", bestw); printf("裝載的物品為 \n"); for(int i = 1; i <= n; ++i) if(bestx[i] == 1) printf("%d ", i); } int main() { InPut(); MaxLoading(); OutPut(); }
測試樣例:
輸入:
(多解,輸出其中一個)
4 60
10
40
50
20
輸出
最優裝載量為 60
裝載的物品為
1 3
執行截圖