标签:
#include <iostream> #include <queue> using namespace std; template <class Type> class QNode { friend void EnQueue(queue<QNode<Type>*> &Q, Type wt, int i, int n, Type bestw, QNode<Type> *E, QNode<Type> *&bestE, int bestx[], bool ch); friend Type MaxLoading(Type w[], Type c, int n, int bestx[]); private: QNode *parent; // 指向父结点的指针 bool LChild; // 左儿子标志 Type weight; // 结点所相应的载重量 }; /* 将活结点加入到活结点队列中 * Q: 活结点队列 * wt: 当前船上的载重量 * i: 结点所在的层 * n: n个集装箱 * bestw: 最优载重量 * E: 当前扩展结点 * bestE: 记录最优的叶结点 * bestx: * ch: 左儿子标志 * */ template<class Type> void EnQueue(queue<QNode<Type>*> &Q, Type wt, int i, int n, Type bestw, QNode<Type> *E, QNode<Type> *&bestE, int bestx[], bool ch) { if (i == n) // 可行叶结点 { if (wt == bestw) { // 当前最优载重量 bestE = E; bestx[n] = ch; } return; } // 非叶结点 QNode<Type> *b; b = new QNode<Type>; b->weight = wt; b->parent = E; b->LChild = ch; Q.push(b); } /* 队列式分支限界法 * 返回最优载重量,bestx返回最优解 */ template<class Type> Type MaxLoading(Type w[], Type c, int n, int bestx[]) { // 初始化 queue<QNode<Type>*> Q; // 活结点队列 Q.push(0); // 同层结点尾部标志 int i = 1; // 当前扩展结点所处的层 Type Ew = 0, // 扩展结点所相应的载重量 bestw = 0, // 当前最优载重量 r = 0; // 剩余集装箱重量 for (int j = 2; j <= n; j++) { r += w[j]; } QNode<Type> *E = 0, // 当前扩展结点 *bestE; // 当前最优扩展结点 // 搜索子集空间树 while (true) { // 检查左儿子结点 Type wt = Ew + w[i]; if (wt <= c) // 可行结点 { if (wt>bestw) { bestw = wt; } EnQueue(Q, wt, i, n, bestw, E, bestE, bestx, true); } // 检查右儿子结点 if (Ew + r>bestw) { EnQueue(Q, Ew, i, n, bestw, E, bestE, bestx, false); } E = Q.front(); // 取下一扩展结点 Q.pop(); if (!E) // 同层结点尾部 { if (Q.empty()) { break; } Q.push(0); // 同层结点尾部标识 E = Q.front(); // 取下一扩展结点 Q.pop(); i++; // 进入下一层 r -= w[i]; // 剩余集装箱重量 } Ew = E->weight; // 新扩展结点所对应的载重量 } // 构造当前最优解 for (int k = n - 1; k>0; k--) { bestx[k] = bestE->LChild; bestE = bestE->parent; } return bestw; } int main() { float c = 70; float w[] = { 0, 20, 10, 26, 15 };//下标从1开始 const int N = 4; int x[N + 1]; float bestw; cout << "轮船载重为:" << c << endl; cout << "待装物品的重量分别为:" << endl; for (int i = 1; i <= N; i++) { cout << w[i] << " "; } cout << endl; bestw = MaxLoading(w, c, N, x); cout << "分支限界选择结果为:" << endl; for (int j = 1; j <= 4; j++) { cout << x[j] << " "; } cout << endl; cout << "最优装载重量为:" << bestw << endl; return 0; }
#include <iostream> #include <queue> using namespace std; class HeapNode; /* 子集空间树中的结点类型 */ class bbnode { friend void AddLiveNode(priority_queue<HeapNode> &H, bbnode *E, float wt, bool ch, int lev); friend float MaxLoading(float w[], float c, int n, int bestx[]); private: bbnode *parent; // 指向父结点的指针 bool LChild; // 左儿子结点标志 }; class HeapNode { friend void AddLiveNode(priority_queue<HeapNode> &H, bbnode *E, float wt, bool ch, int lev); friend float MaxLoading(float w[], float c, int n, int bestx[]); public: operator float() const // 重载类型转换运算符 { return uweight; } private: bbnode *ptr; // 指向活结点在子集树中相应结点的指针 float uweight; // 活结点优先级(上界) int level; // 活结点在子集树中所处的层序号 }; /* 将活结点加入到表示活结点优先队列的最大堆H中 */ void AddLiveNode(priority_queue<HeapNode> &H, bbnode *E, float wt, bool ch, int lev) { bbnode *b = new bbnode; b->parent = E; b->LChild = ch; HeapNode N; N.uweight = wt; N.level = lev; N.ptr = b; H.push(N); } /* 优先队列式分支限界法 * 返回最优载重量,bestx返回最优解 */ float MaxLoading(float w[], float c, int n, int bestx[]) { // 定义最大堆 priority_queue<HeapNode> H; // 定义剩余容量数组r float *r = new float[n+1]; r[n] = 0; for(int j=n-1; j>0; j--) { r[j] = r[j+1] + w[j+1]; } // 初始化 int i = 1; // 当前扩展结点所处的层 bbnode *E = 0; // 当前扩展结点 float Ew = 0; // 扩展结点所相应的载重量 // 搜索子集空间树 while(i!=n+1) // 非叶子结点 { // 检查当前扩展结点的儿子结点 if(Ew+w[i]<=c) { AddLiveNode(H, E, Ew+w[i]+r[i], true, i+1); } // 右儿子结点 AddLiveNode(H, E, Ew+r[i], false, i+1); // 取下一扩展结点 HeapNode N = H.top(); H.pop(); i = N.level; E = N.ptr; Ew = N.uweight - r[i-1]; } // 构造当前最优解 for(int k=n; k>0; k--) { bestx[k] = E->LChild; E = E->parent; } return Ew; } int main() { float c = 70; float w[] = {0,20,10,26,15}; // 下标从1开始 const int N = 4; int x[N+1]; float bestw; cout<<"轮船载重为:"<<c<<endl; cout<<"待装物品的重量分别为:"<<endl; for(int i=1; i<=N; i++) { cout<<w[i]<<" "; } cout<<endl; bestw = MaxLoading(w,c,N,x); cout<<"分支限界选择结果为:"<<endl; for(int j=1; j<=4; j++) { cout<<x[j]<<" "; } cout<<endl; cout<<"最优装载重量为:"<<bestw<<endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/xwz0528/p/4640792.html