一种求解一维装箱问题的近似算法的研究

一种求解一维装箱问题的近似算法的研究
一种求解一维装箱问题的近似算法的研究

摘要

一维装箱问题来源于人们的长期以来的生产实践,是一种组合优化问题。给定有穷个物体,每个物体的重量是已知的正实数。给定足够多个空箱子,问题是要在满足两个约束条件的前提下,将所有物体放到箱子中去,使得所用箱子的个数尽可能地少。两个约束条件是:第一,每个物体均保持完整,恰好放到一个箱子中去。不能将物体分割成几块。第二,每个箱子中所放的物体的重量之和均不能超过一个相同的上限,这个上限是一个已知的正实数。

一维装箱问题具有很高的理论价值和实际价值。一方面,学者已经证明一维装箱问题是一个NP难度问题,因此一维装箱问题具有很高的理论价值。另一方面,一维装箱问题出现在实际生产的一些领域,因此也具有很高的实际价值。

迄今为止,国内外学者提出了许多用来求解一维装箱问题的严格算法和近似算法。一方面,严格的最优算法所花时间太长,实际部门无法忍受。另一方面,近似算法由于可能快速地生成最优解或者接近最优解而为实际生产部门所广泛采用。

人类把物体往容器中装,已有几千年以上的经验。这些生活经验可引导出高效率的算法。本文提出了一种拟人算法。算法由三个部分组成。第一部分是降序最佳适合算法,用于生成初始解。第二部分是邻域搜索算法。给定一个解,用邻域搜索算法可以通过迭代改进这个解。本文的邻域定义的思想来源于“天之道损有余而补不足”。第三部分是跳坑策略。跳坑策略用于跳出局部最优解,将搜索引向有希望的区域,从而提高算法的效率。跳坑策略的思想来源是“三十六计走为上”。

本文的程序计算了一组共17个国际公认的问题实例。这组问题实例分为两类。第一类为8个问题实例,目前尚未确定其客观最优解。第二类为9个问题实例,目前已经确定了其客观最优解。拟人算法对第一类问题实例中的6个问题实例找出了与当前已知最好解质量相同的解。拟人算法还证明了TEST0068这个问题实例的目前已知最好解正是客观最优解。拟人算法快速地找出了第二类问题实例中全部9个问题实例的客观最优解。

计算结果表明,拟人算法是一种有效的求解一维装箱问题的近似算法。

关键词: NP难度;拟人;邻域搜索;跳坑;装箱

Abstract

The one dimensional bin packing problem, which is a famous combinatorial optimization problem, comes from long term practice of human being. The definition of the one dimensional bin packing problem discussed in this paper is as following. Given n items and enough identical bins, the weight of each item is a known positive real number. The capacities of all bins are equal. The problem is to pack all items into the bins with the objective of minimizing the number of occupied bins, subject to two following constraints. (1) Each item is packed into exact one bin. Each item cannot be divided into several parts and put into different bins. (2) The sum of weight of all items of each bin cannot exceed its capacity.

The one dimensional bin packing problem is of both highly theoretical and practical values. On one hand, the one dimensional bin packing problem has been proved to be NP-hard. On the other hand, the one dimensional bin packing problem appears in some real world factories.

So far, many exact algorithms and approximation algorithms have been proposed to solve the one dimensional bin packing problem. Exact algorithms require too much computing time and cannot be accepted by workers. On the other hand, approximation algorithms are widely used by workers, since they may give optimal or near optimal solutions quickly.

Mankind have more than several thousands of years of experience to pack items into containers. The experience can induce efficient algorithm. A quasi-human algorithm is presented in this paper, which is composed of three parts. The first part is best fit decreasing algorithm to generate initial solution. The second part is local search algorithm. Given a solution, local search algorithm is used to improve this solution by iterative steps. The idea of the definition of the neighborhood comes from a Chinese motto “It is the Way of Heaven to diminish superabundance, and to supplement deficiency”. The third part is off-trap strategy, which is used to jump off local optimum and guide the search into promising areas, so as to improve the algorithm. The idea of the off-trap strategy comes from a Chinese motto

“decamping being the best”.

Computational experiments are carried out on a set of 17 benchmark problems. This set of 17 benchmark instances can be divided into two classes. The first class consists in 8 instances whose optimal solutions are still unknown. The second class consists in 9 instances whose optimal solutions are already known. For 6 out of 8 instances of the first class, our algorithm finds out solutions which are equal to the best known solutions up to now. Our algorithm proves that the best known solution for benchmark instance named as TEST0068 up to now is optimal. For all 9 instances of the second class, our algorithm finds out optimal solutions quickly.

The results show that the quasi-human algorithm is an efficient algorithm for the one dimensional bin packing problem.

Keywords: NP-hard; Quasi-human; Local search; Off-trap; Bin packing

目录

1 绪论 (1)

1.1 引言 (1)

1.2 问题描述 (1)

1.3 研究现状 (2)

1.4 本论文的主要结构 (5)

2 算法描述 (6)

2.1 拟人算法的大致框架 (6)

2.2 生成初始解 (7)

2.3 邻域搜索 (7)

2.4 跳坑策略 (9)

3 程序设计 (11)

3.1 程序流程 (11)

3.1.1 读取文本文件中的数据 (13)

3.1.2 生成初始解 (13)

3.1.3 邻域搜索 (14)

3.1.4 释放内存 (15)

3.2 调试程序 (15)

4 计算结果 (16)

5 结论 (18)

参考文献 (19)

致谢 (21)

1 绪论

1.1 引言

当前世界经济高速发展,人口日益增加,资源日渐紧张。人们在生产生活中希望提高效率,节约资源,以实现可持续发展。在运筹学领域有一类所谓最优化问题。最优化问题的一般形式是:在满足约束条件的前提下,给出自变量的值,使得目标函数值最优 (通常是使得目标函数值最小或者最大)。

一维装箱问题[1]来源于人们的长期以来的生产实践,是一种最优化问题,一维装箱问题具有很高的理论价值和实际价值。

一方面,学者已经证明一维装箱问题是一个NP 难度问题,因此一维装箱问题具有很高的理论价值。在现实的工业、商业、交通、通信、军事等领域出现了大量的所谓NP 难度问题,例如车间调度问题、货郎担问题等等。人们虽然目前不能证明,但是强烈相信NP 难度问题不存在时间复杂度为多项式的完整算法。所谓完整算法,对于优化问题来说就是能保证找到最优解的算法,对于判定问题来说就是能够保证正确判定的算法。

另一方面,一维装箱问题出现在实际生产的一些领域,因此也具有很高的实际价值。

世界各国学者已经对一维装箱调度问题做了数十年的研究,人们还提出了许多种算法来求解一维装箱调度问题。

另外,在现实中存在二维、三维、多维的装箱问题。本文仅讨论一维装箱问题。

1.2 问题描述

本文研究的这种一维装箱问题的描述如下。给定有穷个物体,每个物体的重量是已知的正实数。给定足够多个空箱子,问题是要在满足两个约束条件的前提下,将所有物体放到箱子中去,使得所用箱子的个数尽可能地少。两个约束条件是:第一,每个物体均保持完整,恰好放到一个箱子中去。不能将物体分割成几块。第二,每个箱子中所放的物体的重量之和均不能超过一个相同的上限,这个上限是一个已知的正实数。 为了将问题描述得确切,本文提出一种形式化描述。

{}n I I I ,,1 =表示物体的集合。

j w 表示物体j I 的重量。

c 表示每个箱子所能容纳的物体的重量之和的上限。

{}m B B B ,,1 =表示所用箱子的集合。

?????=中。没有放在箱子如果物体中;放在箱子如果物体i j i j ij B I B I P ,

0,1 I ,j w ,c 是已知的。{}m B B B ,,1 =和ij P 是变量。

问题是要在满足如下两个约束条件的前提下,使得所用箱子的个数m 尽可能地小。 ∑=i

ij P

1 (1.1) ∑≤?j j ij c w P (1.2)

其中n j ≤≤1,m i ≤≤1。

1.3 研究现状

当前求解NP 难度问题的算法分为两类:完整算法和近似算法。以一维装箱问题为例,本文介绍这两类算法。

完整算法[2]也称为严格算法,其本质是毫无遗漏的穷举,因此能保证找到问题的最优解,这是完整算法的优点。完整算法的缺点是计算时间太长,实际部门无法忍受,因此只能用于计算较小规模的问题实例。

