标签:
#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