0034算法笔记分支限界法最优装载问题.docx

上传人:b****9 文档编号:25488449 上传时间:2023-06-09 格式:DOCX 页数:23 大小:48.30KB
下载 相关 举报
0034算法笔记分支限界法最优装载问题.docx_第1页
第1页 / 共23页
0034算法笔记分支限界法最优装载问题.docx_第2页
第2页 / 共23页
0034算法笔记分支限界法最优装载问题.docx_第3页
第3页 / 共23页
0034算法笔记分支限界法最优装载问题.docx_第4页
第4页 / 共23页
0034算法笔记分支限界法最优装载问题.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

0034算法笔记分支限界法最优装载问题.docx

《0034算法笔记分支限界法最优装载问题.docx》由会员分享,可在线阅读,更多相关《0034算法笔记分支限界法最优装载问题.docx(23页珍藏版)》请在冰豆网上搜索。

0034算法笔记分支限界法最优装载问题.docx

0034算法笔记分支限界法最优装载问题

 问题描述

     有一批共个集装箱要装上2艘载重量分别为C1和C2的轮船,其中集装箱i的重量为Wi,且

装载问题要求确定是否有一个合理的装载方案可将这个集装箱装上这2艘轮船。

如果有,找出一种装载方案。

 

   容易证明:

如果一个给定装载问题有解,则采用下面的策略可得到最优装载方案。

 

   

(1)首先将第一艘轮船尽可能装满;

   

(2)将剩余的集装箱装上第二艘轮船。

 

   1、队列式分支限界法求解

    在算法的循环体中,首先检测当前扩展结点的左儿子结点是否为可行结点。

如果是则将其加入到活结点队列中。

然后将其右儿子结点加入到活结点队列中(右儿子结点一定是可行结点)。

2个儿子结点都产生后,当前扩展结点被舍弃。

   活结点队列中的队首元素被取出作为当前扩展结点,由于队列中每一层结点之后都有一个尾部标记-1,故在取队首元素时,活结点队列一定不空。

当取出的元素是-1时,再判断当前队列是否为空。

如果队列非空,则将尾部标记-1加入活结点队列,算法开始处理下一层的活结点。

   节点的左子树表示将此集装箱装上船,右子树表示不将此集装箱装上船。

设bestw是当前最优解;ew是当前扩展结点所相应的重量;r是剩余集装箱的重量。

则当ew+r

另外,为了确保右子树成功剪枝,应该在算法每一次进入左子树的时候更新bestw的值。

   为了在算法结束后能方便地构造出与最优值相应的最优解,算法必须存储相应子集树中从活结点到根结点的路径。

为此目的,可在每个结点处设置指向其父结点的指针,并设置左、右儿子标志。

   找到最优值后,可以根据parent回溯到根节点,找到最优解。

   算法具体代码实现如下:

   1、Queue.h

[cpp] viewplain copy

1.#include  

2.using namespace std;  

3.  

4.template   

5.class Queue  

6.{  

7.    public:

  

8.        Queue(int MaxQueueSize=50);  

9.        ~Queue(){delete [] queue;}  

10.        bool IsEmpty()const{return front==rear;}  

11.        bool IsFull(){return ( (  (rear+1)  %MaxSize==front )?

1:

0);}  

12.        T Top() const;  

13.        T Last() const;  

14.        Queue& Add(const T& x);  

15.        Queue& AddLeft(const T& x);  

16.        Queue& Delete(T &x);  

17.        void Output(ostream& out)const;  

18.        int Length(){return (rear-front);}  

19.    private:

  

20.        int front;  

21.        int rear;  

22.        int MaxSize;  

23.        T *queue;  

24.};  

25.  

26.template  

27.Queue:

:

Queue(int MaxQueueSize)  

28.{  

29.    MaxSize=MaxQueueSize+1;  

30.    queue=new T[MaxSize];  

31.    front=rear=0;  

32.}  

33.  

34.template  

35.T Queue:

:

Top()const  

36.{  

37.    if(IsEmpty())  

38.    {  

39.        cout<<"queue:

no element,no!

"<

40.        return 0;  

41.    }  

42.    else return queue[(front+1) % MaxSize];  

43.}  

44.  

45.template  

46.T Queue :

:

Last()const  

47.{  

48.    if(IsEmpty())  

49.    {  

50.        cout<<"queue:

no element"<

51.        return 0;  

52.    }  

53.    else return queue[rear];  

54.}  

55.  

56.template  

57.Queue&  Queue:

:

Add(const T& x)  