近似算法是当前研究的主要方向。当今时代,在纯粹科学研究,通信、交通运输、工程设计和企事业管理部门,在社会的军事、政治和商业的斗争中涌现出大量NP 难度的问题。若按经典的纯粹数学家们所熟悉的穷举方法来求解,则计算时间动辄达到天文数字,根本没有实用价值。学术界许多有经验的人认为对于这些问题根本上就不存在完整、精确而不是太慢的求解算法。

于是人们寄希望于非完整的启发式算法。启发式算法属于近似算法。这种算法对于很刁钻古怪的例子可能会失败,但在通常面临的实际情况下却能算得既精确又相当地快。

到哪里去寻求启发?这是一个根本的难点。中国古代的画论有“外师造化内得心源”的说法,即认为智慧应源于大自然与自身的心灵。事实上,自然界中的各种现象以及人类共同生活中的社会经验,尤其是处理相互关系中许多矛盾的各种公关手腕都是很好的源泉。许多数学中的概念方法与策略事实上都是来源于人类对大自然的观察,来源于他们在社会中生存奋斗的社会经验。

拟物拟人的途径,本来就是科学的正统,而不是邪门歪道。随着新的有意义的困难问题例如NP难度问题的涌现,公理化符号化的方法会逐渐显出自己的不足,朴素的拟物拟人的途径会逐渐被人们所选用。

特别值得指出的是,对于所得的启发式算法,在遇到刁钻的实例而表现出疲软失败的时候,人们可以十分自然地通过分析算法在该次失败中的表现而对它有针对性地加以改善和强化。经过若干次自然的改善和强化之后,一个从实用角度看来叫人很是满意的算法就会呈现在我们的面前[3]。

人们或者运用自身的智慧,或者从大自然得到启发,同时运用良好的编程技术,经常能设计出很好的近似算法,有可能在较短时间内求解大规模问题实例,并达到令人满意的精确度。这种方法被实际部门广泛的使用。这是一条现实的路线。近似算法主要分为以下几种类型:

①拟物算法和拟人算法。拟物算法和拟人算法是黄文奇提出的用于求解NP-hard难度问题的近似算法。拟物方法[4]是一个许多人会感到有趣有用的方法。其工作路径是,到物理世界中去寻找出与原始数学问题等价的自然现象,然后观察其中物质运动的演化规律,从中受到启发以得出形式化的、对于数学问题的求解算法。单纯的拟物方法就已能解决许多问题[5][6]。在遇到刁钻的问题时还可以将拟物方法和拟人方法联合使用形成所谓拟物拟人方法[7]。对其工作的方式可作如下解释、描叙和评论。

由于物理状态的演化天然地是按照使其Lagange函数的时间积分达到最小值的方式进行,这就决定了拟物算法最终在数学上落实为优化问题。然而用数学方法求解优化问题,常常会碰到计算落入局部极小值陷阱的困难境地,对于如何跳出局部极小值陷阱,让计算走向前景更好的区域中去的问题,拟物方法已无能为力。但是,人类在最近几千年的共同生活中形成了丰富的社会经验,利用这些经验往往可以启发出好的“跳出陷阱”的策略。我们可以将这种把人类的社会经验形式化为算法用以求解某些特殊困难问题的数学问题的方式称为拟人途径[8]。

拟物拟人算法的效率通常比生物遗传算法、神经网络算法、淬火算法要高,其原因是它有针对性地为具体问题找到了非常贴切的物理世界,而不是像在遗传、神经网络、淬火方法中那样依赖于一个惟一的始终不变的因而往往是不太贴切的物理体系。另外,拟人方法是向人学习,而人比遗传、神经网络、淬火世界里的那些蛋白质、单个的神经元及晶体显然有高得多的智慧。当然,这里的关键在于合适的数学形式化前夜的艺术和手段,要得到它们也不是一件很容易的事情,需要长期艰苦细心的工作。这种得出算法的过程的艰苦性,可以说是拟物拟人途径的一个缺点。

另外,生物遗传算法、神经网络法、淬火法虽然针对性较差,但其适应性较强,并且亦有其深刻的思想根源和自然背景。在肯动脑筋并且机遇好的时候,拟物拟人与生物遗传算法、神经网络法、淬火法能结合得很好,能产生新的效能更高的算法。

至于纯粹的拟人方法[9][10],其途径是将人类在最近几千年的生存斗争中所形成的某

些经验某些作法说完整说清楚,然后加以抽象化形式化,最后形成算法以求解NP难度问题。

此方法的关键难点在于为给定的NP难度问题找到相应的有悠久历史的人类活动。但是一旦找到,必然能很顺利地发展为高效能的求解算法。

②优先分配规则算法。人们最早提出的求解一维装箱问题的近似算法是优先分配规则算法。优先分配规则算法以某种优先序依次给定将所有物体装入某个箱子。优先分配规则算法的速度非常快,但是其生成解的质量仍有改进的余地。因为优先分配规则算法速度很快,所以很多学者采用优先分配规则算法来生成初始解。本文介绍降序首次适合算法(first fit decreasing)和降序最佳适合(best fit decreasing)算法。降序首次适合算法是将所有物体按照重量从大到小的顺序排成一个物体序列,然后依次取出序列中的一个物体,在所有能放下这个物体的箱子中,选取序号最小的箱子,把物体放进去。降序最佳适合算法是将所有物体按照重量从大到小的顺序排成一个物体序列,然后依次取出序列中的一个物体,在所有能放下这个物体的箱子中,选取空余最小的箱子,把物体放进去。

③局部搜索(local search)算法。局部搜索算法给出的解的质量比优先分配规则算法高。局部搜索算法的工作过程是一个迭代的过程:从初始给定的解开始,所有物体装在有穷个箱子中。取出第一个箱子中的所有物体,装入其他箱子。此时某些箱子可能会超重,这是一个格局,称为一个点。然后在与当前格局相近的格局集合(即当前点的邻域)中搜索比当前格局更好的格局。如果在邻域中找到了比当前格局更好的格局,那么接受这个更好的格局,然后继续做迭代。如果当前格局的邻域中没有比当前格局更好的格局,也就是说,当前格局是局部最优解,那么算法停机。具体来说,有两种搜索策略。第一种搜索策略叫做“见好就收”:检查当前格局的邻域,一旦找到比当前格局好的格局,就接受这个格局,这样就做完了一次迭代,然后继续做迭代;如果当前格局的邻域中没有比当前格局更好的格局,那么邻域搜索停止。第二种搜索策略是找到邻域中最好的格局,如果比当前格局好,就接受这个格局,这样就做完了一次迭代,然后继续做迭代;如果当前格局的邻域中没有比当前格局更好的格局,那么邻域搜索停止。当邻域搜索停止时,如果对应一个解,则接受这个解,继续从新解开始做邻域搜索。如果不对应一个解,则回到当前解,取出第二个箱子中的所有物体,装入其他箱子。此时得到一个格局,从这个格局开始做邻域搜索。依次类推。如果在当前解取出最后的箱子中的所有物体,装入其他箱子。从这个格局开始做邻域搜索,无法得到比当前解更好的解,则算法停机。

④禁忌搜索(tabu search)算法。禁忌搜索算法是基于局部搜索的一种算法,它可以看作是局部搜索算法的一种改进算法。禁忌搜索算法由Glover[11]提出。禁忌搜索算法可用于求解各种组合优化问题人们已经提出了多种求解一维装箱问题的禁忌搜索算法[12]。禁忌搜索算法生成解的质量较高。禁忌搜索算法的工作过程是一个迭代的过程。从

初始给定的解开始,所有物体装在有穷个箱子中。取出第一个箱子中的所有物体,装入其他箱子。此时某些箱子可能会超重,这是一个格局,称为一个点。然后在与当前格局相近的格局集合(即当前点的邻域)中搜索比当前格局更好的格局。算法找到当前格局的邻域中目标函数值最小的格局,不论这个格局的目标函数值是否比当前格局小,都接受这个格局。这样就做了一次迭代。然后继续做迭代。像这样做迭代,很容易陷入循环。为了防止循环,禁忌搜索算法设置一个名为禁忌表的数据结构。禁忌表中记录着在最近若干次迭代中访问过的格局,如果这些格局在当前格局的邻域中,那么就把它们从邻域中清除掉。这样就能够在一定程度上避免循环,从而提高搜索效率。因为禁忌搜索会接受比当前格局差的格局,所以它能够跳出局部最优点。当禁忌搜索因为搜索限定时间到而停止时,如果找到了一个解,则接受这个解,将这个解作为当前解,继续做禁忌搜索。如果没有找到一个解,,则回到当前解,取出第二个箱子中的所有物体,装入其他箱子。此时得到一个格局,从这个格局开始做禁忌搜索。依次类推。如果在当前解取出最后的箱子中的所有物体,装入其他箱子。从这个格局开始做禁忌搜索,无法得到比当前解更好的解,则算法停机。

