算法设计与分析实验报告——实验五 分支限界法

一、实验目的

1. 熟悉分支限界法的基本思想;

2. 使用分支限界法分析、解决问题;

3. 实现算法。

二、实验内容    

  1. 分析装载问题的子集树
  2. 实现分支限界法解决装载问题

三、问题分析   

装载问题给定n个集装箱,要求在不超过轮船载重量c的前提下,将尽可能多的集装箱装上轮船。装载问题的解空间是一棵子集树,采用队列式分支限界法来解决,该算法只求出所要求的最优值。

四、算法描述 

    分支限界法是一种求解最优化问题的搜索算法,在解决装载问题时,分支限界法可以通过不断扩展状态空间,并尝试所有可能的物品组合,在比较最佳的组合之后找到最优解。

分支限界法解决装载问题的算法设计如下:

1.定义一个先进先出队列Q,初始化队列时,在尾部增加一个-1标记,作为分层标志。当一层结束时,在队列尾部增加一个-1标志。

2.定义 Ew 表示扩展节点相对应的载重量,bestw 表示当前最优载重量,r 为剩余集装箱的质量。

3.计算剩余集装箱 r 的总重量,即将第一个节点(根节点)取出并进行检查,得到左子树或右子树的重量,检查约束条件若满足则更新 bestw,并将新的左子树加入队列,如果右子树可行,则将原 Ew 加入队列。

4.从队列中取出队头元素Ew并将其设为当前扩展节点的载重量,并将该节点的所有子节点压入队列中。

5.当队头元素为 -1 时,表示该层已经遍历完毕,弹出队头,将 -1 添加到队尾作为同层遍历结束的标志。

6.进行下一层遍历,i++ 并计算 r 剩余集装箱中去掉当前位置 i 的重量。不断重复上述步骤进行搜索操作,直到队列为空为止。

7.返回最优载重量bestw。

五、运行结果

六、源代码

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define NUM 100
int n;//集装箱的数量
int c;//轮船的载重量
int w[NUM];//集装箱的质量数组

int MaxLoading()
{
    queue<int> Q;//定义活结点队列
    Q.push(-1);
    int i = 0;//当前扩展结点所在层
    int Ew = 0;//扩展结点相对应的载重量
    int bestw = 0;//当前最优载重量
    int r = 0;//剩余集装箱的质量
    for(int j=1; j<n; j++)
        r += w[j];
    while (true)//搜索子空间树
    {
        int wt = Ew+w[i];//检查左子树
        if (wt<=c)//检查约束条件
        {
            if (wt>bestw) bestw = wt;
            //加入活结点队列
            if (i<n-1) Q.push(wt);
        }
        //检查右子树
        if (Ew+r>bestw && i<n-1) 
            Q.push(Ew);
        Ew = Q.front();//从队列中取出活结点
        Q.pop();
        if (Ew==-1)
        {
            if (Q.empty()) //若队列为空,搜索结束
                return bestw;
            Q.push(-1);//同层结点尾部标志
            Ew = Q.front();//从队列中取出活结点
            Q.pop();
            i++;//进入下一层
            r -= w[i];
        }
    }
    return bestw;//返回最优载重量
}
int main()
{
    
    cout<<"请输入集装箱的数量:";
    cin>>n;
    cout<<"请输入轮船的载重量:";
    cin>>c;
    cout<<"请依次输入各个集装箱的重量:";
    for(int i=0; i<n; i++){
        cin>>w[i];
    }       
    int ans=MaxLoading();
    if (ans) 
        cout<<"最优装载量为:"<<ans<<endl;
    else cout<<"Error"<<endl;
    return 0;

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值