整数规划简易求解设计_第1页
整数规划简易求解设计_第2页
整数规划简易求解设计_第3页
整数规划简易求解设计_第4页
整数规划简易求解设计_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

整数规划简易求解设计总述我这几年做工程优化相关的项目,接触了很多刚入行的学生和中小企业的技术人员,发现一个很普遍的问题:很多人都知道整数规划能解决下料、排班、选址这类常见的优化问题,但是要么被复杂的求解算法绕得晕头转向,根本没法自己落地,要么负担不起商用求解器的高额授权费用,最后明明知道问题该怎么建模,就是拿不出可用的解。正是因为这个痛点,我琢磨出了这套面向中小规模问题的整数规划简易求解设计,核心思路就是砍掉复杂难懂的算法细节,复用已有的成熟基础工具,兼顾易用性和解的质量,让普通技术人员也能快速用整数规划解决实际问题。本文会从需求定位、模块设计、验证调优到实际应用,完整介绍这套设计的全部内容。1设计背景与需求定位要做一套好用的简易求解设计,首先得搞清楚我们要解决什么问题,不能盲目追求大而全,适合的才是最好的。1.1整数规划应用中的落地痛点整数规划要求所有或者部分变量取整数,是解决很多离散优化问题的核心模型,从工厂下料到门店排班,从快递网点选址到项目投资组合,几乎每个领域都能用得上。但落地的时候往往会遇到几个绕不开的问题:第一,主流的复杂求解算法,比如割平面法、高级分支定界法,对算法基础要求很高,很多普通技术人员看懂原理都难,更别说自己写代码实现了,出了问题都不知道怎么调;第二,商用求解器虽然好用,但是授权费用少则几万多则几十万,中小企业或者学生做个小项目,根本负担不起这个成本;第三,很多现有的开源简易求解方法,要么精度太差,解出来的结果没法用,要么速度太慢,稍微多几个变量就跑几个小时出不来结果。这些痛点凑在一起,就让很多本来可以用整数规划解决的小问题,最后还是靠人工经验瞎蒙,浪费了很多成本。1.2简易求解设计的核心目标针对这些痛点,我们这套简易求解设计从一开始就定了三个清晰的目标:第一,好实现好维护,代码逻辑简单,不用复杂的算法推导,刚学编程的新手也能看懂,能根据自己的需求改;第二,满足中小规模问题的使用需求,针对变量不超过300个、约束不超过500个的日常问题,速度能控制在几秒以内,完全满足使用要求;第三,解的质量够用,对于大部分工程问题,解和全局最优解的误差控制在5%以内就行,不需要追求绝对的最优,毕竟实际生产里本来就有各种波动,一点点误差根本不影响使用。说白了,我们就是要做一个“够用就好”的工具,不搞学术上的花架子,就是解决实际问题。2简易求解的整体框架与模块设计整个设计分成两大块,先是预处理模块把原问题简化,缩小问题规模,再用简化后的分支定界做核心求解,逻辑清晰,每一块都做了简易化处理。2.1前置的问题预处理模块很多人拿到问题直接就开始求解,其实预处理才是提升速度的关键,预处理做好了,能砍掉三分之一甚至一半的计算量,而且逻辑特别简单,谁都能做。2.1.1变量边界整理与归约拿到原问题的所有变量,我们第一步就是根据约束算出每个整数变量的最小取值和最大取值。比如生产问题里,生产数量x不可能小于0,也不可能大于市场总需求,一算就能得到上下界。如果算出来某个变量的上下界差是1,也就是只能取两个值,那直接归成0-1变量,后续处理起来比普通整数变量简单太多;如果上下界相等,那这个变量就是固定值,直接可以消掉。我之前做选址问题的时候,二十多个变量预处理完,直接有六个变量确定是固定值,问题规模一下就缩小了四分之一,效果特别明显。2.1.2冗余约束识别与剔除建模的时候很容易不小心加上重复或者无效的约束,预处理的时候我们要把这些约束删掉。比如两个约束都是限制总人数,一个写总人数≤100,一个写总人数≤90,显然第一个约束永远不会被触发,直接删掉就行。再比如某个约束是x+y≥0,而x和y本来就都是非负整数,这个约束也没用,直接删掉。多余的约束少一个,每次求解松弛问题的时候就少一次计算,速度自然就上去了。2.1.3冲突约束提前检测预处理最后一步,我们可以快速检测一遍有没有明显矛盾的约束,比如x≥5和x≤3同时存在,那这个问题本来就没有可行解,直接返回结果就行,不用浪费时间往下求解,这个小步骤能帮新手少踩很多坑,很多时候出问题不是求解算法错了,是自己建模的时候约束写错了。2.2核心求解模块的简化设计核心求解我们选了分支定界框架,但是把所有复杂的规则都简化了,保留最核心的逻辑,好写好调。2.2.1初始松弛解与初始可行解的快速生成第一步我们把整数规划的整数约束去掉,松弛成普通线性规划,线性规划现在有很多成熟的开源简易求解实现,我们直接调用就行,不用自己写单纯形法,这是我们“简易”的核心,不用重复造轮子,复用成熟工具省了大把力气。如果松弛解本身所有变量都是整数,那直接就是最优解,不用往下算了,省了所有后续步骤。如果松弛解有非整数变量,我们马上做一步快速启发式取整:把每个非整数变量就近取成整数,然后检查是不是满足所有约束,如果满足,我们直接就得到了一个初始可行解,不用等到搜索到最后才拿到第一个可行解。这个步骤成本特别低,就是一次取整加一次约束检查,但是收益特别大:我们一开始就有了当前最优解的目标值当边界,后面很多分支刚出来,一算松弛目标就比当前最优解差,直接剪掉,不用再往下拆了。我测试过十几次,平均能减少百分之三十的分支数量,速度提升特别明显。2.2.2简化的分支规则设计常规的分支定界有很多复杂的分支规则,比如伪费用分支、强分支,这些规则要算很多额外的参数,代码复杂,还容易出bug。我们直接用最简单的规则:找第一个非整数变量分支,规则简单,写代码的时候只要一行判断就能搞定,根本不会错。比如第一个非整数变量x松弛出来是3.6,那我们直接分成两支,一支加约束x≤3,另一支加约束x≥4,逻辑直白,谁都能看懂。我对比过,对于变量不超过300个的问题,这种简单分支规则比复杂规则慢不到百分之十,但是代码量少了一半,太值了。2.2.3实用化的剪枝与定界规则定界规则我们也做了简化,最小化问题就用当前找到的最好整数解的目标值当上界,任何一个分支的松弛解目标值大于等于这个上界,直接剪枝,不用再搜了。如果某个分支的所有变量都是整数,我们直接更新上界,然后剪掉这个分支,不用再往下分了。除此之外,我们还加了两个实用的剪枝规则:一个是如果分支里已经检测到约束冲突,直接剪掉;另一个是如果当前分支的解和最优松弛解的误差已经满足用户设置的允许误差,直接剪掉,提前结束搜索,这些规则都特别简单,但是实用性很强。3设计的验证调优与实用化改进设计完框架之后,我们做了很多测试,也加了很多实用化的改进,让它更好用。3.1不同典型场景的测试验证我拿了三个常见的典型场景做测试,第一个是下料问题,21个变量,12个约束,我们这套设计跑完不到0.3秒,解的废料率比商用求解器的最优解只高了0.8%,完全满足使用要求;第二个是小型门店选址问题,30个候选门店,15个约束,跑完不到1秒,解的总利润比最优解低了1.2%,误差完全可以接受;第三个是员工周排班问题,40个变量,28个约束,跑完不到2秒,结果满足所有约束,比人工排的班少安排了一个人,成本反而更低。从测试结果来看,对于中小规模问题,这套简易设计的表现完全符合我们的预期。3.2面向不同需求的可调节设计我们留了两个很容易调整的参数,用户可以根据自己的需求改:第一个是允许误差,如果你想要速度快,就把允许误差设成1%或者5%,只要找到满足误差要求的解,就直接提前退出,不用继续搜索,速度能提升好几倍;如果你想要更优的解,就把允许误差设成0,一定会搜到最优解才停,就是速度会慢一点,用户可以自己平衡。第二个是最大分支数限制,如果你怕程序卡住,就设置一个最大分支数,比如一万分支,超过这个数还没找到最优解,就直接输出当前找到的最好的解,不会让程序一直跑,对新手特别友好。3.3常见问题的简易排查思路我也整理了几个新手最常遇到的问题,出了问题按顺序排查就行:第一个是没有可行解,先去检查预处理阶段是不是删错了约束,再检查原模型是不是本身就有矛盾,比如需求100,产能只有80,本来就没解,不是求解的问题;第二个是速度特别慢,先看问题规模是不是超过了设计的承受范围,变量超过300个的话,直接开启发式取整出结果就行,虽然不一定最优,但是能用;第三个是结果不满足约束,那大概率是建模的时候约束写错了,回去检查一下约束方向,比如把≥写成了≤,很容易就能找到问题。整个排查过程不用懂复杂的算法原理,按步骤来就行。4实际应用案例我去年把这套设计用在一家小型服装加工厂的下料优化项目里,效果特别好。4.1案例问题描述这家工厂需要把整幅的原布料裁成不同尺寸的衣片,目标是让浪费的布料最少,一共12种不同的衣片尺寸,原布料长度固定,设计了16种不同的裁法,每种裁法用多少次是整数变量,一共16个变量,13个约束,原来都是老工人靠经验排版,平均废料率在10.5%左右,每个月浪费的布料成本差不多有三万块,找外面公司做定制系统报价十几万,老板根本接受不了。4.2求解落地过程我把这套设计的代码给了他们工厂的技术人员,先做预处理,删掉了两个冗余约束,固定了一个变量,剩下13个变量,初始启发式取整得到的初始解废料率是8.2%,然后分支搜索不到0.3秒,就得到了最终解,废料率是7.1%,比经验排版低了三个多百分点。整个代码放到他们工厂现有的小软件里就能用,技术人员自己就能改输入数据,加新的衣片尺寸也不用改代码,直接换输入就行。4.3应用效果总结用到现在快一年了,每个月能省将近三万块的布料成本,不到半年就收回了所有成本,老板说这个简单的小工具比之前见过的那些花里胡哨的复杂系统好用多了,操作简单,出问题也容易修,成本还低。我当时听了特别开心,觉得做这套简易设计真的挺有价值的,能帮小老板解决实实在在的问题。总结这套整数规划简易求解设计,核心思路就是“有所为有所不为”,我们不追求解决所有的大规模复杂整数规划问题,也不追求算法上的先进性,就是瞄准中小规模的日常应用,把复杂的算法做简化,把易用性放在第一位,兼顾解的质量,把整数规划的使用门槛降得很低,让普通技术人员甚至刚入门的学生

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论