⑤模拟退火算法。模拟退火算法也是基于局部搜索的一种算法。模拟退火算法也可用于求解各种组合优化问题,包括一维装箱问题[13]。模拟退火算法检查当前格局的邻域中的格局,如果邻域中的这个格局比当前格局好,则一定接受这个格局;否则以一个大于0 同时小于1 的概率接受这个格局。与禁忌搜索算法一样,模拟退火算法也能跳出局部最优点。

⑥遗传算法。遗传算法可用于求解一维装箱问题[14]。遗传算法的工作过程也是迭代的过程。与局部搜索算法、禁忌搜索算法和模拟退火算法不同的是,遗传算法是将当前一组格局更新为另外一组格局,而不是将当前一个格局更新为另外一个格局。遗传算法首先随机生成一组格局做为所谓初始种群,然后对种群做迭代:从当前种群(当前这组格局)中选择一些格局,对这些格局做遗传操作(交叉、变异等),从而得到一组新的格局(即一个新的种群)。

1.4 本论文的主要结构

本学位论文主要由五个部分组成,其内容具体安排如下:

第一部分是绪论。主要介绍了本课题的来源、选题背景、问题描述和论文的主要结构。

第二部分介绍算法描述。

第三部分介绍程序设计。

第四部分介绍程序运行的结果。

第五部分是本课题研究的结论。

2 算法描述

人类把物体往容器中装,已有几千年以上的经验。我们可以利用这些生活经验来发展出高效率的算法。

本文提出的这种算法是一种拟人算法。算法由三个部分组成。第一部分是降序最佳适合算法(best fit decreasing )用于生成初始解。第二部分是邻域搜索算法。给定一个解,用邻域搜索算法可以通过迭代改进这个解。第三部分是跳坑策略。跳坑用于跳出局部最优解,将搜索引向有希望的区域,从而提高算法的效率。算法三个部分的思想来源均为人类的生产和生活经验,本算法是由拟人途径得到的。

定义2.1 某些物体在箱子里,其余物体在箱子外,这称为一个格局。

初始格局是所有物体均在箱子外,所有箱子均为空。与初始格局对称的终止格局是所有物体均在箱子里。

终止格局的形式化描述为:整数变元1x ,…,n x 的一组指派表示一个终止格局,其

中i x j =表示物体j I 放在箱子i B 中,n j ≤≤1,m i ≤≤1。把对整数变元1x ,…,n x 的一组指派看成{}n m ,,1 空间中的一个点X ,将与点X 在一个、两个或更多个变元上取值不同的点的集合称为X 的邻域。

考虑一个终止格局,如果每个箱子中所装的物体的重量之和均不超过上限,则此终止格局对应着一个解。

2.1 拟人算法的大致框架

步骤一(初始解的生成):调用一种简单好想的构造型算法生成初始解。该构造型算法见2.2节。转步骤二。

步骤二(判断停机条件):判断停机条件是否满足,若满足则停机,输出本次计算过程中所找到的最好的解。若不满足停机条件,则转步骤三。停机条件恰有两个:第一,客观最优解已经找到。第二,跳坑次数已经达到上限。只要满足其中一个条件,则算法停机。

步骤三(邻域搜索):从当前解出发,调用邻域搜索算法进行计算,试图寻找一个比当前解更好的解。该邻域搜索算法见2.3节和2.4节。邻域搜索算法执行完毕后,转步骤二。

2.2 生成初始解

步骤一:开局。将所有物体按照重量从大到小的顺序排好序。这个物体序列记为n I I ,,1 。所有物体均在箱子外面。将物体1I 放在箱子1B 中。转步骤二。

步骤二:考虑当前格局。如果所有物体均在箱子里面,则生成了初始解。如果至少有一个物体在箱子外面,则按照如下手法将一个物体放入箱子。在当前格局中,物体j I I ,,1 在箱子i B B ,,1 里,物体n j I I ,,1 +在箱子外。如果箱子i B B ,,1 中的每一个均不

能容纳1+j I ,则将1+j I 放入箱子1+i B 。如果箱子i B B ,,1 中的若干个箱子能容纳1+j I ,则选

取在当前格局空余最小的箱子(如果空余最小的箱子不止一个,则选取其中编号最小的箱子),将1+j I 放入,从而演化到新格局。转步骤二。

2.3 邻域搜索

本文提出的邻域搜索的思路来源于人们用箱子装物体的实际经验。当n 个物体装在m 个箱子中,首先任意取一个装了物体的箱子,取出其中全部物体,装到其它已装有物体的箱子中去。此时很可能有某些箱子中的物体重量超过上限。然后根据某种方法进行调整,试图使得每个箱子中的物体重量均不超过上限。最终邻域搜索的结果恰有两种:或者成功,或者失败。

步骤一:考虑当前解。将当前解的格局记录下来,记为rn utionPatte CurrentSol 。物体n I I ,,1 放在箱子m B B ,,1 中。令1=k 。转步骤二。

步骤二:如果m k >,则邻域搜索结束。如果m k ≤,则取出箱子k B 中的所有物体,

将1+k B 的编号改为k B ,…,将m B 的编号改为1-m B 。按照从重量大到小的顺序,依次将

物体放入已装物体重量之和最小的箱子(如果已装物体重量之和最小的箱子不止一个,则选取序号小的箱子),从而演化到新格局。如果无超重的箱子,则新格局是一个解。将这个解作为当前解,邻域搜索结束。如果有超重的箱子,无不满的箱子,则当前解是客观上的最优解,停机。如果既有超重的箱子,又有不满的箱子,则转步骤三。 步骤三:进行调整。如果经过调整后,得到了一个比当前解更好的解,则接受这个解,邻域搜索结束。如果没有找到一个比当前解更好的解,则返回到当前解的格局rn utionPatte CurrentSol 。1+=k k 。转步骤二。

所谓调整,是一个迭代的过程。已知一个终止格局,用一个新的终止格局取代老的终止格局,这是迭代的一步。

在叙述如何进行迭代之前,要给出邻域的定义。

取一个超重的箱子,记为α。取一个不满的箱子,记为β。现在要将α中的若干物体放入β中,将β中的若干物体放入α中。目的是要减轻α中物体的重量,增加β中物体的重量。中国人有句格言“天之道损有余而补不足[15]”。我们所设计的邻域是基于这句格言的。

我们采用的目标函数是由Fleszar 和Hindi [16]提出的目标函数。给定一个终止格局,目标函数值等于所有箱子中的物体重量的平方的和。调整的目的是要在所用箱子数不变的前提使得目标函数值尽可能地小。形式化描述如下:

minimize ()∑==m

i i L f 12 (2.1)

其中m 是所用箱子数,i L 是箱子i B 中所装物体重量。

对于点X ,X '是X 的一个邻点。若)()(X f X f <',则称X '为X 的邻域中的下降点。 第一种邻域记为)0,1(Swap 。将超重的箱子α中的一个物体取出放入不满的箱子β。 第二种邻域记为)1,1(Swap 。将超重的箱子α中的一个物体与不满的箱子β中的一个物体交换。