58.{  

59.    if(IsFull())cout<<"queue:

no memory"<

60.    else  

61.    {  

62.        rear=(rear+1)% MaxSize;  

63.        queue[rear]=x;  

64.    }  

65.    return *this;  

66.}  

67.  

68.template  

69.Queue&  Queue:

:

AddLeft(const T& x)  

70.{  

71.    if(IsFull())cout<<"queue:

no memory"<

72.    else  

73.    {  

74.        front=(front+MaxSize-1)% MaxSize;  

75.        queue[(front+1)% MaxSize]=x;  

76.    }  

77.    return *this;  

78.}  

79.  

80.template  

81.Queue&  Queue :

:

Delete(T & x)  

82.{  

83.    if(IsEmpty())cout<<"queue:

no element(delete)"<

84.    else   

85.    {  

86.        front=(front+1) % MaxSize;  

87.        x=queue[front];  

88.    }  

89.    return *this;  

90.}  

91.  

92.  

93.template  

94.void Queue :

:

Output(ostream& out)const  

95.{  

96.    for(int i=rear%MaxSize;i>=(front+1)%MaxSize;i--)  

97.       out<

98.}  

99.  

100.template  

101.ostream& operator << (ostream& out,const Queue& x)  

102.{x.Output(out);return out;}  

   2、6d3-1.cpp

[cpp] viewplain copy

1.//装载问题 队列式分支限界法求解   

2.#include "stdafx.h"  

3.#include "Queue.h"  

4.#include   

5.using namespace std;  

6.  

7.const int N = 4;  

8.  

9.template  

10.class QNode  

11.{  

12.    template  

13.    friend void EnQueue(Queue*>&Q,Type wt,int i,int n,Type bestw,QNode*E,QNode *&bestE,int bestx[],bool ch);  

14.  

15.    template  

16.    friend Type MaxLoading(Type w[],Type c,int n,int bestx[]);  

17.  

18.    private:

  

19.        QNode *parent;  //指向父节点的指针  

20.        bool LChild;    //左儿子标识  

21.        Type weight;    //节点所相应的载重量  

22.};  

23.  

24.template  

25.void EnQueue(Queue*>&Q,Type wt,int i,int n,Type bestw,QNode*E,QNode *&bestE,int bestx[],bool ch);  

26.  

27.template  

28.Type MaxLoading(Type w[],Type c,int n,int bestx[]);  

29.  

30.int main()  

31.{  

32.    float c = 70;    

33.    float w[] = {0,20,10,26,15};//下标从1开始    

34.    int x[N+1];    

35.    float bestw;  

36.    

37.    cout<<"轮船载重为:

"<

38.    cout<<"待装物品的重量分别为:

"<

39.    for(int i=1; i<=N; i++)    

40.    {    

41.        cout<

42.    }    

43.    cout<

44.    bestw = MaxLoading(w,c,N,x);    

45.    

46.    cout<<"分支限界选择结果为:

"<

47.    for(int i=1; i<=4; i++)    

48.    {    

49.        cout<

50.    }    

51.    cout<

52.    cout<<"最优装载重量为:

"<

53.    

54.    return 0;    

55.}  

56.  

57.//将活节点加入到活节点队列Q中  

58.template  

59.void EnQueue(Queue*>&Q,Type wt,int i,int n,Type bestw,QNode*E,QNode *&bestE,int bestx[],bool ch)  

60.{  

61.    if(i == n)//可行叶节点  

62.    {  

63.        if(wt == bestw)  

64.        {  

65.            //当前最优装载重量  

66.            bestE = E;  

67.            bestx[n] = ch;            

68.        }  

69.        return;  

70.    }  

71.    //非叶节点  

72.    QNode *b;  

73.    b = new QNode;  

74.    b->weight = wt;  

75.    b->parent = E;  

76.    b->LChild = ch;  

77.    Q.Add(b);  

78.}  

79.  

80.template  

81.Type MaxLoading(Type w[],Type c,int n,int bestx[])  

