Vous êtes sur la page 1sur 3

% [x,val,status]=MILP_bb(c,A,b,M,eps)

% this function solves a mixed-integer linear programming problem


% using the branch and bound algorithm
% The code uses Kartik's revised simplex and dual simplex codes
% to solve the LP relaxations at each node of the branch and bound tree.
% max c'*x
% subject to
% A*x = b
% x >= 0
% M is a vector of indices for the variables that are constrained to be
integers
% eps is the user tolerance
% the output variables are :
% x : the optimal solution
% val: value of the objective function at the optimal solution
% status =1 if successful
% =2 if the original problem is infeasible
% Kartik's MATLAB code
% Last updated: 19th April, 2006
% The B&B driver routine based on a MATLAB code by Sherif Tawfik, Cairo University
% downloaded from the MATLAB File Exchange.

function [x,val,status]=MILP_bb(c,A,b,M,eps)

[m,n] = size(A);
% Use the phase 1 procedure to find an initial basic feasible solution
% for the LP relaxation at the root node.
Aphase1 = A;
bphase1 = b;
index = find(b < 0);
bphase1(index) = -b(index);
Aphase1(index,:) = -A(index,:);
Aphase1 = [Aphase1 eye(m)];
cphase1 = [zeros(n,1); -ones(m,1)];
x0phase1 = [zeros(n,1); bphase1];
B0 = [n+1:n+m]';

[val,x0,B] = revised_simplex_bb(cphase1,Aphase1,bphase1,eps,x0phase1,B0);

clear Aphase1 cphase1 bphase1 x0phase1 B0 index;

% If the root LP relaxation is infeasible, then just quit!


if val < 0,
x = [];
status = 2;
val = [];
return;
end

bound = -inf; % the initial lower bound is set to -ve infinity

root = 1;

[x,B,status,b]=branch(c,A,b,x0,B,M,eps,bound,root); % a recursive function that


processes the BB tree

val = c'*x(1:n); % objective value of the optimal solution

function [xx,B,status,bb]=branch(c,A,b,x,B,M,eps,bound,root)
% x is an initial solution

% Solve the LP relaxation at the current node


% If it is the LP relaxation at the root node use the revised simplex method
% Else use the dual simplex method
if root == 1,
[val0,x0,B] = revised_simplex_bb(c,A,b,eps,x,B);
% The root LP relaxation is solved using Kartik's revised simplex code
% Initial bfs is the one found using the phase 1 procedure.
status0 = 1;
root = 0; % We are now dealing with descendents of the root node
else
[val0,x0,B,status0] = dual_simplex_bb(c,A,b,eps,x,B);
% All LP relaxations at descendent nodes are solved using Kartik's dual
% simplex code with warm-start information.
end

% If the LP relaxation is infeasible then PRUNE THE NODE BY INFEASIBILITY


% If the LP objective value is less than our current integer bound then PRUNE THE
NODE BY BOUNDS

if status0 == 2 | val0 < bound


xx=x;
status=status0; bb=bound;
% We are pruning this node, so there is no need to branch further on
% this node
return;
end

% If the solution to the LP relaxation is feasible in the MILP problem, then check
its objective value
% against that of the incumbent solution
% If the new feasible solution has a greater objective value then update the lower
bound
% In any case, PRUNE THE NODE BY OPTIMALITY

ind=find(abs(x0(M)-round(x0(M))) > eps );


if isempty(ind)
status=1;
if val0 > bound % replace the incumbent solution
x0(M)=round(x0(M));
xx=x0;
bb=val0;
else
xx=x; % we have pruned the node and there is no need to branch further on
this node
bb=bound;
end
return;
end

% The solution of the LP relaxation is not feasible in the MILP problem.


% However, the objective value of the LP relaxation is greater than the current
lower bound.
% So we branch on this node to create two subproblems.
% We will solve the two subproblems recursively by calling the same branching
function.

% The first LP problem with the added constraint that x_i <= floor(x_i) , i=ind(1)
br_var=M(ind(1));
br_value=x0(br_var);

[m,n] = size(A);
A1 = [A zeros(m,1); zeros(1,n+1)];
A1(m+1,br_var) = 1;
A1(m+1,n+1) = 1;
b1 = [b; floor(br_value)];
c1 = [c; 0];
x01 = [x0; b1(m+1)-x0(br_var)];
% The basis size grows by 1 with the new slack variable in the basis
B01 = [B; n+1];

% second LP problem with the added constraint that x_i >= ceil(x_i) , i=ind(1)
A2 = [A zeros(m,1); zeros(1,n+1)];
A2(m+1,br_var) = 1;
A2(m+1,n+1) = -1;
b2 = [b; ceil(br_value)];
c2 = [c; 0];
x02 = [x0; x0(br_var)-b2(m+1)];
% The basis size grows by 1 with the new slack variable in the basis
B02 = [B; n+1];

% solve the first child problem


[x1,B1,status1,bound1]=branch(c1,A1,b1,x01,B01,M,eps,bound,root);
status=status1;
if status1 == 1 & bound1 > bound % if the solution was successful and gives a
better bound
xx=x1;
B=B1;
bound=bound1;
bb=bound1;
else
xx=x0;
bb=bound;
end

% solve the second child problem


[x2,B2,status2,bound2]=branch(c2,A2,b2,x02,B02,M,eps,bound,root);

if status2 == 1 & bound2 > bound % if the solution was successful and gives a
better bound
status=status2;
xx=x2;
B=B2;
bb=bound2;
end

Vous aimerez peut-être aussi