第三种邻域记为)2,1(Swap 。将超重的箱子α中的一个物体与不满的箱子β中的两个物体交换。

第四种邻域记为)3,1(Swap 。将超重的箱子α中的一个物体与不满的箱子β中的三个物体交换。

可以推广到)4,1(Swap ,...,),1(βn Swap ,其中βn 是箱子β中所装的物体个数。 因为有了)0,1(Swap ,则)0,2(S w a p 不必考虑。)0,2(Swap 可以用两次)0,1(Swap 取代。

第五种邻域记为)1,2(Swap 。将超重的箱子α中的两个物体与不满的箱子β中的一个物体交换。

第六种邻域记为)2,2(Swap 。将超重的箱子α中的两个物体与不满的箱子β中的两个物体交换。

可以推广到)3,2(Swap ,...,),2(βn Swap ,其中βn 是箱子β中所装的物体个数。

Loh ,Golden 和Wasil [1]提出了两种邻域)0,1(Swap 和)1,1(Swap 。Fleszar 和Hindi [16]提出了两种邻域)2,1(Swap 和)2,2(Swap 。本文提出的邻域与这些邻域类似。差别在于本文考虑一个超重的箱子和一个不满的箱子。文献[1][16]考虑任意两个箱子。已知一个点,考虑其邻域,若一个邻点对应的目标函数值严格小于当前点对应的目标函数值,则这个点称为下降点。

微调的思路如下所述。

第一,从一个给定的终止格局X 开始,这是初始点。

第二,设在任一时刻X 的值)(t X 已算出,首先按照某种自然的顺序依次考虑当前点)(t X 的邻点。若下降点集非空,则用第一个下降点作为X 在1+t 时刻的值)1(+t X 。我们将这种从)(t X 到)1(+t X 的过渡称为下降步骤。若下降点集为空,则已知)(t X 点为函数f 的局部最小值点,于是按照某种基于拟人思路的“跳坑”策略将计算从)(t X 点跳到其邻域中的一个确定的新点)1(+t X 。我们可将这种从)(t X 到)1(+t X 的过渡称为逃出步骤。 以上思路虽然是本质的,但有一个小漏洞需要补平。即在逃出步骤中,若点)(t X 按照跳坑策略逃出到)1(+t X ,则很可能从)1(+t X 的角度来看,老点)(t X 是)1(+t X 的邻域中的下降点,于是很有可能从)1(+t X 出发的下降步骤是回到)(t X 。即计算走了回头路。 为补平这一漏洞,我们可以设置变元禁集。这样,我们的寻优搜索的思路框架被发展为如下步骤:

步骤一:从一个给定的终止格局X 开始,这是初始点。将变元禁集之初始集赋为空集。转步骤二。

步骤二:考虑当前点的邻域。有些邻点是由对禁集中的变元赋值而得到的。除去这样的邻点不考虑。按照某种自然的顺序考察邻域,如果找到了一个下降点,则见好就收,接受此下降点。如果对邻域搜索完毕,没有找到下降点,则按跳坑策略跳到一个点。转步骤三。

步骤三:若当前点对应一个解,则停止。若计算时间已超限,则停止。否则更新变元禁集。

以下我们描述跳坑策略和更新变元禁集的步骤。

2.4 跳坑策略

当前点为局部最小值点,在所有超重的箱子中均匀地随机选取一个箱子

B,在这个

x

箱子中的所有物体中均匀地随机选取一个物体

I,在所有不满的箱子中均匀地随机选取

x

一个箱子

B,将x I从x B中取出,放入y B。

y

这个跳坑策略的思想来源依然是“天之道损有余而补不足”。

变元禁集的演化规则如下:

第一,如果从老点)(t

X是按下降步骤操作的,则置变元禁集为空。

X到)1(+t

第二,如果从老点)(t

X是按逃出步骤操作的,则将对应的变元加入变元禁集。

X到)1(+t

3 程序设计

本文的程序设计采用已故卓越美籍荷兰裔计算机科学家Edsger Wybe Dijkstra提出的结构化程序设计思想。

Edsger Wybe Dijkstra早在1951年就学习了计算机程序设计,然后参与了一些荷兰的大工程例如Fokker友谊飞机的开发,其中机翼震动的计算需要编写程序。因为编写庞大程序的需要,Edsger Wybe Dijkstra提出了结构化程序设计思想。

结构化程序设计可归纳为“自顶向下,逐步求精”。结构化程序设计由计算机科学家提出,但是其思想根源并不是纯粹科学,而是人类在长期生存斗争中的经验。军事家提出“分而治之”,“集中优势兵力,各个歼灭敌人”。这些说法是结构化程序设计思想的来源。在军事上,如果敌人多而且强,则设法将敌人分割,集中兵力和火力将敌人各个歼灭。作者在写程序时,如果程序难而且复杂,不好写,则首先将程序分成一些模块,然后集中思维和时间去写每一个模块的程序。

所谓“自顶向下”是指首先将程序分割为几个大模块,从而写出主函数main()的程序,然后对复杂的大模块,再分割成若干小模块,如果小模块仍然较复杂,则依此类推,继续分割,直到小模块容易被编程者写出程序为止。

所谓“逐步求精”是指在分割程序的过程中,程序的面貌越来越清晰,针对每个小模块,写出清晰的程序。最终将所有模块合并,成为所需要的完整的程序。

作者对面向对象的程序设计也曾经浅尝。结构化程序设计思想与面向对象的程序设计思想并无实质性矛盾,在需要引入对象概念的场合,这两者可以很好地结合。例如可以采用结构化程序设计来写底层的核心的程序,采用面向对象的程序设计来设计外表的吸引人的界面。

3.1 程序流程

整个程序的流程如图3.1所示。整个程序可分为四个模块。

第一个模块是读取文本文件中问题实例的数据,调用库函数malloc()为各种数据结构分配内存。这个模块的程序简单,无需再分解。

第二个模块是生成初始解。这个模块的程序较简单,无需再分解。

第三个模块是邻域搜索。这个模块是重点,程序复杂,本身需分成一些更小的模块。

第四个模块是释放内存。这个模块的程序最简单,只需调用库函数free()就可以,无需再分解。

图3.1 整个程序的流程

作者写程序时遵循如下四条原则。

第一,要有整块的时间来写程序,不要烦,不要急。

第二,要有好的草稿纸,举个例子,画图辅助自己写程序。

第三,草稿纸要写得干净,不要折,写上页码,作为原始文档好好保存。第四,自顶向下,逐步求精。

3.1.1 读取文本文件中的数据

一个benchmark问题实例存储在一个文本文件中,以名为TEST0005的问题实例为例,存储在名为TEST0005.txt的磁盘文件中,其格式如下。

第1行:57 表示物体的重量总共恰有57种不同的重量。

第2行:10000 表示箱子的容量是10000。

第3行:4964 3 表示重量为4964的物体恰有3个。

依此类推。

第59行:40 2 表示重量为40的物体恰有2个。

在C语言中,要读取文本文件中的数据,首先定义一个FILE类型的指针FP,然后利用库函数fopen()来打开文件,例如FP = fopen("e:\\TEST0005.txt","r"),其中e:\\TEST0005.txt是文本文件所在目录以及文件名,r表示以只读方式打开文件,最后利用库函数fscanf()文件指针,格式字符串,变量地址)来读取文本文件中的数据,例如fscanf(FP,"%d",&numberOfDifferentItemWeights)表示读取FP指针指向的文本文件中一个符号串,将其转化为十进制整数,存储在变量numberOfDifferentItemWeights中。

本文的程序采用库函数malloc()来给数据分配内存。与之对称地,当程序运行结束的前夕,调用库函数free()来释放用malloc()分配的内存。

本模块中使用的主要数据结构如下。

int NUMBER_M_OF_DIFFERENT_ITEM_WEIGHTS表示物体总共有多少种不同的重量。

int CAPACITY_C_OF_THE_BINS表示箱子容量。

int * ITEM_WEIGHTS是整型数组名,此数组记录所有不同的重量的值。

int * NUMBER_OF_ITEMS_OF_WEIGHTS是整型数组名,此数组记录每种重量的物体有多少个。

int NUMBER_OF_ITEMS表示物体总数。

int * WEIGHT_OF_ITEMS是整型数组名,此数组记录每个物体的重量。

NUMBER_M_OF_DIFFERENT_ITEM_WEIGHTS,CAPACITY_C_OF_THE_BINS,ITEM_WEIGHTS,NUMBER_OF_ITEMS_OF_WEIGHTS是题目给定的,可以直接从文本文件中读取。NUMBER_OF_ITEMS,WEIGHT_OF_ITEMS可以根据已知的信息算出。

3.1.2 生成初始解

生成初始解的函数命名为generate_initial_solution()。此模块中所使用的主要数据结构如下。

int * BIN_NUMBER_OF_ITEMS记录在初始解中,每个物体放在哪个箱子中。

int * SPARE_SPACE_OF_BINS记录每个箱子的剩余空间。

int NUMBER_OF_OCCUPIED_BINS表示使用的箱子数。

int ** ITEMS_NUMBER_IN_EACH_BIN是二维整型数组名,其中记录每个箱子中放了哪些物体。

