基于退火算法的启发式下料问题
2016-04-29 15:58
357 查看
刚刚做完最优控制的大作业,总结下所用的模拟退火算法,谈谈自己的理解。 问题就是典型的下料问题。把板材切割成要求数量和规格的产品。其中,输入为板材的大小、产品的数量和大小,输出为余料率、产品的坐标。 第一次接触模拟退火算法,表示这的确是一个不错的方法。对于就最优解的问题,的确能节约不少计算时间。模拟退火算法的精髓就在于其将**收缩**和**扩张**动态结合在一起,得到最优解是收缩的过程,而为了避免陷入局部最优解,又得有扩张的表现。再次印证了我一直以来坚信的一个想法,大自然演化的很巧妙,如果有什么无法解决的问题,或者想有什么创新,就到大自然中去找吧,哈哈,说多了。下面具体谈谈模拟退火。 具体算法概述参见百度百科吧[模拟退火](http://baike.baidu.com/link?url=gPZzOBtDyvJh3KpKlV-kF-YCgIbAxaYxjiIqc6DSyfOULq25aNHB3LeUUHYhDbwbPBkD5m9_yk7t1OKQwOUxrq),我就不写了,我主要说说我的理解。 退火过程中的每个金属分子有能量和状态两种属性,将能量最低时的状态记做r,能量和状态的概率有对应关系,能量越高,分子状态为r的概率越低,反之在最低温度时,r状态的概率趋近于1。将组合优化问题看做金属,解看做状态,那么最优解就是能量最低的状态,同时也定义一个费用函数来表示能量,通常都用T乘某个略小于1的系数。当T值比较高时,状态变化比较活跃,当T值达到最低时,达到最优解的概率趋近于1。 算法步骤: 1,任选一初始解X0。 给定初始温度Tmax; 2,若在该温度达到内循环停止条件,转第3步,否则,从解邻域N(Xi)中随机选取一Xj,计算目标函数的差值,如果小于0,则Xi=Xj,否则,计算exp[(-f(Xj)-f(xi))/T]>random(0,1),则Xi=Xj;重复2 3,更新温度T=d(T),若满足外循环停止条件,中止计算,否则,返回2。 更详细的介绍请看我上传的我们老师讲课的PPT,里面证明了此算法的适用条件,并证明了此算法能够达到全局最优解。 要想应用此算法,问题必须满足以下条件: 1.可达性,即无论起点如何,任何一个状态都可以到达。这样才使我们有得到最优解的可能 2,渐进不依赖起点。由于起点的选择有非常大的随机性,我们的目的是达到全局最优,因此,应渐进的不依赖起点。 3,分布稳定性。包含两个内容:其一是当温度不变时,其马尔科夫链的极限分布存在;其二是当温度渐进0时,其马尔科夫链也有极限分布。(马尔科夫链就是一种随机状态序列,可以直观的理解为一个解) 然后需要确定以下几个量: 1,解的形式 2,邻域的选取 3,初始温度的选取 4,温度下降的规则 5,每一温度下马氏链的迭代步长和停止规则 只要确定了这些,就可以根据上面提到的步骤进行计算了。 对于下料问题,1,将产品的下料顺序看成问题的一个解,启发式安排下料,得出余料率(余料率就是目标函数,其值越小越好,最优解即是余料率最小时的下料顺序)。余料率小于5%时,停止计算; 2,邻域的构造采用2-opt,即随机改变其中两个产品的生产顺序。因为是随机改变两个顺序,所以邻域中每个解的选取概率都是相同的 3,起始温度可以选择T=100,温度下降就用T=T*k,k可以去略小于1的数,比如0.96,终止温度可选10; 4,迭代步长就选用最简单的非时齐,每一温度下只迭代一步。 最后,对于每个解计算余料率时用的启发式方法(对于每个要生产的产品,优先占角)(此部分算法是参考别的论文写的)如下: 1,找到当前板材中的可用角,(只考虑左下角,即└形状的角),如果没有就取一张新的板材, 2,计算下一个要切割的产品占哪个角比较好,规则如下: 1,计算到产品到形成该角以外的其他矩形块(包括板材边)的最小距离Dmin,此值越小越好。 2,如果有n个角的Dmin值相同,则计算此角的贴边率(边重叠总长/产品周长) 3,如果还是有相同的角,就按序号优先级了 3,直到所有的产品都切割完,输出余料率。
//主程序部分 for (; T > 10; T*=0.96) { tuihuo(productbuf, material, alproduct, T, ExceStock);//迭代一步 cout << ExceStock << " " << endl; if (ExceStock <= 0.01)break; }
//退火算法部分 void tuihuo(deque<stock> &probuf, const stock &matrl, vector<stock> &alpro, double &T, double &excestock) { deque<stock> probuf1(probuf);//放置交换后的一个邻域 vector<stock> alpro1; //放置交换后的解启发式运算结果 twoOpt(probuf, probuf1); double exstock, exstock1;//余料率 alpro.clear(); exstock = ProductLayout(probuf, matrl, alpro); exstock1 = ProductLayout(probuf1, matrl, alpro1); if (exstock1 <= exstock)//如果邻域更好 { probuf.swap(probuf1); exstock = exstock1; alpro = alpro1; } else { double P = exp((exstock - exstock1)/T);//概率 static default_random_engine e1; static uniform_int_distribution<unsigned> u1(0, 1); if (P > u1(e1)) { probuf.swap(probuf1); exstock = exstock1; alpro = alpro1; } } excestock = exstock; }
相关文章推荐
- 对抗启发式代码仿真检测技术分析
- Large scale optimization
- 逻辑回归模型
- 转-局部搜索的形象描述
- 单纯形法
- [NOIP 2009]靶形数独
- 四.单纯形法(两阶段和大M法)
- 三.单纯形方法(原理)
- 二.线性规划的基本性质
- 一.最优化理论与算法学科介绍
- 模拟退火求解TSP问题<2变换法产生路径>
- “模拟退火算法的并行化”之“接手‘硬骨头’”
- 数值最优化
- 模拟退火算法的详细理解
- A*寻路算法入门(四)
- 基于模拟退火算法求解TSP问题(JAVA)
- 【HNOI2011】【BZOJ2336】任务调度
- 《最优化方法及其Matlab程序设计》马昌凤 部分习题答案
- 凸函数在凸集内部的多维凸组合仍然凸函数
- POJ 2420 A Star not a Tree? (爬山法||模拟退火)