码迷,mamicode.com
首页 > 其他好文 > 详细

装载问题

时间:2015-07-12 14:03:14      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:

 

#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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!