程序生成初始解后,将初始解作为当前解。有_IN_CURRENT_SOLUTION_PA TTERN 后缀的变量是属于对应当前解的终止格局的。

int * BIN_NUMBER_OF_ITEMS_IN_CURRENT_SOLUTION_PA TTERN表示在对应当前解的终止格局中,每个物体放在哪个箱子中。

int NUMBER_OF_OCCUPIED_BINS_IN_CURRENT_SOLUTION_PA TTERN表示在当前解中使用的箱子数。

int ** ITEMS_NUMBER_IN_EACH_BIN_IN_CURRENT_SOLUTION_PA TTERN是二维整型数组,其中记录在当前解中每个箱子中放了哪些物体。

int * LOAD_OF_EACH_BIN_IN_CURRENT_SOLUTION_PA TTERN记录在当前解中每个箱子中物体的重量之和。

INCREASING_SEQUENCE_OF_BINS_BY_LOAD_IN_CURRENT_SOLUTION_PA T TERN是一个整型数组,其中记录在当前解中箱子按照重量从小到大的序列。

3.1.3 邻域搜索

邻域搜索函数命名为local_search()。此模块中所使用的主要数据结构如下。

有_IN_CURRENT_FINAL_PATTERN后缀的变量是属于当前终止格局的,很可能并不对应一个解。

int * BIN_NUMBER_OF_ITEMS_IN_CURRENT_FINAL_PATTERN表示在当前终止格局中使用的箱子数。

int NUMBER_OF_OCCUPIED_BINS_IN_CURRENT_FINAL_PATTERN是二维整型数组,其中记录在当前终止格局中每个箱子中放了哪些物体。

int ** ITEMS_NUMBER_IN_EACH_BIN_IN_CURRENT_FINAL_PATTERN表示在当前终止格局中,每个物体放在哪个箱子中。

int * LOAD_OF_EACH_BIN_IN_CURRENT_FINAL_PATTERN记录在当前终止格局中每个箱子中物体的重量之和。

INCREASING_SEQUENCE_OF_BINS_BY_LOAD_IN_CURRENT_FINAL_PATTER Nint 是一个整型数组,其中记录在当前终止格局中箱子按照重量从小到大的序列。

3.1.4 释放内存

释放函数命名为free_memory()。此函数调用库函数free()来释放用库函数malloc()分配的内存空间。

以ITEMS_NUMBER_IN_EACH_BIN为例,此二维数组所占用的内存是采用malloc()函数分配的。程序如下:

ITEMS_NUMBER_IN_EACH_BIN = (int **)malloc(sizeof(int *) * (NUMBER_OF_OCCUPIED_BINS+1));

for(j=1; j<=NUMBER_OF_OCCUPIED_BINS; j++)

ITEMS_NUMBER_IN_EACH_BIN[j] = (int *)malloc(sizeof(int) * (MAXIMAL_NUMBER_OF_ITEMS_IN_A_BIN+1));

在释放二维数组的内存时,程序应为:

for(j=1; j<=NUMBER_OF_OCCUPIED_BINS; j++)

free(ITEMS_NUMBER_IN_EACH_BIN[j]);

free(ITEMS_NUMBER_IN_EACH_BIN);

3.2 调试程序

在调试程序的过程中,作者遵循的四条原则如下。

第一,不熬夜,保证在脑筋清醒的状态下调试程序。

第二,用折半查找,找到第一个出错的地方。

第三,用放大镜仔细看第一个出错的地方,也就是显示各个变量的值,就能看出错在哪里。

第四,将调试过程中发现的错误以及改正的手段记录在纸上作为原始文档以备忘。

作者在调试本文的程序时所找出并纠正的错误按顺序列举如下。

①local_search()函数中一个for循环没有用花括号将循环体括起来。

②将箱子按照重量从小到大排序的算法有错,改为用冒泡排序的算法。

③generate_initial_solution()函数生成初始解后,要将其信息记录在各种数据结构中。最初版的程序没有记录这些信息,从而导致出错。

④swap_one_zero()函数中,从一个超重的箱子取一个物体放在一个不满的箱子中,需修改这两个箱子的重量值,然后更新箱子按照重量从小到大排序的序列。更新序列的程序有错,交换两个数组元素的值时写错了。

4 计算结果

我用C语言编程序实现了本文提出的算法。编译器是微软公司的Visual C++ 6.0。我采用最快速度选项来编译源程序。程序在CPU为AMD 3.0 GHz的个人电脑上运行。

本文的程序计算了一组共17个benchmark问题实例。这17个benchmark问题实例由W?scher和Gau于1996年提出。这组问题实例可通过网络下载,网址为http://paginas.fe.up.pt/~esicup/index.php。

这17个实例可分为两类。第一类有8个问题实例名为TEST0005、TEST0014、TEST0022、TEST0030、TEST0058、TEST0065、TEST0068、TEST0082,目前尚未确定其客观最优解。第二类有9个问题实例名为TEST0044、TEST0049、TEST0054、TEST0055_52、TEST0055_64、TEST0075、TEST0084、TEST0095、TEST0097,目前已经确定了其客观最优解。

第一类8个问题实例的计算结果见表5.1。本文的程序标记为拟人算法。在这一组共8个benchmark问题实例中,拟人算法对6个问题实例找出了与当前最好解质量相同的解。拟人算法还证明了TEST0068这个benchmark问题实例的目前已知最好解正是客观最优解。在表5.1中以粗体显示TEST0068的计算结果。

表5.1 拟人算法对W?scher和Gau提出的尚未确定客观最优解的8个实例的计算结果

问题实例已知最好解拟人算法

解时间(秒)

TEST0005 29 29 0.22

TEST0014 24 24 0.14

TEST0022 15 15 0.05

TEST0030 28 28 0.22

TEST0058 20 21 0.10

TEST0065 16 16 0.06

TEST0068 12 12 0.03

TEST0082 24 25 0.16

第二类9个问题实例的计算结果见表5.2。拟人算法找到了全部9个问题实例的客观最优解。

一种求解装箱问题的混合算法-最新文档

一种求解装箱问题的混合算法 : This paper presents a new hybrid algorithm based on genetic algorithm and tabu search for bin packing problem. It combines the advantage of global search ability of genetic algorithm with the adaptability of tabu search and has better convergence performance than simple genetic algorithm. At last, an practical example is applied to prove the efficiency of this algorithm. 0引言 装箱问题(Bin Packing Problem, BPP)是一类重要的组合优化问题,在现实生活中有着广泛的应用背景,特别在现代物流中,许多问题都抽象化为装箱问题或其变形,如货物如何装载,才能提高运载器具的利用率,从而降低运输成本;物流任务应如何调度,才能提高运行效率,等等。但在理论上,装箱问题是一个NP难题[1],很难精确求解。因此对其求解进行研究具有重要的理论价值和实际意义。 到目前为止,针对该问题人们提出了许多算法,但都有其局限性:枚举法和分支定界等精确算法在箱子数目稍大时,会出现“组合爆炸”;一些近似算法如下次适应NF、首次适应FF、降序首次适应FFD、最佳适应BF等,在解决复杂的装箱问题时结果与物品的体积数据有较大关系,在极端情况下很不理想;遗传

装箱问题C语言实现(算法分析)

算法分析 题目:装箱(Bin Packing)问题 院别:数学与计算科学学院 专业:信息与计算科学 姓名:蒋文明 学号:0800710313 指导老师:宁黎华 日期: 2011. 06. 9

目录 一、问题描述 (1) 二、问题分析 (1) 三、代码实现 (2) 四、测试结果 (3) 五、心得体会 (4) 六、源程序 (4)

一、问题描述 一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3, 4*4, 5*5,6*6.这些产品通常使用一个 6*6*h 的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。 二、问题分析 对于6*6的一个箱子来说,最多只能放一个6*6或一个5*5或4*4的盒子,所以我们初始化需要的箱子数时就是这这几种箱子的个数和,对于3*3的箱子来说,我们可以放一个或2个或3个或4个,这我们可以通过整除和取模来确定放了3*3盒子的箱子数,再把它加入到总箱子数中,接下来我们就是把1*1和 2*2的盒子塞进前面所需的箱子中,当塞不完时再来新增盒子,我们首先要将前面的箱子剩余的空间统计出来,并且要以2*2的优先考虑,因为我们可以把多余的2*2的位置变为填充4个1*1的,毕竟1*1的只要有空间随处都可以塞。所以当我们的箱子要是装了1个5*5的盒子的话,那么它就只能塞1*1的了,一个可以塞11个1*1的,对于装了4*4的盒子的话,那么还可以装5个2*2的盒子,暂且不要去转话成1*1的,除非没办法只能装1*1的,对于3*3 的话就可以根据取模之后一个箱子剩下的空间了,如果一个箱子中只放了一个3*3的,那么还剩下3个3*3的空间可以放,我们知道可以放5个2*2的和7个 1*1的,对于放了2个3*3的箱子,我们剩下的空间可以放3个2*2的以及6个1*1的,对于放了