82.{//队列式分支限界法,返回最优装载重量,bestx返回最优解  

83. //初始化  

84.    Queue*> Q;      //活节点队列  

85.    Q.Add(0);                   //同层节点尾部标识  

86.    int i = 1;                  //当前扩展节点所处的层  

87.    Type Ew = 0,                //扩展节点所相应的载重量  

88.         bestw = 0,             //当前最优装载重量  

89.         r = 0;                 //剩余集装箱重量  

90.  

91.    for(int j=2; j<=n; j++)  

92.    {  

93.        r += w[j];  

94.    }  

95.      

96.    QNode *E = 0,           //当前扩展节点  

97.                *bestE;         //当前最优扩展节点  

98.  

99.    //搜索子集空间树  

100.    while(true)  

101.    {  

102.        //检查左儿子节点  

103.        Type wt = Ew + w[i];  

104.        if(wt <= c)//可行节点  

105.        {  

106.            if(wt>bestw)  

107.            {  

108.                bestw = wt;  

109.            }  

110.            EnQueue(Q,wt,i,n,bestw,E,bestE,bestx,true);  

111.        }  

112.  

113.        //检查右儿子节点  

114.        if(Ew+r>bestw)  

115.        {  

116.            EnQueue(Q,Ew,i,n,bestw,E,bestE,bestx,false);  

117.        }  

118.        Q.Delete(E);//取下一扩展节点  

119.  

120.        if(!

E)//同层节点尾部  

121.        {  

122.            if(Q.IsEmpty())  

123.            {  

124.                break;  

125.            }  

126.            Q.Add(0);       //同层节点尾部标识  

127.            Q.Delete(E);    //取下一扩展节点  

128.            i++;            //进入下一层  

129.            r-=w[i];        //剩余集装箱重量  

130.        }  

131.        Ew  =E->weight;      //新扩展节点所对应的载重量  

132.    }  

133.  

134.    //构造当前最优解  

135.    for(int j=n-1; j>0; j--)  

136.    {  

137.        bestx[j] = bestE->LChild;  

138.        bestE = bestE->parent;  

139.    }  

140.    return bestw;  

141.}  

   程序运行结果如图:

   2、优先队列式分支限界法求解

    解装载问题的优先队列式分支限界法用最大优先队列存储活结点表。

活结点x在优先队列中的优先级定义为从根结点到结点x的路径所相应的载重量再加上剩余集装箱的重量之和。

   优先队列中优先级最大的活结点成为下一个扩展结点。

以结点x为根的子树中所有结点相应的路径的载重量不超过它的优先级。

子集树中叶结点所相应的载重量与其优先级相同。

   在优先队列式分支限界法中,一旦有一个叶结点成为当前扩展结点,则可以断言该叶结点所相应的解即为最优解。

此时可终止算法。

   算法具体代码实现如下:

   1、MaxHeap.h

[cpp] viewplain copy

1.template  

2.class MaxHeap  

3.{  

4.    public:

  

5.        MaxHeap(int MaxHeapSize = 10);  

6.        ~MaxHeap() {delete [] heap;}  

7.        int Size() const {return CurrentSize;}  

8.  

9.        T Max()   

10.        {          //查  

11.           if (CurrentSize == 0)  

12.           {  

13.                throw OutOfBounds();  

14.           }  

15.           return heap[1];  

16.        }  

17.  

18.        MaxHeap& Insert(const T& x); //增  

19.        MaxHeap& DeleteMax(T& x);   //删  

20.  

21.        void Initialize(T a[], int size, int ArraySize);  

22.  

23.    private:

  

24.        int CurrentSize, MaxSize;  

25.        T *heap;  // element array  

26.};  

27.  

28.template  

29.MaxHeap:

:

MaxHeap(int MaxHeapSize)  

30.{// Max heap constructor.  

31.    MaxSize = MaxHeapSize;  

32.    heap = new T[MaxSize+1];  

33.    CurrentSize = 0;  

34.}  

35.  

36.template  

37.MaxHeap& MaxHeap:

:

Insert(const T& x)  

38.{// Insert x into the max heap.  

39.    if (CurrentSize == MaxSize)  

40.    {  

41.        cout<<"no space!

"<

42.        return *this;   

43.    }  

44.  

45.    // 寻找新元素x的位置  

46.    // i——初始为新叶节点的位置,逐层向上,寻找最终位置  

47.    int i = ++CurrentSize;  

48.    while (i !

= 1 && x > heap[i/2])  

49.    {  

50.        // i不是根节点,且其值大于父节点的值,需要继续调整  

51.        heap[i] = heap[i/2]; // 父节点下降  

52.        i /= 2;              // 继续向上,搜寻正确位置  

53.    }  

54.  

55.   heap[i] = x;  

56.   return *this;  

57.}  

58.  

59.template  

60.MaxHeap& MaxHeap:

:

DeleteMax(T& x)  

61.{// Set x to max element and delete max element from heap.  

62.    // check if heap is empty  

63.    if (CurrentSize == 0)  

64.    {  

65.        cout<<"Empty heap!

"<

66.        return *this;   

67.    }  

68.  

69.    x = heap[1]; // 删除最大元素  

70.    // 重整堆  

71.    T y = 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1