00001MATLAB的yalmip的gurobi的infisable problem问题
0摘要:
在我将日前24时刻调度,转为日内96时刻调度的过程中遇到了infisable problem的报错,当目测找不出时,我通过查阅资料解决了此问题。具体步骤以及需要注意的点如下:
Model is infeasible or unbounded。
1 设置gurobi+:
设置以下参数:
ops = sdpsettings('solver', 'Gurobi+', 'verbose', 2, 'debug', 1, 'gurobi.NonConvex', 2);
result=optimize(C,OBJ,ops);
if result.problem==0
fprintf('求解成功 !!!\n');
else
error('求解出错!请查找错误来源');
end
%报错后再鼠标选中运行下一31的export函数
[model,recoverymodel] = export(C,OBJ,ops);
易错点1:用export函数无法导出model
看遍教程,发现别人用[model,recoverymodel] = export(C,OBJ,ops);就好使,我用就不行。一开始以为是以下三个原因之一:
①export是python环境中的gurobi导出模型的方法。
②debug=1未设置
③'gurobi.NonConvex', 2非半正定模型未设置(注释:ops.gurobi.NonConvex=2也行)
后来无意间发现,是gurobi需要写成gurobi+才行,gurobi+的意思是优先使用gurobi。不添加+号就会出现model等于空集,导致无法将后续的冲突约束导出。(这点,未见有博客明确指出,较为隐晦,我已经一一验证以上四点,发现就是gurobi+的原因,与其他三项无关,可能更底层的原因是需要求助yalmip中的部分库函数)
2 导出互相冲突的约束的序号
iis = gurobi_iis(model);
如果程序不报错,那么就别放这行代码进去;如果程序报错,那么这行代码通常需要单独选中后才会运行。
之后在工作区会出现iis结构体,其中的iis.Arows的1代表约束冲突,约束序号为该1所在行号。这里参见博客,最好将该列放在excel中行号与1进行对应。可以替换FALSE为空格(如下图)便于后面查找变量及约束序号。
3 导出原模型所有的约束条件
代码如下所示:
gurobi_write(model, 'TestModel.lp');注意是.lp而不是ilp
导出结果如下所示:
这里我提醒以下两点:
①其中的C123这些就是自变量,等效于Ebuy与H_CHP等。C的序号就是Ebuy等电力调度的设备变量的初始化顺序。
②约束R123与yalmip约束的先写后写无对应关系,很杂乱。
③testmodel.lp文件内,是所有变量和所有约束,其冲突约束需要自己挑选出来。
这里刚开始有如下几个美好的想法:
①只输出有冲突的约束
②输出约束时不用C123而是用Ebuy等变量名
结果发现,部分博客展示出美好想法①可以在python环境中用m.computeIIS实现,但在matlab的yalmip环境中,我验证了ops. computeIIS();以及model. computeIIS();都不好使。大概是因为cplex编写程序用的并不是结构体模型。我不学python就没去验证,感觉希望不大。
4 找出原模型相互冲突的约束条件,并进行注释,缩小程序报错的范围
找出原模型相互冲突的约束条件的方法是通过iis.Arows=1的行号123找出冲突约束R123,继而根据R123内的变量名C456去自己编写的m程序内去查找变量名Ebuy,根据变量名与系数值,确认冲突约束。这个过程较为复杂。以下介绍一种个人认为比较便捷的流程。
第一步:在yalmip编写的m程序函数中,根据自变量初始化顺序,注释各个变量Ebuy与H_CHP分别等价于C123和C456。注意从0开始,标注完所有变量,如下图所示:
若是在程序编写过程中直接用变量对变量赋值,即部分变量无初始化sdpvar的过程,例如下图,那么就更加复杂了,几乎不可能找出所有冲突约束,因此,我的程序编写的习惯需要进一步合规合理。
一一查找,注释的过程记得细心标注,按道理,将所有冲突约束全注释后就应该能运行,继而再逐次减少注释,即可进一步缩小报错的范围,自然也很可能走向牛角尖。
最常见以及最容易修改的报错原因有如下几个:
①电平衡与热平衡难以同时维持,只有chp没有gb,或者CHP与gb都是[100,1000]这种无[0,100]的范围的欠缺。这时,可以考虑将==换成<=或>=
②将电源变量约束10放宽成100,1000,尤其是外网交互功率,一定要设置的较大限值,这样系统才更容易实现源荷平衡
③将常值负荷变量通通缩小100倍,若能运行,则大概率是电热源出力上下限设置值过小的问题。若不能运行,那么很可能就是效率参数问题、或者单个变量的多个约束间发生冲突(虽然上文说了那么多,但我觉得这个最实用,哈哈)这个系数可以从小到大,统一去乘以所有常参数,看谁先越限就是谁,也是个比较省时间的方法,哈。
④求解器不适用于自己编写的非线性模型代码,也很有可能
⑤日前参数赋值给日内时,例如弹性系数矩阵24*24变成96*96后,那么日前的电价变化量和功率变化量,就只能赋值其中之一给日内96时刻的变量,否则就会冲突
⑥其他原因。
5 参考其他博主的链接
https://zhuanlan.zhihu.com/p/358596015
祝各位兄弟一次成功,哈哈!!!
值得注意的是,若是变量乘积引起的非凸,用gurobi依旧不好使,可以用大m法,涉及电价*功率的可以将电价sdpvar*sdpvar转化为A*binvar*sdpvar,再用大M法。涉及到2次项+1次项,或者ln等的,可以用分段函数线性化,具体的见往期视频。但我目前还没遇到过,非常感叹gurobi的强大,加油!!!
在日前24转化为日内96时,注意将所有的容量、成本等的全除以4才对。