斐波那契法 一维搜索方法

短后的区间不大于区间[0,10]的5% 。 解:由题意=δ5%,由斐波那契数列δ1 ≥n F ,则n=7, 00=a ,100=b 1t =0b )(0076a b F F --=2180 , 21 130)(00760'1=-+=a b F F a t , 将1t 和'1t 代入函数,比较大小有)()('11t f t f < 则有001==a a ,21801'2==t t ,21130'11==t b ,21 50)(116512=--=a b F F b t , 将2t 和'2t 代入函数,比较大小有)()('22t f t f < , 则有012==a a ,21502'3==t t ,2180'22==t b ,21 30)(225423=--=a b F F b t , 将3t 和'3t 代入函数,比较大小有)()('33t f t f >, 则有213033==t a ,2150'34==t t ,218023==b b ,21 60)(33433'4=-+=a b F F a t , 将4t 和'4t 代入函数,比较大小有)()('44t f t f >, 则有215044==t a ,2160'45==t t ,218034==b b ,21 70)(44324'5=-+=a b F F a t , 将5t 和'5t 代入函数,比较大小有)()('55t f t f >, 则有216055= =t a ,2170'56==t t ,218045==b b , 则令105 351)21602180()01.05.0(2160))((55215'6=-?++=-++=a b F F a t ε, 将6t 和'6t 代入函数,比较大小有)()('66t f t f <, 则216056==a a ,105351'66==t b ,区间为:?? ????105351,2160 所以选择6t 为极小点,=)(6t f 89.6)2170( -=f 。

机械优化设计一维搜索实验报告

《机械优化设计》 实验报告 班级: 机械设计(2)班 姓名:邓传淮 学号:0901102008

1 实验名称:一维搜索黄金分割法求最佳步长 2 实验目的:通过上机编程,理解一维搜索黄金分割法的原理,了解计算机在优化设计中的应用。 3 黄金分割法的基本原理 黄金分割法是用于一元函数f(x)在给定初始区间[a,b]内搜索极小点α*的一种方法。它是优化计算中的经典算法,以算法简单、收敛速度均匀、效果较好而著称,是许多优化算法的基础,但它只适用于一维区间上的凸函数[6],即只在单峰区间内才能进行一维寻优,其收敛效率较低。其基本原理是:依照“去劣存优”原则、对称原则、以及等比收缩原则来逐步缩小搜索区间[7]。具体步骤是:在区间[a,b]内取点:a1 ,a2 把[a,b]分为三段。如果f(a1)>f(a2),令a=a1,a1=a2,a2=a+r*(b-a);如果f(a1)

4实验所编程序框图(1)进退发确定单峰区间的计算框图

(2)黄金分割法计算框图

5 程序源代码 (1)进退发确定单峰区间的程序源代码 #include #include #define f(x) pow(x,4)-3*pow(x,3)-5*pow(x,2)-14*x+46 main() { int k; double x,h,x1,x2,x3; double f1,f2,f3,f; double a,b; x1=0; h=1; x2=x1+h; f1=f(x1); f2=f(x2); if (f1>f2) { h=2*h; x3=x2+h; f3=f(x3);

算法设计与分析复习题目及答案 (3)

分治法 1、二分搜索算法是利用(分治策略)实现的算法。 9. 实现循环赛日程表利用的算法是(分治策略) 27、Strassen矩阵乘法是利用(分治策略)实现的算法。 34.实现合并排序利用的算法是(分治策略)。 实现大整数的乘法是利用的算法(分治策略)。 17.实现棋盘覆盖算法利用的算法是(分治法)。 29、使用分治法求解不需要满足的条件是(子问题必须是一样的)。 不可以使用分治法求解的是(0/1背包问题)。 动态规划 下列不是动态规划算法基本步骤的是(构造最优解) 下列是动态规划算法基本要素的是(子问题重叠性质)。 下列算法中通常以自底向上的方式求解最优解的是(动态规划法) 备忘录方法是那种算法的变形。(动态规划法) 最长公共子序列算法利用的算法是(动态规划法)。 矩阵连乘问题的算法可由(动态规划算法B)设计实现。 实现最大子段和利用的算法是(动态规划法)。 贪心算法 能解决的问题:单源最短路径问题,最小花费生成树问题,背包问题,活动安排问题, 不能解决的问题:N皇后问题,0/1背包问题 是贪心算法的基本要素的是(贪心选择性质和最优子结构性质)。 回溯法 回溯法解旅行售货员问题时的解空间树是(排列树)。 剪枝函数是回溯法中为避免无效搜索采取的策略 回溯法的效率不依赖于下列哪些因素(确定解空间的时间)

分支限界法 最大效益优先是(分支界限法)的一搜索方式。 分支限界法解最大团问题时,活结点表的组织形式是(最大堆)。 分支限界法解旅行售货员问题时,活结点表的组织形式是(最小堆) 优先队列式分支限界法选取扩展结点的原则是(结点的优先级) 在对问题的解空间树进行搜索的方法中,一个活结点最多有一次机会成为活结点的是( 分支限界法). 从活结点表中选择下一个扩展结点的不同方式将导致不同的分支限界法,以下除( 栈式分支限界法)之外都是最常见的方式. (1)队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。 (2)优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。 (最优子结构性质)是贪心算法与动态规划算法的共同点。 贪心算法与动态规划算法的主要区别是(贪心选择性质)。 回溯算法和分支限界法的问题的解空间树不会是( 无序树). 14.哈弗曼编码的贪心算法所需的计算时间为( B )。 A、O(n2n) B、O(nlogn) C、O(2n) D、O(n) 21、下面关于NP问题说法正确的是(B ) A NP问题都是不可能解决的问题 B P类问题包含在NP类问题中 C NP完全问题是P类问题的子集 D NP类问题包含在P类问题中 40、背包问题的贪心算法所需的计算时间为( B )

【题10】装箱问题

【题10】装箱问题 有一个箱子容量为v (正整数,0≤v ≤20000),同时有n 个物品(0=best {若箱子即便装下全部物品,其剩余空间仍不小于best ,则回溯} then exit ; if k<=n {在未装入全部物品的前提下搜索两种可能情况} then begin if v>=a[k] {若剩余空间装得下物品k ,则物品k 装入箱子,递归计算子状态}

一种装箱问题的高效定位启发式算法

An ef?cient placement heuristic for three-dimensional rectangular packing Kun He,Wenqi Huang? School of Computer Science and Technology,Huazhong University of Science and Technology,Wuhan430074,China a r t i c l e i n f o Available online28April2010 Keywords: Cutting and packing Three-dimension Rectangular packing Container loading Heuristic a b s t r a c t By embodying the spirit of‘‘gold corner,silver side and strawy void’’directly on the candidate packing place such that the searching space is reduced considerably,and by utilizing the characteristic of weakly heterogeneous problems that many items are in the same size,a?t degree algorithm(FDA)is proposed for solving a classical3D rectangular packing problem,container loading problem. Experiments show that FDA works well on the complete set of1500instances proposed by Bischoff, Ratcliff and Davies.Especially for the800dif?cult strongly heterogeneous instances among them,FDA outperforms other algorithms with an average volume utilization of91.91%,which to our knowledge is 0.45%higher than current best result just reported in2010. &2010Elsevier Ltd.All rights reserved. 1.Introduction Cutting and packing problems are representative combinational optimization problems with many important applications in the industry.This paper addresses the problem of loading a subset of three-dimensional(3D)rectangular items into a3D rectangular container,such that the total volume of the packed items is maxi- mized,i.e.the container’s wasted volume is minimized.A layout is called feasible,if each packed item is located orthogonally and completely in the container and there is no overlapping between any two items.This problem is an NP-hard problem,whose1D degradation,the0–1knapsack problem,is still NP-hard. This3D rectangular packing problem is also called the container loading problem,because the most common and important application of this problem is to load rectangular cargoes into containers,vehicles or ships in the transportation industry.There are some additional considerations that would be taken into account in the real world[1,2],among which the orientation constraint and the stability constraint are the most important ones.In our opinion,if there is an ef?cient approach to solve the basic problem that has no additional constraints,then it is not dif?cult to make the approach adapted to problems considering some additional ones. Since the orientation constraint has been widely considered by the researchers,and it has been accepted by the famous BR benchmarks[1],we take the orientation constraint into account that one or two sides of the items may not be used as the height. This situation usually happens when cargoes are boxes full of oil or wine.We do not concern the stability constraint for the following reasons:(1)Stability constraint is not considered as widely as the orientation one and the stability criteria is inconsistent in the literature.In some cases it requires that each item is fully supported,or partially supported with at least a given percentage;in other cases it requires that the gravity center of each item falls over an underlying item or over the bottom of the container.(2)Stability could become a consequence of the high cargo compactness when the container’s volume utilization is high enough.(3)Foam rubber or other stuf?ng could be used to ?ll the small empty spaces left,as what has been done in some freight companies. Many ef?cient algorithms have been proposed for solving this classical3D packing problem.The most prevalent approach is wall building or layering[1,3–9],?rst proposed by George and Robinson in1980[3].In the past thousand years,people usually start packing goods from the bottom and build up the packing in layers,inserting each goods such that it is contiguous with what is already packed.Inspired by these human’s experience,the wall building or layering method usually opens a new layer or wall with a width equals to some item dimension,then each layer is?lled up by a number of horizontal strips,and each strip is packed in a greedy way.Another ef?cient approach widely adopted by the researchers is block arrangement[10–12],?rst proposed by Bortfeldt and Gehring in1998[10],which binds items of the same or similar size into a larger rectangular block to do the tentative packing.By utilizing the block arrangement method,Parren?o proposed an approach that always places a column or layer built by same size items into a maximal space,the largest empty parallelepiped spaces[13,14].Above approaches all utilized the characteristic of the weakly heterogeneous instances that many items are in the same size.Therefore,the solution qualities are in a downtrend when the problems become more Contents lists available at ScienceDirect journal homepage:https://www.360docs.net/doc/159200201.html,/locate/caor Computers&Operations Research 0305-0548/$-see front matter&2010Elsevier Ltd.All rights reserved. doi:10.1016/j.cor.2010.04.015 ?Corresponding author.Tel.:+862787543018;fax:+862787545004. E-mail addresses:brooklet60@https://www.360docs.net/doc/159200201.html,(K.He),wqhuangwh@https://www.360docs.net/doc/159200201.html, (W.Huang). Computers&Operations Research38(2011)227–233

装箱问题matlab

综合实验报告 一、实验名称 装箱问题 二、实验目的 掌握装箱问题的近似解法:NF算法、FF算法;FFD算法;熟悉这些算法的程序编写. 三、实验要求 (1)利用NF算法,FF算法,FFD算法,CF算法求解装箱问题,熟悉这些算法的程序编写; (2)选择一种计算机语言设计或利用Matlab软件作为辅助工具来实现该实验。 四、实验原理 NF算法: 按照物体给定的顺序装箱:把物品 放到它第一个能放进去的箱子 中。是具有最大下标的使用过的箱子,若 的长度不大于 的剩余长度,则把 放入 ,否则把

放入一个新的箱子 ,且 在以后的装箱中不再使用。最后循环 FF算法: 按照物体给定的顺序装箱:把物品 放到第一个箱子中。 是当前已经使用过的箱子,在这些箱子中找一个长度不小于 且下标最小的箱子,将放入 ,如果不存在这样的箱子,则另开一个新箱子 , 将 放入 中。 FFD算法: 先将物体按长度从大到小排序,然后按FF算法对物体装箱. 不失一般性,对n件物品的体积按从大到小排好序,即有v1≥v2≥…≥vn,然后按排序结果对物品重新编号即可。 CF算法: step1:把物件 按其大小进行非增序排列,不妨设

。 step2:首先把 放入箱子中 ,然后从最右端开始,依次把物件 放入 ,直到下一个物件不能再放入箱子为止,开启新的箱子 。 step3:设在第i 步循环时,打开第i 个箱子,此时把物件 放入 中. 假设第i-1 个箱子中最后一个放入的物件为 ,则在i 步循环时最右端的物件为 ,那么当 且 时,把 放入 中,开启新的箱子 。 step4:直到把所有物件都放入箱子中,循环终止,并输出箱子数目m.

一维数组的常用算法源代码

1.数组元素逆置 #include #include int main() { int a[10],t,i,j; //随机生成数组元素,并显示 printf("逆置前:"); for(i=0;i<10;i++) { a[i]= rand()%100; printf("%4d",a[i]); } printf("\n"); //数组元素逆置,即对称位置交换for(i=0,j=9;i

2.静态查找 #include #include int main() { int a[10],t,i,j; //随机生成数组元素,并显示 printf("数组元素:"); for(i=0;i<10;i++) { a[i]= rand()%100; printf("%4d",a[i]); } printf("\n"); //输入查找的数 printf("请输入要查找的数:"); scanf("%d", &t); //静态查找:从前往后依次遍历 for(i=0;i<10;i++) if(a[i]==t) break;//找到并退出//输出查找结果 if(i<10)

printf("%d在数组a[%d]中。\n",t,i); else printf("%d不在a数组中。\n",t); } 3.二分查找:前提数组有序 #include #include void sort(int a[], int n) { int i,j, t; for(i=0;ia[j+1]) {t=a[j]; a[j]=a[j+1]; a[j+1]=t;} } int main() { int a[10],t,i,left,right,mid; //随机生成数组元素 printf("数组元素:"); for(i=0;i<10;i++)

常用一维搜索算法

无约束优化:不对定义域或值域做任何限制的情况下,求解目标函数的最小值。 这是因为实际应用中,许多情形被抽象为函数形式后均为凸函数,对于凸函数来说局部最小值点即为全局最小值点,因此只要能求得这类函数的一个最小值点,该点一定为全局最小值。 (直接法:又称数值方法,它只需计算目标函数驻点的函数数值,而不是求其倒数,如坐标轮换法,单纯型法等。 间接法:又称解析法,是应用数学极值理论的解析方法。首先计算出目标函数的一阶或一阶、二阶导数,然后根据梯度及海赛矩阵提供的信息,构造何种算法,从而间接地求出目标函数的最优解,如牛顿法、最速下降法共轭梯度法及变尺度法。) 在优化算法中保证整体收敛的重要方法就是线搜索法与信赖域法,这两种算法既相似又有所不同。根据不同的线搜索准则就延伸出不同的线搜索算法,譬如比较常见和经典的最速下降法,牛顿法,拟牛顿法以及共辄梯度法等。 一维搜索又称线性搜索(Line Search),就是指单变量函数的最优化,它是多变量函数最优化的基础,是求解无约束非线性规划问题的基本方法之一。 一维搜索技术既可独立的用于求解单变量最优化问题,同时又是求解多变量最优化问题常用的手段,虽然求解单变量最优化问题相对比较简单,但其中也贯穿了求解最优化问题的基本思想。由于一维搜索的使用频率较高,因此努力提高求解单变量问题算法的计算效率具有重要的实际意义。 在多变量函数的最优化中,迭代格式X k+1=X k+a k d k其关键就是构造搜索方向d k和步长因子a k 设Φ(a)=f(x k+ad k) 这样从凡出发,沿搜索方向d k,确定步长因子a k,使Φ(a)<Φ(0)的问题就是关于步长因子a的一维搜索问题。其主要结构可作如下概括:首先确定包含问题最优解的搜索区间,然后采用某种分割技术或插值方法缩小这个区间,进行搜索求解。 一维搜索通常分为精确的和不精确的两类。如果求得a k使目标函数沿方向d k达到 极小,即使得f (x k+a k d k)=min f (x k+ ad k) ( a>0) 则称这样的一维搜索为最优一维搜索,或精确一维搜索,a k叫最优步长因子; 如果选取a k使目标函数f得到可接受的下降量,即使得下降量f (x k)一f (x k+a k d k)>0是用 户可接受的,则称这样的一维搜索为近似一维搜索,或不精确一维搜索,或可接受一维 搜索。 由于在实际计算中,一般做不到精确的一维搜索,实际上也没有必要做到这一点,因为精确的

本科毕业设计论文--经典一维装箱问题的适应近似算法的研究

经典一维装箱问题的适应近似算法的研究 摘要 本文研究经典一维装箱问题(Bin Packing Problem)及其适应近似算法,给出了一个新的适应近似算法:交叉装填算法(简称CF算法),而且证明了当这些物件大小按非增性预先排序后,CF算法时间复杂度是线性的;通过具体例子说明交叉装填算法优于其它适应 近似算法,并且推断CF算法达到装箱问题的最好近似值3 2 。 关键词:一维装箱问题,近似算法,适应算法,交叉装填算法

ABSTRACT In this paper the Bin-Packing problems and any-fit approximation algorithm are studied. We give a new any-fit approximation algorithm (Cross Fit Approximation Algorithm) in O(nlogn)steps. In addition, if the sizes of all objects decreasing according to their sizes, The any-fit approximation algorithm runs in O(n)steps. This paper proved the cross fit approximation algorithm’s capability excelled other any-fit approximation algorithm’s by some example,and extrapolate the new any-fit algorithm is a 3 2 -approximation algorithm. Key Words:Pin Packing Problem,Approximation Algorithm,Any-fit Algorithm,Cross Any-fit Algorithm.

基于matlab的一维搜索

最优化理论与算法 基于matlab 的一维搜索——0.618试探法 2 m in ()21def f x x x =-- , 初始区间11[,][1,1]a b =-,精度0.16L ≤ clc clear %设定初始值 L=0.16; k=1; b=1; a=-1; r=a+0.382*(b-a); u=a+0.618*(b-a); fr=fun(r); fu=fun(u); c=[]; while b-a>L if fr>fu a=r; b=b; r=u; u=a+0.618*(b-a); fr=fun(r); fu=fun(u); else a=a; b=u; u=r; r=a+0.382*(b-a); fr=fun(r); fu=fun(u); end k=k+1; c=[c,[a,b,r,u,fr,fu]]; end k jieguo=reshape(c,6,k)’ s=[a,b] l=b-a jieguo = -1.0000 1.0000 -0.2360 0.2360 -0.6526 -1.1246 -0.2360 1.0000 0.2360 0.5278 -1.1246 -0.9706 -0.2360 0.5278 0.0558 0.2360 -1.0496 -1.1246 0.0558 0.5278 0.2360 0.3475 -1.1246 -1.1060 0.0558 0.3475 0.1672 0.2360 -1.1113 -1.1246 0.1672 0.3475 0.2360 0.2787 -1.1246 -1.1234 0.1672 0.2787 0.2098 0.2360 -1.1218 -1.1246

第5章 一维搜索

第5章 一维搜索 §5.1 最优化算法的简单介绍 1.算法概念 在解非线性规划时,所用的计算方法,最常见的是迭代下降算法. 迭代:从一点) (k x 出发,按照某种规则A 求出后继点) 1(+k x .用1+k 代替k ,重复以上 过程,产生点列}{) (k x 。 规则A 是在某个空间X 中点到点的映射,即对每一个X x k ∈) (,有点 X x A x k k ∈=+)() () 1(. 更一般地,把A 定义为点到集的映射,即对每个点X x k ∈) (,经A 作用,产生一个点 集X x A k ?)() (.任意选取一个点)() () 1(k k x A x ∈+,作为) (k x 的后继点. 定义1: 算法A 是定义在空间X 上的点到集映射,即对每一个点X x ∈,给定-个子集 X x A ?)(. 例1 考虑线性规划: 1 s.t. min 2 ≥x x 最优解1=x .设计一个算法A 求出这个最优解. ???????

无约束最优化问题可以定义解集合为 }0)(|{=?=Ωx f x 约束最优化问题可以定义解集合为 }T -K 为|{点x x =Ω 2. 算法收敛问题 设Ω为解集合,X X A →:是一个算法,集合X Y ?.若以任一初点Y x ∈) 1(开始, 算法产生的序列其任一收敛子序列的极限属于Ω,则称算法映射A 在Y 上收敛. 收敛速率: 定义2: 设序列}{) (k γ 收敛于* γ,定义满足 ∞<=--≤+∞ →βγ γ γ γp k k k * ) (*) 1(lim 的非负数p 的上确界为序列}{) (k γ 的收敛级. 若序列的收敛级为p ,就称序列是p 级收敛的. 若1=p 且1<β,则称序列是以收敛比β 线性收敛的. 若1>p 或者1=p 且0=β,则称序列是超线性收敛的. 例2 序列{}10 ,<

matlab求贪婪算法装箱问题的练习

路漫漫其修远兮,吾将上下而求索- 百度文库 利用matlab编程FFD算法完成装箱问题: 设有6种物品,它们的体积分别为:60、45、35、20、20和20单位体积,箱子的容积为100个单位体积。 建立box_main.m function[box_count,b]=box_main(v) vmax=100; sort(v,'descend'); n=length(v); b=zeros(1,n); for i=1:n b(i)=vmax; end box_count=1; for i=1:n for j=1:box_count if v(i)<=b(j) %可以放入 b(j)=b(j)-v(i); break; else%不可放入时 continue; end end if j==box_count box_count=box_count+1; end end box_count=box_count-1; end 主程序为: v=[60 45 35 20 20 20]; [box_count,b]=box_main(v) 结果: box_count =3 b =5 15 80 100 100 100 所以,使用的箱子数为3, 使用的箱子的剩余空间为5,15 ,80。 “超市大赢家”提供了50种商品作为奖品供中奖顾客选择,车的容量为1000dm3 , 奖品i 占用的空间为wi dm3 ,价值为vi 元, 具体的数据如下: vi = { 220, 208, 198, 192, 180, 180, 165, 162, 160, 158,155, 130, 125, 122, 120, 118, 115, 110, 105, 101, 100, 100, 98,96, 95, 90, 88, 82, 80, 77, 75, 73, 72, 70, 69, 66, 65, 63, 60, 58,56, 50, 30, 20, 15, 10, 8, 5, 3, 1} wi = {80, 82, 85, 70, 72, 70, 66, 50, 55, 25, 50, 55, 40, 48,50, 32, 22, 60, 30, 32, 40, 38, 35, 32, 25, 28, 30, 22, 50, 30, 45,30, 60, 50, 20, 65, 20, 25, 30, 10, 20, 25, 15, 10, 10, 10, 4, 4, 2,1}。 解: 模型建立:用价值密度贪婪准则的方法设x=v/w,对x做正向排序,依次选取商品。 建立chaoshi.m function [item_count,y]=chaoshi(v,w,car) n=length(v); x=zeros(n,3); x(:,1)=v'; x(:,2)=w'; x(:,3)=v'./v'; x=sortrows(x,-3); item_count=0; for i=1:n if car>=x(i,2) car=car-x(i,2); item_count=item_count+1; else break; end end y=zeros(item_count,2); for i=1:item_count

三点一维搜索法报告

三点一维搜索法报告 姓名:张攀班级:2009211102 学号:09210048 算法的基本思想: 三点一维算法是从0.618法衍生而来的,0.618算法使用从两点a,b间选择两个点c,d将原来区域分为三个,抛弃不符合所求数值趋势的两个区域,不断逼近所求值,当|b-a|

实例分析: 选择函数:f[x] := Sin[x^4] + Cos[x] 该函数在[0,1]范围内有极小值,令a=0,b=1,p=0.1,e选取1*10^(-9),运算后结果在x=0.4904089750976563时有最小值0.939949。运算次数为22次, P值选取效率的影响: 在该函数中,[0,1]内函数波动较为平缓,从中间缓慢向两边扩展显然速度较快,因为所求点接近终点,当p增大的时能很快覆盖到所求点效率将变高,如果区域远超过所求点则效率将变低。 P取值以及逼近次数i的关系: P=0.1,i=22 P=0.2,i=26 P=0.25,i=19 P=0.3,i=19 P=0.35,i=21 P=0.4,i=23 P=0.5,i=26 P=0.6,i=30 P=0.7,i=36 P=0.8,i=57 可见最好的取值应为0.25到0.3之间。 总结: 三点一维算法实际通过多次比较,减少了0.618法对点的移动,和对区域的选择,比0.618法稳定。在比较区域大时三点一维算法比起0.618法更加优秀。

相关文档
最新文档