MindOpt V1.1 新增"MIP/SolutionNumber"参数
在本月达摩院新发布的MindOpt 优化求解器V1.1.0版本中,新增加了一个"MIP/SolutionNumber"参数,可以用于获取MILP多个解。
优化求解器产品是求解优化问题的专业计算软件,属于底层数学软件,可以用于各个行业。对优化求解器有更多好奇心的初学者,可查阅小编之前的文章《什么是优化技术?给算法小白同学的快速讲解和上手文》(或公众号精排版)。
在默认模式使用时,求解器最后只会给出一个解,对应求解到的最优目标值。有些业务里,会想要找到更多的可行解,目标值不一定最优,用于给业务指导。此次MindOpt更新的MILP参数会产生多个可行解。下载和安装MindOpt软件>>
使用方法
想要多个结果,设置的相关参数:
- MIP/SolutionPoolSize (int) 设置解缓存池的最大容量。求解前设置。
计算完成后,从属性(Attributes)中获取结果的属性:
- SolCount (int) 找到的较优解数量。
- Xn (double) 由参数 MIP/SolutionNumber 指定的较优解。
- 关联参数:MIP/SolutionPoolSize (int) 设置获取较优解的下标。设置后,通过获取属性Xn得到该较优解。求解完成后使用。
比如求解完成后,获取第k个solution的方式:用户设置<参数> SolutionNumber = k (0 <= k < SolCount),设置完成之后<属性>Xn即为对应的suboptimal solution的值。
示例代码
示例代码如下:
- line2是索引的MindOpt安装目录里面的示例MILP模型文件
- line6是设置候选解池数目
- line10是求解的最优目标值
- line14-20 是由差到优的结果的获取方式
frommindoptpyimport*file="~/mindopt/1.1.0/examples/data/pg.mps.gz"m=read(file) vars=m.getVars() expr=m.getObjective() m.setParam(MDO.Param.MIP_SolutionPoolSize, 10) m.optimize() print("Solution count =", m.SolCount) print("Problem status =", m.status) if (m.status==MDO.Status.OPTIMAL): print("Best Solution obj =", m.objval) print(str([var.Xforvarinvars[:20]]), "...") print("Suboptimal solutions from worst to best:") foriinrange(m.SolCount): m.setParam(MDO.Param.MIP_SolutionNumber, i) objval=m.objConstforiinrange(expr.size()): objval+=expr.getCoeff(i) *expr.getVar(i).Xnprint(" suboptimal obj = ", objval) print(" "+str([round(var.Xn,1) forvarinvars[:20]]), "...")
输出的结果日志摘取部分如下:
.................. Set parameter MIP/SolutionPoolSize to value 10Model summary. - Num. variables : 2700- Num. constraints : 125- Num. nonzeros : 5200- Num. integer vars. : 100- Bound range : [1.0e+00,2.5e+03] - Objective range : [1.0e+00,1.4e+02] .................. - Solution pool : 10Branch-and-cut method terminated. Time : 30.305s .................. Solution count =10Problem status =1Best Solution obj =-8674.342607117027 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0] ... Suboptimal solutions from worst to best: Set parameter MIP/SolutionNumber to value 0 suboptimal obj =7009.0 [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 1 suboptimal obj =6937.0 [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 2 suboptimal obj =-3661.011498595497 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 3 suboptimal obj =-3987.192860239571 [1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 4 suboptimal obj =-4162.448499031024 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 5 suboptimal obj =-8553.380870759038 [1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 6 suboptimal obj =-8637.723513904024 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0] ... Set parameter MIP/SolutionNumber to value 7 suboptimal obj =-8653.94037031042 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0] ... Set parameter MIP/SolutionNumber to value 8 suboptimal obj =-8665.322015044003 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, -0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0] ... Set parameter MIP/SolutionNumber to value 9 suboptimal obj =-8666.843995053305 [1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0] ...