📄 bnb.m
字号:
%DEBUG if p.options.bnb.verbose;fprintf(' %4.0f : %12.3E %7.2f %12.3E %2.0f %2.0f %2.0f %2.0f %2.0f\n',solved_nodes,upper,100*gap,lower,length(stack)+length(node),sedd);end
if p.options.bnb.verbose;fprintf(' %4.0f : %12.3E %7.2f %12.3E %2.0f \n',solved_nodes,upper,100*gap,lower,length(stack)+length(node));end
end
if p.options.bnb.verbose;showprogress([num2str2(solved_nodes,3) ' Finishing. Cost: ' num2str(upper) ],p.options.bnb.verbose);end
function stack = push(stackin,p)
if ~isempty(stackin)
stack = [p;stackin];
else
stack(1)=p;
end
%%
function [p,stack] = pull(stack,method,x_min,upper);
if ~isempty(stack)
switch method
case {'depth','depthfirst','depthbreadth','depthproject','depthbest'}
[i,j]=max([stack.depth]);
p=stack(j);
stack = stack([1:1:j-1 j+1:1:end]);
case 'breadth'
[i,j]=min([stack.depth]);
p=stack(j);
stack = stack([1:1:j-1 j+1:1:end]);
case 'best'
[i,j]=min([stack.lower]);
p=stack(j);
stack = stack([1:1:j-1 j+1:1:end]);
otherwise
end
else
p = [];
end
% **********************************
%% BRANCH VARIABLE
% **********************************
function [index,whatsplit] = branchvariable(x,integer_variables,binary_variables,options,x_min,Weight,p)
all_variables = [integer_variables(:);binary_variables(:)];
switch options.bnb.branchrule
case 'weight'
interror = abs(x(all_variables)-round(x(all_variables)));
[val,index] = max(abs(p.weight(all_variables)).*interror);
case 'first'
index = min(find(abs(x(all_variables)-round(x(all_variables)))>options.bnb.inttol));
case 'last'
index = max(find(abs(x(all_variables)-round(x(all_variables)))>options.bnb.inttol));
case 'min'
nint = find(abs(x(all_variables)-round(x(all_variables)))>options.bnb.inttol);
[val,index] = min(abs(x(nint)));
index = nint(index);
case 'max'
[val,index] = max(abs(x(all_variables)-round(x(all_variables))));
otherwise
error('Branch-rule not supported')
end
if index<=length(integer_variables)
whatsplit = 'integer';
else
index = index-length(integer_variables);
whatsplit = 'binary';
end
% **********************************
% SPLIT PROBLEM
% **********************************
function [p0,p1,variable] = binarysplit(p,x,index,lower,options,sosgroups,sosvariables)
p0 = p;
p1 = p;
variable = p.binary_variables(index);
tf = ~(ismembc(p0.binary_variables,variable));
new_binary = p0.binary_variables(tf);
% friends = [];
% if ~isempty(sosvariables)
% if ismember(variable,sosvariables)
% i = 1;
% while i<=length(sosgroups)
%
% if ismember(variable,sosgroups{i})
% friends = setdiff(sosgroups{i},variable);
% break
% else
% i = i + 1;
% end
% end
% end
% end
p0.ub(variable)=0;
p0.lb(variable)=0;
% if length(friends) == 1
% p0.ub(friends)=1;
% p0.lb(friends)=1;
% end
p0.lower = lower;
p0.depth = p.depth+1;
p0.binary_variables = new_binary;%setdiff1D(p0.binary_variables,variable);
%p0.binary_variables = setdiff(p0.binary_variables,friends);
p1.ub(variable)=1;
p1.lb(variable)=1;
%if length(friends) == 1
% p1.ub(friends)=0;
% p1.lb(friends)=0;
%end
p1.binary_variables = new_binary;%p0.binary_variables;%setdiff1D(p1.binary_variables,variable);
%p1.binary_variables = setdiff(p1.binary_variables,friends);
p1.lower = lower;
p1.depth = p.depth+1;
% % *****************************
% % PROCESS MOST PROMISING FIRST
% % (p0 in top of stack)
% % *****************************
if x(variable)>0.5
pt=p1;
p1=p0;
p0=pt;
end
function [p0,p1] = integersplit(p,x,index,lower,options,x_min)
variable = p.integer_variables(index);
current = x(p.integer_variables(index));
lb = floor(current)+1;
ub = floor(current);
% xi<ub
p0 = p;
p0.lower = lower;
p0.depth = p.depth+1;
p0.x0(variable) = ub;
p0.ub(variable)=min(p0.ub(variable),ub);
% xi>lb
p1 = p;
p1.lower = lower;
p1.depth = p.depth+1;
p1.x0(variable) = lb;
p1.lb(variable)=max(p1.lb(variable),lb);
% *****************************
% PROCESS MOST PROMISING FIRST
% *****************************
if lb-current<0.5
pt=p1;
p1=p0;
p0=pt;
end
function s = num2str2(x,d,c);
if nargin==3
s = num2str(x,c);
else
s = num2str(x);
end
s = [repmat(' ',1,d-length(s)) s];
function [stack,lower] = prune(stack,upper,options,solved_nodes,p)
% *********************************
% PRUNE STACK W.R.T NEW UPPER BOUND
% *********************************
if ~isempty(stack)
% toolarge = find([stack.lower]>upper*(1-1e-4));
toolarge = find([stack.lower]>upper*(1-options.bnb.prunetol));
if ~isempty(toolarge)
stack(toolarge)=[];
end
end
if ~isempty(stack)
lower = min([stack.lower]);
else
lower = upper;
end
function p = adaptivestrategy(p,upper,solved_nodes)
% **********************************'
% SWITCH NODE SELECTION STRATEGY?
% **********************************'
if strcmp(p.options.bnb.method,'depthproject') & (upper<inf)
p.options.bnb.method = 'project';
end
if strcmp(p.options.bnb.method,'depthbest') & (upper<inf)
p.options.bnb.method = 'best';
end
if strcmp(p.options.bnb.method,'depthbreadth') & (upper<inf)
p.options.bnb.method = 'breadth';
end
if strcmp(p.options.bnb.method,'depthest') & (upper<inf)
p.options.bnb.method = 'est';
end
function res = resids(p,x)
res= [];
if p.K.f>0
res = -abs(p.F_struc(1:p.K.f,:)*[1;x]);
end
if p.K.l>0
res = [res;p.F_struc(p.K.f+1:p.K.f+p.K.l,:)*[1;x]];
end
if (length(p.K.s)>1) | p.K.s>0
top = 1+p.K.f+p.K.l;
for i = 1:length(p.K.s)
n = p.K.s(i);
X = p.F_struc(top:top+n^2-1,:)*[1;x];top = top+n^2;
X = reshape(X,n,n);
res = [res;min(eig(X))];
end
end
res = [res;min([p.ub-x;x-p.lb])];
function p = Updatecostbound(p,upper,lower);
if p.simplecost
if ~isinf(upper)
ind = find(p.c);
if p.c(ind)>0
p.ub(ind) = min(p.ub(ind),(upper-p.f)/p.c(ind));
else
p.lb(ind) = max(p.lb(ind),(p.f-upper)/abs(p.c(ind)));
end
end
end
function [x_min,upper] = initializesolution(p);
x_min = zeros(length(p.c),1);
upper = inf;
if p.options.usex0
z = p.x0;
residual = resids(p,z);
relaxed_feasible = all(residual(1:p.K.f)>=-1e-12) & all(residual(1+p.K.f:end)>=-1e-6);
if relaxed_feasible
upper = computecost(p.f,p.corig,p.Q,z,p);%upper = p.f+p.c'*z+z'*p.Q*z;
x_min = z;
end
else
p.x0 = zeros(length(p.c),1);
x = p.x0;
z = evaluate_nonlinear(p,x);
residual = resids(p,z);
relaxed_feasible = all(residual(1:p.K.f)>=-p.options.bmibnb.eqtol) & all(residual(1+p.K.f:end)>=p.options.bmibnb.pdtol);
if relaxed_feasible
upper = computecost(p.f,p.corig,p.Q,z,p);%upper = p.f+p.c'*z+z'*p.Q*z;
x_min = x;
end
end
function [p,poriginal,stack] = pruneglobally(p,poriginal,upper,lower,stack,x);
if isempty(p.nonlinear) & (nnz(p.Q)==0) & p.options.bnb.nodetight
pp = poriginal;
if p.K.l > 0
A = -pp.F_struc(1+pp.K.f:pp.K.f+pp.K.l,2:end);
b = pp.F_struc(1+p.K.f:p.K.f+p.K.l,1);
else
A = [];
b = [];
end
if (nnz(p.Q)==0) & ~isinf(upper)
A = [pp.c';-pp.c';A];
b = [upper;-(lower-0.0001);b];
else
% c = p.c;
% Q = p.Q;
% A = [c'+2*x'*Q;A];
% b = [2*x'*Q*x+c'*x;b];
end
[lb,ub,redundant,pss] = milppresolve(A,b,pp.lb,pp.ub,pp.integer_variables,pp.binary_variables,ones(length(pp.lb),1));
if ~isempty(redundant)
if (nnz(p.Q)==0) & ~isinf(upper)
redundant = redundant(redundant>2)-2;
else
% redundant = redundant(redundant>1)-1;
end
if length(redundant)>0
poriginal.K.l=poriginal.K.l-length(redundant);
poriginal.F_struc(poriginal.K.f+redundant,:)=[];
p.K.l=p.K.l-length(redundant);
p.F_struc(p.K.f+redundant,:)=[];
end
end
if ~isempty(stack)
keep = ones(length(stack),1);
for i = 1:length(stack)
stack(i).lb = max([stack(i).lb lb]')';
stack(i).ub = min([stack(i).ub ub]')';
if any(stack(i).lb>stack(i).ub)
keep(i) = 0;
end
end
stack = stack(find(keep));
end
poriginal.lb = max([poriginal.lb lb]')';
poriginal.ub = min([poriginal.ub ub]')';
p.lb = max([p.lb lb]')';
p.ub = min([p.ub ub]')';
end
function [p,poriginal,stack] = fixvariables(p,poriginal,upper,lower,stack,x_min,monotinicity)
% Fix variables
if p.options.bnb.nodefix & (p.K.f == 0) & (nnz(p.Q)==0) & isempty(p.nonlinear)
A = -poriginal.F_struc(poriginal.K.f + (1:poriginal.K.l),2:end);
b = poriginal.F_struc(poriginal.K.f + (1:poriginal.K.l),1);
c = poriginal.c;
[fix_up,fix_down] = presolve_fixvariables(A,b,c,poriginal.lb,poriginal.ub,monotinicity);
%
poriginal.lb(fix_up) = 1;
p.lb(fix_up) = 1;
% not_in_obj = find(p.c==0);
% constrained_blow = all(poriginal.F_struc(1:poriginal.K.l,1+not_in_obj)>=0,1);
% sdp_positive = sdpmonotinicity(not_in_obj) == -1;
% can_fix = not_in_obj(find(constrained_blow & sdp_positive));
%
% still_on = find(p.lb==0 & p.ub==1);
% p.lb(intersect(can_fix,still_on)) = 1;
% still_on = find(poriginal.lb==0 & poriginal.ub==1);
% poriginal.lb(intersect(can_fix,still_on)) = 1;
if ~isempty(stack) & ~(isempty(fix_up) & isempty(fix_down))
keep = ones(length(stack),1);
for i = 1:length(stack)
stack(i).lb = max([stack(i).lb poriginal.lb]')';
stack(i).ub = min([stack(i).ub poriginal.ub]')';
if any(stack(i).lb>stack(i).ub)
keep(i) = 0;
end
end
stack = stack(find(keep));
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -