Code covered by the BSD License  

Highlights from
TSP solver by CE & BK algorithms

image thumbnail
from TSP solver by CE & BK algorithms by Sebastien PARIS
Solve TSP problems with 2 stochastic solvers : CE & BK algorithms

cemcmc_tsp(L , option)
function out = cemcmc_tsp(L , option)

% Solve the classic Travel Sale Man problem with Botev-Kroeze (BK) optimization
% algorithm
%
% Usage 
% ------
%
% out = cemcmc_tsp(L , [option])
%
% Inputs
% -------
%
% L                      Distance/cost matrix (n x n)
% option                 Structure for the option of the BK algorithm (optional) 
%
%   option.N             Number of paths to generate for each iteration (default 10*round(log10(n))*n)
%   option.rho           Threshold for selectionning the best rho*N paths (default log10(n)*0.25)
%   option.b             Number of gibbsampler burnin (default = round(10*log10(n)) )
%   option.winjec        Number of consecutive step to wait where gamma(t) not improved before injecting  (default 5)
%   option.nbinjec       Number of injection (default 5*log10(n))
%   option.Kgamma        K Gain to add on gamma percentile (gamma(1+nb_inject*Kgamma) (default 1/100)
%   option.Kb            K Gain to add on b (b(1+nb_inject*Kb) (default 1/10)
%   option.Krho          K Gain to add on rho (rho(1+nb_inject*Krho) (default 1/50)
%   option.KN            K Gain to add on N (N(1+nb_inject*KN) (default 1/10)
%   option.rhomax        Maximum value of rho by injection (default 0.7)
%   option.T_max         Maximum number of iterations (default 10000)
%   option.X_ini         Initial vector (n + 1 x 1) (default = [])
%   option.gamma_ini     Initial percentile (default [])
%   option.verbose       1 for real time plot, 2 for text display (default 2)
%   option.V             Cities coordinates (n x 2). option.verbose = 1 is requiered;
%
%
% Outputs
% -------
%
% out
%    X_opt                Optimal solution. a (n + 1 x 1) index vector.
%    S_opt                Distance associated with the optimal path
%    St                   Optimal distance versus time iteration of the algorithm
%    gammat               rho-Percentile versus time
%
% Example
% ------
%
% n                        = 20;
% V                        = 10*rand(n , 2);
% L                        = distmat(V);
% out                      = cemcmc_tsp(L);
% plot(V(: , 1) , V(: , 2) , 'b+' , V(out.X_opt , 1) , V(out.X_opt , 2) , 'r' ,  'markersize' , 8 , 'linewidth' , 2)
% text(V(: , 1) , V(: , 2) , num2str((1 : n)' , '%0.0f') , 'fontname' , 'times' , 'fontsize' , 13);
%
%
% Author : Sbastien PARIS (sebastien.paris@lsis.org)
% --------
%
% Ref    : "An efficient Algorithm for Rare-Event Probability Estimation, Combinatorial, Optimization, and Counting", 
% ---      Z. I. Botev, D. P. Kroese, Methodology and Computing in Applied Probability, vol. 10
%
% see    http://iew3.technion.ac.il/CE/about.php


[n , d] = size(L);

if(n ~= d)

    error('L must be  a square(n x n)');

end



if ( (nargin < 2) || isempty(option))

    option.N                 = 10*round(log10(n))*n;   % number of tours to generate by MCWR

    option.b                 = round(10*log10(n))*n;

    option.rho               = log10(n)*0.25; %0.5;        % threshold for selectionning the best rho*N paths

    option.winjec            = 5;

    option.nbinjec           = round(5*log10(n));

    option.Kgamma            = 1/100;

    option.Kb                = 1/10;

    option.Krho              = 1/50;

    option.rhomax            = 0.7;

    option.KN                = 1/10;

    option.X_ini             = [];

    option.gamma_ini         = [];

    option.T_max             = 1000;          % Maximum number of iteration

    option.verbose           = 2;

end

if(~any(strcmp(fieldnames(option) , 'N')))

    option.N                     = 10*round(log10(n))*n;

end

if(~any(strcmp(fieldnames(option) , 'b')))

    option.b                     = round(10*log10(n))*n;

end

if(~any(strcmp(fieldnames(option) , 'rho')))

    option.rho                   = log10(n)*0.25; %0.5;

end

if(~any(strcmp(fieldnames(option) , 'winjec')))

    option.winjec                = 5;

end

if(~any(strcmp(fieldnames(option) , 'nbinjec')))

    option.nbinjec               = round(5*log10(n));

end

if(~any(strcmp(fieldnames(option) , 'Kgamma')))

    option.Kgamma                = 1/100;

end

if(~any(strcmp(fieldnames(option) , 'Kb')))

    option.Kb                    = 1/10;

end

if(~any(strcmp(fieldnames(option) , 'Kb')))

    option.Kb                    = 1/10;

end

if(~any(strcmp(fieldnames(option) , 'rhomax')))

    option.rhomax               = 0.7;

end

if(~any(strcmp(fieldnames(option) , 'KN')))

    option.KN                   = 1/10;

end

if(~any(strcmp(fieldnames(option) , 'X_ini')))

    option.X_ini                = [];

end

if(~any(strcmp(fieldnames(option) , 'gamma_ini')))

    option.gamma_ini            = [];

end

if(~any(strcmp(fieldnames(option) , 'T_max')))

    option.T_max                = 10000;

end

if(~any(strcmp(fieldnames(option) , 'verbose')))

    option.verbose               = 2;

end

if (option.verbose == 1)

    if (~any(strcmp(fieldnames(option) , 'V')))

        disp('option.V must be provided tp verbose, switching verbose = 0');

        option.verbose = 0;

    end

    fig1        = figure(1);

    set(fig1 , 'renderer' , 'zbuffer');

    set(fig1 , 'doublebuffer' , 'on');

    set(gca , 'nextplot' , 'replace');

    str_n   = num2str((1 : n)' , '%0.0f');


end

b                         = option.b;

rho                       = option.rho;

N                         = option.N;



Nrho                      = round(rho*N);

ind_Nrho                  = (1 : Nrho);

ON                        = ones(1 , option.N);

St                        = zeros(1 , option.T_max);

gammat                    = zeros(1 , option.T_max);

S_old                     = inf;

%%===== Initialization  ========%%

if(~isempty(option.X_ini))

    X                     = option.X_ini(: , ON);

else

    [ignore,p]            = sort(rand(n - 1 , N) , 1);

    X                     = [ON ; p + 1 ; ON];

end

[S , indice]              = sort(cost_TSP(L , X));

if(isempty(option.gamma_ini))

    gammat_old            = S(Nrho);

else

    gammat_old            = option.gamma_ini;

end

S_old                     = +inf;

I                         = indice(ind_Nrho);


X_opt                     = X(: , I(1));

S_opt                     = S(1);

t                         = 1;

cons                      = 0;

injec                     = 0;



if (option.verbose == 1)

    maxi             = max(option.V);

    mini             = min(option.V);

    fig1             = figure(1);

    p1               = plot(option.V(X_opt , 1) , option.V(X_opt , 2) , 'r' , option.V(: , 1) , option.V( : , 2) ,  '+' , 'markersize' , 8 , 'linewidth' , 2);

    text(option.V(: , 1) , option.V(: , 2) , str_n , 'fontname' , 'times' , 'fontsize' , 12)

    axis([mini(1) , maxi(1) , mini(2) , maxi(2)])

    %    title(sprintf('\\bf{n = %d, N = %d, \\rho=%3.2f, \\gamma_{%d}^{opt}=%6.2f , \\gamma_{%d}(%d) = %6.2f, d = %d}' , n , option.N , option.rho , t ,  S_opt , t , Nrho, gammat_old , cons) , 'fontsize' , 12 , 'fontname' , 'times');

    title(sprintf('\\bf{n=%d, N=%d, \\rho=%3.2f, \\gamma_{%d}^{opt}=%6.2f , \\gamma_{%d}(%d)=%6.2f, b=%d, d=%d, i=%d}' , n , N , rho , t ,  S_opt , t , Nrho, gammat(t) , b, cons, injec) , 'fontsize' , 12 , 'fontname' , 'times');


elseif (option.verbose == 2)

    disp(sprintf('n=%d, N=%d, \\rho=%3.2f, \\gamma_{%d}^{opt}=%6.2f , \\gamma_{%d}(%d)=%6.2f, b=%d, d=%d, i=%d' , n , N , rho , t ,  S_opt , t , Nrho, gammat(t) , b, cons, injec));

end

drawnow

%%========== Main Loop ==========%%


while( (t < option.T_max) && (injec <= option.nbinjec)) %(cons < option.d)

    %%%%%%%% Best Elite Samples Xtilde ~ g*(x|gamma_{t-1}) %%%%%%%%%%

    Xtilde          = X(: , I);

    Stilde          = S(ind_Nrho);

    %%%%%%%%%%%%%%%% Bootstrapping Xtilde => Y ~ g*(x|gamma_{t-1}) %%%%%%%%%%%%%%

    ind_bootstrap   = ceil(Nrho*rand(1 , N));

    %ind_bootstrap   = bootstrap(Stilde , option.N );

    Y               = Xtilde(: , ind_bootstrap);

    SY              = Stilde(ind_bootstrap);

    %%%%%%%%%%%%%%%% Gibbsampler Y = > X %%%%%%%%%%%%%%

    [X , SX]        = gibbsampler_tsp(Y , SY , L , gammat_old , b);

    %%% Index of Elite Samples %%

    [S , indice]    = sort(SX);

    I               = indice(ind_Nrho);
    
    if(S(Nrho) < gammat_old)

        gammat(t)   = S(Nrho);

    elseif(cons > option.winjec)

        injec       = injec + 1;

        gammat(t)   = round(gammat_old*(1 + injec*option.Kgamma));

        b           = round(option.b*(1 + injec*option.Kb));

        rho         = min(option.rhomax , option.rho*(1 + injec*option.Krho));

        Nold        = N;

        N           = round(option.N*(1 + injec*option.KN));

        ind         = ceil(Nold*rand(1 , (N - option.N)))  ;

        Nrho        = round(rho*N);

        ind_Nrho    = (1 : Nrho);

        indice      = [indice , indice(ind)];

        I           = indice(ind_Nrho);

    else

        gammat(t)   = gammat_old;

    end

    %%% Best current Score %%

    S_new           = S(1);

    if ((gammat(t) == gammat_old) && (S_new == S_old));

        cons         = cons + 1;

    else

        cons         = 0;

    end


    if(S_new < S_opt)

        X_opt      = X(: , I(1));

        S_opt      = S_new;

        cons       = 0;

    end

    St(t)      = S_opt;

    gammat_old = gammat(t);

    S_old      = S_new;


    %%===========  Display ===========%%

    if (option.verbose == 1)

        p1          = plot(option.V(X_opt , 1) , option.V(X_opt , 2) , 'r' , option.V(: , 1) , option.V( : , 2) ,  '+' , 'markersize' , 8 , 'linewidth' , 2);

        text(option.V(: , 1) , option.V(: , 2) , str_n , 'fontname' , 'times' , 'fontsize' , 13);

        axis([mini(1) , maxi(1) , mini(2) , maxi(2)])

        title(sprintf('\\bf{n=%d, N=%d, \\rho=%3.2f, \\gamma_{%d}^{opt}=%6.2f , \\gamma_{%d}(%d)=%6.2f, b=%d, d=%d, i=%d}' , n , N , rho , t ,  S_opt , t , Nrho, gammat(t) , b, cons, injec) , 'fontsize' , 12 , 'fontname' , 'times');

    elseif(option.verbose == 2)

        disp(sprintf('n=%d, N=%d, \\rho=%3.2f, \\gamma_{%d}^{opt}=%6.2f , \\gamma_{%d}(%d)=%6.2f, b=%d, d=%d, i=%d' , n , N , rho , t ,  S_opt , t , Nrho, gammat(t) , b, cons, injec));

    end

    drawnow

    t                   = t + 1;

end

St(t:option.T_max)      = [];
gammat(t:option.T_max)  = [];

out.S_opt               = S_opt;
out.X_opt               = X_opt;
out.St                  = St;
out.gammat              = gammat;

Contact us at files@mathworks.com