【数据结构】--C++实现箱子装箱问题

一、问题描述

①在箱子装载问题中,有若干个容量为c的箱子和n个待装载入箱子中的物品。物品i需占是s[i]个单元(0<s[i]<=c)。所谓成功装载(feasible packing),是指能把所有物品都装入箱子而不溢出,而最优装载(optimal packing)是指使用了最少箱子的成功装载。对于箱子装载问题,有4种流行的求解算法。

②基本要求:

->n依次取100,200,500,1000,比较以上四种方法(在时间上和所用箱子的数量上)的性能。

->FF,FFD方法使用竞赛树结构,BF,BFD使用二叉搜索树结构。

二、需求描述

1.4种流行的求解算法:

<1>最先匹配法(FF):物品按1,2...,n的顺序装入箱子。假设箱子从左至右排列,每一物品i放入可盛载它的最左箱子。

<2>最先匹配递减法(FFD):方法与FF类似,区别在于各物品首先按容量递减的次序排列,即对于1<=i<n,有s[i]>=s[i+1].

<3>最优匹配法(BF):设c[j]为箱子j的可用容量,初始时,所有箱子的可负载容量为c。物品i放入具有最小c且容量大于s[i]的箱子中。

<4>最优匹配递减法(BFD):方法与BF相似,区别在于各物品首先按容量递减的次序排列,即对于1<=i<n,有s[i]>=s[i+1].

2.输入要求:

①第一种输入方式:n在程序中固定读入100,200,500,1000个数,这些数预先在文本中手动输入为固定的无序正整数。

②第二种输入方式:n为程序运行后,人为输入的数n,并且生成n个随机数,用作程序所需要测试的物品大小数。

3.输出要求:

输出的要求为:直观的分析排列出在不同的箱子数量、不同的物品数量以及不同的物品大小的情况下,上述四种方法在时间上和所用的箱子的数量上的不同。

比较四种方法的性能。

4.界面设计:

使用的是程序运行控制台输出,没有使用图形化界面。

界面设计如图:

①第一种输入方式:

②第二种输入方式

5.测试设计:

使用第一种方式输入数据:首先分别将100,200,500,1000个数据输入到一个文本文件中,然后在程序中使用读取文件的方法将文本文件的数据当做程序的测试数据,进行测试实验。

读取文件的方法为:

使用的测试数据为:

①100个数据

 

②200个数据

③500个数据

④1000个数据

数据就是大同小异啦,自己建立txt文件输入数据就好

三、设计

3.1结构设计

①对于最先匹配法(FF)和最先匹配递减法(FFD)方法使用了竞赛树结构。

----->对于竞赛树的结构设计

*T[i]代表胜者

*P[I]代表参赛者

*当外部节点为n,则内部节点为n-1

*最底层最左端的内部节点编号为s

*最底层外部节点个数lowext=2(n-s)

*最底层内部节点个数为n-s

*令offset=2*s-1,对任何一个外部节点P[I],可根据公式得出其父节点

      (i+offset)/2                i<=lowext

 p=

      (i-lowext+n-1)/2        i>lowext

----->使用竞赛树对于上述方法的具体实现

*将竞赛树的外部节点当做容量为c的箱子,构建赢者树,先从左子树开始查找判断是否可以容纳物品,逐步向下寻找,因为内部节点返回的是外部节点的胜者(这里规定为箱子容量更大的一个作为胜者)即箱子号,便可以找到可以使用的箱子(即对应外部节点),在使用箱子后,箱子的容量减去物品大小,并重构赢者树,形成新的胜者。

*初始化时,对所有n个箱子,bin [i] .unused Capacity=bin Capacity。

 bin [i] 作为选用,对最大赢者树进行初始化。

*FF和FFD利用了数据类型bintype,该类型只有一个数据成员,unused Capacity 并重载了操作符<=,使表达式x<=y的值为真,当且仅当x.unused Capacity>=y.unused Capacity。

*FF和FFD假定,除非右边选手大于左边选手,否则左边选手为胜者。

*竞赛树是用数组表示的完全二叉树,它能按照数组的下标乘2或加1方式从上向下移动。

 

②对于最优匹配法(BF)和最优匹配递减法(BFD)使用了二叉搜索树结构。

----->对于二叉搜索树的结构设计

*对于二叉搜索树由链表描述,因为二叉搜索树的元素和形状随操作而改变,从链式描述二叉树类派生

*使用带有重复关键字的二叉搜索树能在O(nlogn)时间内实现最优匹配法。

*在根节点的左子树中,元素的关键字(如果有的话)都小于根节点的关键字。

*在根节点的右子树中,元素的关键字(如果有的话)都大于根节点的关键字。

*根节点的左、右子树也都是二叉搜索树。

----->使用二叉搜索树对于上述方法的具体实现

*在实现最优匹配法时,搜索树的每个元素代表一个正在使用且剩余容量不为0的箱子

*因为箱子不同,但剩余容量可能相同,可以用一棵带有重复关键字的二叉搜索树来描述箱子,每个箱子的剩余容量作为节点的关键字。

*节点的内部值为箱子的剩余容量,节点外部是箱子的名称。

*从根节点开始(左小右大),右子树均可以,则先进入左子树进行查找,若满足可装载,则成为候选者,再进入左子树,若不满足则进入其右子树一直往下找,直到没有子树,则没有更好的候选者,所以箱子i即是要找的箱子。

*当物品i找到最匹配箱子后,可将它从搜索树中删除,将其剩余容量减去s[i]再将它重新插入树中(除非它的剩余容量为0),若没有找到最匹配的箱子,则启用一个新箱子。

*对于二叉搜索树的元素类型是一个偶对pair<const K,E>,其中K是关键字类型,E是相应的元素的数据类型。

 

3.2类设计(共设计了5个类来完成整个程序)

①竞赛书实例

{ 实例:

       完全二叉树,每个节点指向比赛胜者,外部节点表示参赛者

 操作:

       Initialize(a);

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值