新手发帖... ... :)
最近在准备数学建模,处理非线性的整数规划问题时,用到了bnb20()函数,最开始也遇到了很多问题,总是不好使,最后的解决方案如下:
Matlab环境:MATLAB R2008a
原始问题(来源于薛定宇等《高等应用数学问题的MATLAB求解》p188--例6-26):
>> A = [0 2 1 4 2; 3 4 5 -1 -1]; intlist = ones(5, 1); Aeq = []; Beq = [];
>> B = [54; 62]; xm = [0, 0, 3.32, 0.678, 2.57]‘; xM = 20000*ones(5, 1);
>> ix = (intlist == 1); xm(ix) = ceil(xm(ix)); x0 = xm;
>> [errmsg, f, x] = bnb20('test', x0, intlist, xm, xM, A, B, Aeq, Beq)
输出结果:
*** searched 0 % of three
*** Z : Inf
*** t : 0.0 secs
*** c : 0 cycles
*** fail : 0 cycles
Optimization terminated: first-order optimality measure less
than options.TolFun and maximum constraint violation is less
than options.TolCon.
Active inequalities (to within options.TolCon = 1e-006):
lower upper ineqlin ineqnonlin
2 1
3 2
5
??? Error using ==> lt
Matrix dimensions must agree.
Error in ==> bnb20 at 312
elseif all(abs(round(x(K))-x(K))0
查询bnb20原代码,关键注释代码如下:
>> edit bnb20
settings is a row vector with settings for BNB:
% settings(1) (standard 0) if 1: if the sub-problem does not converge do not branch it and
% raise fail by one. Normally BNB will always branch a nonconvergent sub-problem so it can
% try again to find a solution.
% A sub-problem that is a leaf of the branch-and-bound-tree cannot be branched. If such
% a problem does not converge it will be considered infeasible and fail will be raised by one.
% settings(2) is the handle of main BNB GUI. Leave empty.
% options is an options structure. For details type help optimset.
% options.maxSQPiter is a variable used by fmincon (if modified as described in bnb20.m).
% maxSQPiter cannot be set by optimset because it is not part of the
% standard options
% structure. maxSQPiter is 1000 by default.
这里面有个关键的地方,是option.maxSQPiter,"maxSQPiter cannot be set by optimset because it is not part of the standard options"按照中文解释是在Matlab中的options结构不含maxSQPiter一项(貌似和作者发布这个m文件的时间$Date: 1998/08/24 13:46:15 $)有关),但在命令窗口中输入:
>> ff = optimset; ff.MaxSQPIter
ans =
[]
可知新版的Matlab中的options结构中含有MaxSQLPIter一项,但为空,而在后面bnb20.m文件代码中,有如下if判断:
Line 111:
if nargin>3 && ~isempty(xl)
if isnumeric(xl) && isreal(xl) && all(size(xl)<=size(x0))
xlb(1:size(xl,1))=xl;
else
errmsg='xlb must be a real column vector the same size as x0.';
return;
end
end
可知MaxSQLPIter需要初始化一个正整数值,比如可以给默认值100。由于使用opt这一项参数,因此还需添加如下东西:
1.添加一个m文件,用于得到线性不等式约束(由于在本问题中无非线性约束,因此ceq,c全为空,注意只能以m文件的方式获得)
function [c, ceq] = nolinear(x)
%本文件实现了约束条件不等式的获取
ceq = []; c = [];
2.在命令窗口中添加参数设置
>> ff = optimset; ff.TolFun = 1e-6; ff.TolX = 1e-6; ff.TolCon = 1e-020;ff.MaxSQPIter = 1000;
%之前测试的时候,发现ff.TolFun和ff.Tolx貌似必须要进行设置 :)
>> settings = [0];
%settings的默认设置,具体见前面注释中对settings的解释 :)
>> [errmsg, f, x] = bnb20('test', x0, intlist, xm, xM, A, B, Aeq, Beq, nonlinear, settings, ff)
%'test‘是对目标函数的描述,intlist的设置为什么是[1 1 1 1 1]'在前面的注释中也提到 :)
输出结果:
errmsg =
''
f =
-89
x =
19.0000
0
4.0000
10.0000
5.0000
所输出的结果和书中给出的值一样,即正确。
PS:1.bnb20()函数和众多其它需要设置初始值的函数一样,其最终得出的结果有时候很依赖x0的选择,貌似和“全局最优”和“局部最优”有关,因此
得出结果后,还需尝试其它初始值,进行验证,有时候感觉就像碰运气 :)
2.上述的解决方案基本上可以解决使用bnb20()函数所遇到的所有问题,如果实在还不行,在参考bnb20.m文件的代码及注释吧... ... :)