实验名称: 箱子装载问题

实验地点:

实验目的:

1、 理解和复习所学各种算法的概念;

2、  掌握和复习所学各种算法的基本要素;

3、  掌握各种算法的优点和区别;

4、  通过应用范例掌握选择最佳算法的设计技巧与策略;

实验原理

回溯法原理:

从开始结点出发,以深度优先方式搜索整个解空间。这个节点成为活结点,同时也成为当前的扩展节点。在当前的扩展节点处,搜索向纵深方向一致一个新节点。

贪心算法原理:

贪心算法通过一系列的选择来得到问题的解。他所做的每一个选择都是当前状态下局部最好选择,即贪心选择。

分支限界法原理:

每一个活结点只有一次机会成为扩展结点,一旦成为扩展结点,就一次性产生其所有儿子结点。儿子结点中,导致不可行解或者非最优解的被舍弃,其余加入活结点表中。从活结点表中取下一结点成为当前扩展结点,并重复上述结点的扩展过程,一直持续到找到所需的解或活结点表为空为止。

实验内容:

1、使用贪心算法、回溯法、分支限界法解决箱子装载问题。(任选两种)

2、通过上机实验进行算法实现。

3、保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。

源程序:

(1)贪心算法

#include<stdio.h>
#include<stdlib.h>
void swap(int &x, int &y){  //交换 int t;t = x;x = y;y = t;
}
void sort(int w[], int t[], int n)  //排序,有小到大
{for (int m = 0; m<n; m++)    //为每个物品编序号 t[m] = m;int i, j;int lastExchangeIndex;i = n - 1;while (i>0){lastExchangeIndex = 0;for (j = 0; j<i; j++){if (w[j + 1]<w[j]){swap(w[j + 1], w[j]);  //物品的重量交换lastExchangeIndex = j;swap(t[j], t[j + 1]);}}i = lastExchangeIndex;}
}
void loading(int x[], int w[], int c, int n, int *t)    //最有装载
{sort(w, t, n);for (int i = 0; i<n; i++)x[i] = 0;for (int j = 0; j<n&&w[t[j]] <= c; j++){x[t[j]] = 1;c -= w[t[j]];       //装入 }
}
int main(){int n, c;printf("请输入物品个数:");scanf("%d", &n);printf("请输入最大容量:");scanf("%d", &c);int x[200]; //存储物品编号 int w[200];    //存储每个物品重量for (int i = 0; i<n; i++){printf("请输入第%d个物品重量:", i);scanf("%d", &w[i]);}int *t = new int[n];    //物品是否装入for (int j = 0; j<n; j++)x[j] = 0;   //初始化物品均未装入loading(x, w, c, n, t);printf("装入物品编号为:");for (int k = 0; k<n; k++)if (x[k] == 1)printf("%d ", t[k]);return 0;}

(2)回溯法

#include<stdio.h>
#include<stdlib.h>
#define num 100
int bestx[num] = { 0 };    //存放最优解
int w[num]; //集装箱重量
int x[num]; //解
int bestw = 0; //最优装船重量
int cw = 0;    //当前已装船重量
int n;  //集装箱个数
int c1; //第一船的重量
int c2; //第二船的重量//限界函数
int bound(int t)        // 选择当前节点又分支的剩余集装箱重之和
{int rw = 0;for (int i = t + 1; t<n; t++)rw = rw + w[i];return (rw + cw);    //上界
}
//递归求解
void loadingRec(int t){int i;if (t>n)        //到底叶子节点,求得一个可行解{if (cw>bestw){       //当前解比以前解更优 bestw = cw;for (i = 1; i <= n; i++)bestx[i] = x[i];};return;}else{if (cw + w[t]<c1)        //左分支满足约束条件{x[t] = 1;cw = cw + w[t];loadingRec(t + 1);      //前进继续搜索下一节点//回溯;回复cw与x[t]的值cw = cw - w[t];x[t] = 0;}if (bound(t)>bestw)        //右分支满足限界条件loadingRec(t + 1);}
}
int main(){n = 4;      //集装箱个数printf("集装箱个数:");scanf("%d",&n); printf("集装箱重量:");w[1] = 4, w[2] = 5, w[3] = 3, w[4] = 2;      //集装箱重量for(int i=1;i<=n;i++){scanf("%d",&w[i]);}c1 = 8;       //第一个船重量c2 = 7;        //第二个船重量printf("第一个船重量:");scanf("%d",&c1);printf("第二个船重量:"); scanf("%d",&c2); cw = 0;bestw = 0;loadingRec(1);     //从第一个集装箱开始装箱printf("第一船的最优装载量为:%d\n", bestw);printf("第一船的最优解为");for (int i = 1; i <= n; i++)printf("%d ", bestx[i]);//求剩余集装箱的重量int cw2 = 0;for (int i = 0; i <= n; i++)if (bestx[i] == 0)cw2 += w[i];if (cw2>c2)printf("无法将剩余集装箱转入第二船,问题无解");elseprintf("可以将剩余集装箱装入第二船,问题有解");getchar();
}

(3)分支限界法

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<queue>
#define num 100
float w[num];   //集装箱重量
int x[num]; //解
float c;
int n;  //集装箱个数
float bestw;
using namespace std;
template<class Type>
class HeapNode;
template<class Type>
class bbnode;
template<class Type>
void AddLiveNode(priority_queue<HeapNode<Type> > &H,bbnode<Type>  *E,Type wt,bool ch,int lev);
template<class Type>
Type MaxLoading(Type w[],Type c,int n,int bestx[]);
template<class Type>
class bbnode
{friend void AddLiveNode<Type>(priority_queue<HeapNode<Type>  > &H,bbnode<Type>  *E,Type wt,bool ch,int lev);friend Type MaxLoading<Type>(Type*,Type,int,int*);friend class AdjacencyGraph;//邻接矩阵public:bbnode<Type> *parent;//指向父节点的指针bool Lchild;//左儿子结点标志
};
template<class Type>
class HeapNode
{friend void AddLiveNode<Type>(priority_queue<HeapNode<Type> > &H,bbnode<Type>  *E,Type wt,bool ch,int lev);friend Type MaxLoading<Type>(Type *,Type,int,int*);public:operator Type () const{return uweight;}public:bbnode<Type>  *ptr;//指向活结点在子集树中相应结点的指针Type uweight;//活结点优先级(上界)int level;//活结点在子集树中所处的层序号
};
//将活结点加入到表示活结点优先队列的最大堆H中
template<class Type>
void AddLiveNode(priority_queue<HeapNode<Type>  > &H,bbnode<Type>  *E,Type wt,bool ch,int lev)
{bbnode<Type>  *b = new bbnode<Type> ;b->parent = E;b->Lchild = ch;HeapNode<Type>N;N.ptr = b;N.uweight = wt;N.level = lev;H.push(N);
}
//优先队列式分支限界法,返回最优载重量,bestx返回最优解
//优先级是当前载重量+剩余重量
template<class Type>
Type MaxLoading(Type w[],Type c,int n,int bestx[])
{priority_queue<HeapNode<Type> > H;//定义最大堆的容量为1000Type *r = new Type [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 <Type> *E = 0;//当前扩展结点Type 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<Type>N =H.top();//取下一扩展结点H.pop();//下一扩展结点,将最大值删去i = N.level;E = N.ptr;Ew = N.uweight - r[i-1];//当前优先级为上一优先级-上一结点重量}//构造当前最优解,类似回溯的过程for(int j = n;j > 0;j--){bestx[j] = E->Lchild;E = E->parent;}return Ew;
}
int main(){printf("轮船重量:");scanf("%f",&c);printf("请输入物品个数:");scanf("%d", &n);printf("物品的重量:");for(int i=1;i<=n;i++){scanf("%f",&w[i]);}bestw=MaxLoading<float>(w,c,n,x);cout<<"分支限界选择结果为:"<<endl;for(int i=1;i<=n;i++){cout<<x[i]<<" ";}cout<<endl;cout<<"最优装载重量为:"<<bestw<<endl;return 0;
}

实验结果:

(1)贪心算法

贪心算法并没有求得最优解。

(2)回溯法

(3)分支限界法

心得与体会:

1、 理解和复习贪心算法、回溯法、分支限界法的概念;

2、  掌握和复习贪心算法、回溯法、分支限界法的基本要素;

3、  掌握贪心算法、回溯法、分支限界法的优点和区别;

4、  通过应用范例掌握选择最佳算法的设计技巧与策略;

参考文章

https://blog.csdn.net/qq_43496675/article/details/106090334

https://blog.csdn.net/weixin_36888577/article/details/79937886

https://blog.csdn.net/weixin_44755413/article/details/106199259

https://blog.csdn.net/softwareldu/article/details/41170137

https://blog.csdn.net/xiaoquantouer/article/details/52015928

C++——《算法分析与设计》实验报告——箱子装载问题相关推荐

  1. 算法分析与设计实验报告 ——二分搜索程序算法的实现

    算法分析与设计实验报告 --二分搜索程序算法的实现 实验目的及要求 1.理解分治算法的概念和基本要素: 2.理解递归的概念: 3.掌握设计有效算法的分治策略: 4.通过二分搜索技术学习分治策略设计技巧 ...

  2. 算法分析与设计实验报告——实现汽车加油问题

    算法分析与设计实验报告--实现汽车加油问题 目录: 算法分析与设计实验报告--实现汽车加油问题 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与讨论 ...

  3. 算法分析与设计实验报告——二分搜索算法的实现

    算法分析与设计实验报告--二分搜索算法的实现 目录: 算法分析与设计实验报告--二分搜索算法的实现 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与 ...

  4. 中北大学算法分析与设计实验报告一(BF算法)

    中北大学算法分析与设计实验报告一(BF算法) 1.实验名称 实验一 算法基础实验:数理基础与串匹配程序设计 2.实验目的 以字符串匹配问题为例,结合C等编程语言和链表.堆.栈等数据结构知识,基于BF算 ...

  5. 算法分析与设计实验报告

    计算机算法分析与设计实验报告 实验一:递归回溯 阶乘(Factorial) #include<iostream> using namespace std; int factorial(in ...

  6. 中北大学算法分析与设计实验报告六(最大团问题)

    中北大学算法分析与设计实验报告六(最大团问题) 1.实验名称 实验六 回溯与分支限界算法实验 2.实验目的 题目:最大团问题 强化学生利用回溯算法和优化处理实际问题的能力. 3.训练知识点集群 (1) ...

  7. 算法分析与设计实验报告三——动态规划算法

    一.实验目的 掌握动态规划方法贪心算法思想 掌握最优子结构原理 了解动态规划一般问题 二.实验内容 编写一个简单的程序,解决0-1背包问题.设N=5,C=10,w={2,2,6,5,4},v={6,3 ...

  8. 南京邮电大学c语言实验报告4,南京邮电大学算法设计实验报告——动态规划法...

    <南京邮电大学算法设计实验报告--动态规划法>由会员分享,可在线阅读,更多相关<南京邮电大学算法设计实验报告--动态规划法(12页珍藏版)>请在人人文库网上搜索. 1.实 验 ...

  9. 2019春第二次课程设计实验报告

    2019春第二次课程设计实验报告 一.实验项目名称: 贪吃蛇游戏编写: 二.实验项目功能描述: 这个实验主要是实现游戏的正常运行,实现的目标是对小蛇移动的控制, 同时对小蛇数据的保存,如何实现转弯的效 ...

最新文章

  1. 推荐一个论文复现神器!
  2. 壕!甲骨文创始人 8000 万美元买豪宅后打算拆掉
  3. 认识StringBuffer类
  4. linux shell 中 printf 与 echo的区别
  5. 关于matlab中princomp的使用说明讲解
  6. cache性能分析实验 北邮_北邮人又获奖啦快来点赞!
  7. jQuery中的text()、html()和val()以及innerText、innerHTML和value
  8. php rmdir 返回值,php通过rmdir删除目录的简单用法
  9. 手写及场景文字分析与识别的一些新尝试
  10. Flutter布局锦囊---带输入字段的应用栏
  11. CCF NOI1138 高精度加法
  12. python中的join函数连接dataframe_python pandas处理CSV文件并使用join()方法拼接两个dataframe...
  13. Ubuntu 16.04 安装后网络、ssh禁止root、上传设置
  14. Linux下yum配置及相关问题
  15. ideal如何用标签输出_实战|如何使用JavaScript访问设备前后摄像头
  16. 计算机网络拓扑结构详解
  17. css 剪辑图片_[译]用CSS剪切圆形图片
  18. 腾讯云轻量服务器和虚拟主机有什么区别?
  19. 300最不常用的springboot计算机毕业设计题目汇总,总有你需要用到的
  20. 大脑小胶质细胞“隐藏技能”被发现

热门文章

  1. html手机pc不同页面,PC端和手机端如何同时生成静态页
  2. mysql 查询每人每天_PHP+MySQL实现对一段时间内每天数据统计优化操作实例
  3. c语言填空三个数找中间大小,计算机文化基础复习题及答案(精华)
  4. oracle 12c 自动任务,Oracle job自动任务实用指南
  5. wp comments post.php,通过修改wp-comments-post.php 防wordpress垃圾(spam)评论 | 沉默过客
  6. android studio编辑不了,无法在Android Studio中编辑文件
  7. java的imshow方法_如何在循环中使用子图,imshow或图形来显示所有图像?
  8. 计算机导航 骨科 ppt模板,(医学PPT课件)术中即时三维导航在脊柱侧弯矫形的应用...
  9. android python 纠正图片,Python脚本替换Android资源(包名,图片,文件内容)
  10. tensorflow打印模型图_[深度学习]TensorRT加速tensorflow实例