Computer code

compute_exec_time.m
function compute_exec_time( total_alt, total_cri, total_try, output_file)
% compute executing time of class 'model'
% preprocess input parameters, and output file
if nargin < 1
total_alt = [ 3 4 5 6 7 8 9 10];
end
if nargin < 2
total_cri = [ 3 4 5 6 7 8 9 10];
end
if nargin < 3
total_try = [100 100 100 100 100 100 100 100];
end
if nargin < 4
output_file = 'compute_exec_time.xls';
end
% test output file
fprintf('test output file [%s], writing... ', output_file);
status = xlswrite( output_file, {'start at' , datestr( clock)}, 'time');
if status
fprintf('ok\n');
else
error( '\ncompute_exec_time() error: can not write to file [%s] !!!', output_file);
return;
end
% preallocate storage
ttl_row = size( total_alt(:), 1);
ttl_col = size( total_cri(:), 1);
avg_tm = zeros( ttl_row, ttl_col);
std_tm = zeros( ttl_row, ttl_col);
ttl_size = sum( total_try, 2) * ttl_col;
detail = zeros( ttl_size, 3);
% main loop
k = 0;
tm_msg = running_msg();
for mi = 1 : ttl_row
m = total_alt( mi);
t = total_try( mi);
for ni = 1 : ttl_col
n = total_cri( ni);
if t > 0
tm = zeros( 1, t);
else
tm = 0;
end
if mi == 1 & ni == 1 % warn-up, prepare memory for relative modules
md = model(m, n);
md.solve( tm_msg);
end
for ti = 1 : t
md = model(m, n);
best = md.solve( tm_msg, ti, t);
tm( ti) = best.tm;
k = k + 1;
detail( k, : ) = [ m n best.tm];
clear model;
end
avg_tm( mi, ni) = mean(tm);
std_tm( mi, ni) = std (tm);
clear tm;
end
end
tm_msg.stop();
% save results
fprintf('saving results to [%s]... ', output_file);
s1 = xlswrite( output_file, {'start at' , datestr( tm_msg.start_tm) ; ...
'stop at' , datestr( tm_msg.stop_tm)}, 'time');
s2 = xlswrite( output_file, avg_tm, 'avg');
s3 = xlswrite( output_file, std_tm, 'std');
s4 = xlswrite( output_file, detail, 'detail');
if s1 & s2 & s3 & s4
fprintf('done!\n');
else
fprintf('error! results do NOT saved!!!\n');
end
end %%%% function %%%%
IT2TrFN.m
classdef IT2TrFN < handle
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
properties
L = [0 0 0 0];
U = [0 0 0 0];
hL = 0;
hU = 0;
d = 0;
end
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
methods
function obj = IT2TrFN(a1L, a2L, a3L, a4L, hL, a1U, a2U, a3U, a4U, hU)
if nargin == 1 & size(a1L(:), 1) == 10
obj.L = a1L(1:4);
obj.U = a1L(6:9);
obj.hL = a1L( 5);
obj.hU = a1L(10);
% obj.validate();
elseif nargin == 1 & size(a1L(:), 1) == 1 & a1L == 0
% keep all zeros
elseif nargin == 10
obj.L = [a1L, a2L, a3L, a4L];
obj.U = [a1U, a2U, a3U, a4U];
obj.hL = hL;
obj.hU = hU;
% obj.validate();
else
obj.rand_gen();
end
% obj.d = obj.calc_d();
end %%%% function %%%%
function obj = rand_gen(obj)
% step 1: random 5 segments, and normalize by cumulative sum
Usum=cumsum(rand(1,5)); obj.U=Usum(1:4)/Usum(5) * ( 1 - 0 ) + 0 ;
Lsum=cumsum(rand(1,5)); obj.L=Lsum(1:4)/Lsum(5) * (obj.U(4) - obj.U(1)) + obj.U(1);
% step 2: compute max height of inside trapezoid
ratio2 = min((obj.L(2) - obj.U(1)) / (obj.U(2) - obj.U(1)), 1);
ratio3 = min((obj.L(3) - obj.U(4)) / (obj.U(3) - obj.U(4)), 1);
% step 3: max height of inside trapezoid, min height of outside trapezoid
hLmin = 0;
hUmax = 1;
hLmax = min(hUmax *ratio2, hUmax *ratio3); obj.hL = obj.random_range(hLmin, hLmax);
hUmin = max(obj.hL/ratio2, obj.hL/ratio3); obj.hU = obj.random_range(hUmin, hUmax);
% step 4: validate & compute d(A,0)
obj.validate();
obj.d = obj.calc_d();
end %%%% function %%%%
function [v] = random_range(obj, from, to)
v = from + (to - from) * rand(1,1);
end
function validate(obj)
if any(obj.L ~= sort(obj.L)) || any(obj.L < 0) || any(obj.L > 1)
fprintf('%.4f ', obj.L);
error('bad position: L');
end
if any(obj.U ~= sort(obj.U)) || any(obj.U < 0) || any(obj.U > 1)
fprintf('%.4f ', obj.U);
error('bad position: U');
end
if obj.hL > obj.hU || any([obj.hL obj.hU] < 0) || any([obj.hL obj.hU] > 1)
fprintf('hL=%.4f > hU=%.4f', obj.hL, obj.hU);
error('bad height: hL, hU');
end
if obj.hU * (obj.L(2)-obj.U(1)) / (obj.U(2)-obj.U(1)) < obj.hL
fprintf('hL=%.4f > hU=%.4f', obj.hL, obj.hU);
error('bad height: hL, hU');
end
if obj.hU * (obj.L(3)-obj.U(4)) / (obj.U(3)-obj.U(4)) < obj.hL
fprintf('hL=%.4f > hU=%.4f', obj.hL, obj.hU);
error('bad height: hL, hU');
end
end %%%% function %%%%
function plot(obj)
yU=[0 obj.hU obj.hU 0];
yL=[0 obj.hL obj.hL 0];
axis([0, 1, 0, 1]);
% axis([0 1 0 1]);
plot(obj.U, yU, 'r-', [0 obj.U(2)], [obj.hU obj.hU], 'r--'); hold on;
plot(obj.L, yL, 'b-', [0 obj.L(2)], [obj.hL obj.hL], 'b:.');
plot([obj.U(2) obj.U(2)], [obj.hU 0], 'k--.'); plot([obj.U(3) obj.U(3)], [obj.hU 0], 'k--.');
plot([obj.L(2) obj.L(2)], [obj.hL 0], 'k:.' ); plot([obj.L(3) obj.L(3)], [obj.hL 0], 'k:.' );
hold off;
end %%%% function %%%%
function test(obj, ttlRow, ttlCol)
if nargin < 2
ttlRow = 4;
end
if nargin < 3
ttlCol = 3;
end
k = 1;
for m = 1 : ttlRow
for n = 1 : ttlCol
subplot(ttlRow, ttlCol, k);
obj.rand_gen();
obj.plot();
k = k + 1;
end
end
end %%%% function %%%%
function [v] = calc_d(obj)
% compute d(A,0): distance function of a IT2TrFN
%
% @formula 1/8*(a1L+a2L+a3L+a4L + 4*alU+ 2*a2U+ 2*a3U+ 4*a4U + 3*(a2U+a3U-a1U-a4U)*hL/hU)
a1L=obj.L(1); a2L=obj.L(2); a3L=obj.L(3); a4L=obj.L(4); hL=obj.hL;
a1U=obj.U(1); a2U=obj.U(2); a3U=obj.U(3); a4U=obj.U(4); hU=obj.hU;
v = 1/8*(a1L+a2L+a3L+a4L + 4*a1U+ 2*a2U+ 2*a3U+ 4*a4U + 3*(a2U+a3U-a1U-a4U)*hL/hU);
end %%%% function %%%%
end % methods
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
methods(Static)
function [res] = add(obj2, mul)
% calc: res = sum( mul[] * obj2{}), mul is a multiplier vector
ttl = size(obj2(:), 1);
if nargin == 1
mul = ones(ttl, 1);
end
res = IT2TrFN(0);
res.hL = 1;
res.hU = 1;
for i = 1 : ttl
res.L = res.L + mul(i) * obj2{i}.L;
res.U = res.U + mul(i) * obj2{i}.U;
res.hL = min(res.hL, obj2{i}.hL);
res.hU = min(res.hU, obj2{i}.hU);
end
end %%%% function %%%%
end
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
end % classdef
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
model.m
classdef model < handle
% a dataSet class of this model
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
properties
m = 0; % total alternatives
n = 0; % total criteria
data = {}; % decision matrix, type 2 FS, {m, n}
W = {}; % weight, type 2 FS, {n}
L = {}; % likelihood, {n}[m, m]
LL = {}; % lower bound of L, {n}[m, m]
LU = {}; % upper bound of L, {n}[m, m]
total_tm = 0; % total elapsed solving time (in seconds)
end %%%% properties %%%%
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
methods
function obj = model(arg1, arg2)
if nargin == 0
[obj.m, obj.n, obj.data, obj.W] = data_paper();
elseif nargin == 1
[obj.m, obj.n, obj.data, obj.W] = data_paper(arg1);
else
obj.data_rand_gen(arg1, arg2);
end
obj.calc_L_matrix();
end %%%% function %%%%
function obj = data_rand_gen(obj, m, n)
obj.m = m;
obj.n = n;
obj.data = cell(m, n);
for i = 1 : m
for j = 1 : n
obj.data{i, j} = IT2TrFN();
end
end
for j = 1 : n
obj.W{j} = IT2TrFN();
end
end %%%% function %%%%
function [best, detail] = solve(obj, tm_msg, t, ttl_t)
if nargin < 2
tm_msg = running_msg();
end
if nargin < 4
t = [];
ttl_t = [];
end
if nargout == 2
ttl_seq = prod( obj.m);
detail = cell(ttl_seq, 1);
k = 1;
else
detail = {};
end
obj.total_tm = 0;
best = {};
perm = permutation( obj.m);
while perm.get_next();
res.seq = perm.seq;
tic;
res.Zval = obj.calc_CI_concordance(perm.seq);
res.tm = toc;
obj.total_tm = obj.total_tm + res.tm;
tm_msg.add_time( res.tm, 'm,n,trial: %d,%d,%d/%d, seq:%s', ...
obj.m, obj.n, t, ttl_t, sprintf(' %d', perm.seq));
if isempty( best) || best.Zval < res.Zval
best = res;
end
if ~ isempty( detail)
detail{ k} = res;
k = k + 1;
end
end
best.tm = obj.total_tm;
end %%%% function %%%%
function [best_CI, best_seq] = solve_v0(obj)
% obj.calc_L_matrix();
best_CI = 0;
best_seq = 1 : obj.m;
perm = permutation(obj.m);
while perm.get_next()
this_seq = perm.seq;
this_CI = obj.calc_CI_concordance(this_seq);
if best_CI < this_CI
best_CI = this_CI;
best_seq = this_seq;
end
end
end %%%% function %%%%
function CI = calc_CI_concordance(obj, seq)
m = obj.m;
n = obj.n;
pair_mtx = zeros(m, m);
for i = 1 : m-1
for j = i+1 : m
pair_mtx(seq(i), seq(j)) = 1;
end
end
sumL = zeros(1, n);
for i = 1 : n
% fprintf('i(%d)=1:n(%d)\n', i, n); disp(pair_mtx); disp(obj.L{i});
tmp = pair_mtx .* obj.L{i};
sumL(i) = sum(tmp(:));
end
res = IT2TrFN.add( obj.W, sumL);
CI = res.calc_d();
end %%%% function %%%%
function obj = calc_L_matrix(obj)
n = obj.n;
m = obj.m;
obj.L = cell(n, 1);
obj.LL = cell(n, 1);
obj.LU = cell(n, 1);
for j = 1 : n
obj.L{j} = zeros(m, m);
obj.LL{j} = zeros(m, m);
obj.LU{j} = zeros(m, m);
for p = 1 : m
for b = 1 : m
if p == b
obj.L {j}(p, b) = 0.5;
obj.LL{j}(p, b) = 0.5;
obj.LU{j}(p, b) = 0.5;
elseif p < b
[obj.L{j}(p, b), obj.LL{j}(p, b), obj.LU{j}(p, b)]= obj.calc_likelihood(obj.data{p, j}, obj.data{b, j});
else
obj.L {j}(p, b) = 1 - obj.L {j}(b, p);
obj.LL{j}(p, b) = 1 - obj.LL{j}(b, p);
obj.LU{j}(p, b) = 1 - obj.LU{j}(b, p);
end
end
end
end
end %%%% function %%%%
function [L, LL, LU] = calc_likelihood(obj, Apj, Abj)
% calculate L-(Apj>=Abj), L+(), L() by formula (10), (11), (12)
it1 = Abj.U - Apj.L ; % vector 1...4
it2a = Abj.U(4) - Apj.L(1);
it2b = Apj.L(4) - Apj.L(1) + Abj.U(4) - Abj.U(1);
it3 = Abj.hU - Apj.hL ;
divident = sum( max( it1, 0) ) + it2a + 2 * max( it3, 0);
divisor = sum( abs( it1 ) ) + it2b + 2 * abs( it3 );
if divisor == 0
L = 0;
LL = 0;
LU = 0;
return;
end
LL = max( 1 - max( divident / divisor, 0), 0);
it1 = Abj.L - Apj.U ; % vector 1...4
it2a = Abj.L(4) - Apj.U(1);
it2b = Apj.U(4) - Apj.U(1) + Abj.L(4) - Abj.L(1);
it3 = Abj.hL - Apj.hU ;
divident = sum( max( it1, 0) ) + it2a + 2 * max( it3, 0);
divisor = sum( abs( it1 ) ) + it2b + 2 * abs( it3 );
LU = max( 1 - max( divident / divisor, 0), 0);
L = (LL + LU) / 2;
end %%%% function %%%%
function obj = calc_d(obj)
% obj.d: the normalized collective decision matrix
obj.d = zeros( size( obj.data));
for i = 1 : obj.m
for j = 1 : obj.n
obj.d( i, j) = obj.data{ i, j}.d;
end
end
end %%%% function %%%%
function plot( obj)
k = 1;
for i = 1 : obj.m
for j = 1 : obj.n
subplot(obj.m, obj.n, k);
obj.data{i,j}.plot();
k = k + 1;
end
end
end %%%% function %%%%
end % methods
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
end % classdef
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
permutation.m
classdef permutation < handle
% get all permutations of a given integer, m
% This class handle all permutations as a tree,
% and store the fixed informations of stack (path) only.
%
% usage:
% clear;
% m = 4;
% perm = permutation(m);
% while perm.get_next()
% seq = perm.seq;
% fprintf('%d ', seq); fprintf('\n');
% end
%
% Data structure of example, m=4
% INIT & first leaf:
% m = 4
% fin = FALSE
% ttl{1:4}[] =
% { 4 ; 3 ; 2 ; 1 }
%
% parents{1:4}[] =
% { [] ; [1] ; [1 2] ; [1 2 3] }
% children{1:4}[] =
% { [1 2 3 4] ; [2 3 4] ; [3 4] ; [4] }
% pos{1:4}[] =
% { 1 ; 1 ; 1 ; 1 }
%
% GET: return the leaf: [2 1 4 3], and do next_leaf()
% parents{1:4}[] =
% { [] ; [2] ; [2 1] ; [2 1 4] }
% children{1:4}[] =
% { [1 2 3 4] ; [1 3 4] ; [3 4] ; [3] }
% pos{1:4}[] =
% { 2 ; 1 ; 2 ; 1 }
% fin = FALSE
%
% NEXT: method next_leaf():
% 1, POP: find the lowest, unfinished branch, the layer 'lyr'
% lyr=2, pos{2}=1 < ttl{2}=3
% 2, NextChild: pos{2}=1+1
% 3, PUSH:
% parents{1:4}[] =
% { [] ; [2] ; [2 3] ; [2 3 1] }
% children{1:4}[] =
% { [1 2 3 4] ; [1 3 4] ; [1 4] ; [4] }
% pos{1:4}[] =
% { 2 ; 2 ; 1 ; 1 }
% fin = FALSE
%
% FINISH:
% 1, in step 1, POP, of NEXT,
% if lyr is highest (lyr==1) and pos{1}=5 > m, then set flag, fin, ON
% fin = (lyr==1) & (pos{1}>m)
properties
fin = 0;
seq = [];
end
properties (SetAccess = private)
m = 0;
ttl = {};
pos = {};
parents = {};
children = {};
end
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
methods
function obj = permutation(m)
obj.m = m;
obj.fin = 0;
obj.ttl = num2cell(m : -1 : 1)';
obj.pos = num2cell(zeros(m,1)) ;
obj.parents = cell(m, 1);
obj.children = cell(m, 1);
end %%%% function %%%%
function obj = down_to_first_leaf(obj, lyr)
for i = lyr+1 : obj.m
grandPa = obj.parents {i-1};
brother = obj.children{i-1};
meNum = obj.pos {i-1};
brotherNum = 1 : size(brother(:),1);
obj.parents {i} = [grandPa , brother(meNum)];
obj.children{i} = brother(brotherNum ~= meNum);
obj.pos {i} = 1;
end
obj.seq = [ obj.parents{obj.m} , obj.children{obj.m}];
end %%%% function %%%%
function lyr = up_to_first_unfinish_branch(obj)
for lyr = obj.m : -1 : 1
if obj.pos{lyr} < obj.ttl{lyr}
return;
end
end
obj.fin = 1;
lyr = 0;
end %%%% function %%%%
function next_exist = get_next(obj)
if obj.pos{1} == 0
lyr = 1;
obj.children{lyr} = 1 : obj.m;
obj.pos {lyr} = 1;
else
lyr = obj.up_to_first_unfinish_branch();
if lyr <= 0
next_exist = 0;
obj.seq = [];
return;
end
obj.pos{lyr} = obj.pos{lyr} + 1;
end
obj.down_to_first_leaf(lyr);
next_exist = 1;
end %%%% function %%%%
function res = compute_exec_time(obj, all_m)
ttl_try_array = [0 0 3000 1000 30 20 10 5 3 2];
ttl_m = size (all_m(:), 1);
res = zeros(1, ttl_m);
for i = 1 : ttl_m
m = all_m(i);
ttl_try = ttl_try_array(m);
disp_tm = 0;
for j = 1 : ttl_try
clear perm;
perm = permutation(m);
start_tm = cputime;
while perm.get_next()
% do nothing
end
elapsed_tm = cputime - start_tm;
res(i) = res(i) + elapsed_tm;
disp_tm = disp_tm + elapsed_tm;
if disp_tm >= 1
fprintf('\n m=%d,%5d/%d, %.2f sec', m, j, ttl_try, res(i));
disp_tm = 0;
end
end
res(i) = res(i) / ttl_try;
fprintf('\n==> m=%2d: %.6f sec (average of %d trials)', m, res(i), ttl_try);
end
end %%%% function %%%%
end % methods
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
end % classdef
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
running_msg.m
classdef running_msg < handle
% running message
properties
total_tm = 0; % in seconds
disp_tm = 0; % in seconds
start_tm = []; %
stop_tm = []; %
itv = 1; % in seconds
msg = '';
end
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
methods
function obj = running_msg(show_interval)
if nargin >= 1
obj.itv = show_interval;
end
obj.start_tm = clock;
fprintf('start at: %s\n', datestr(obj.start_tm));
end %%%% function %%%%
function obj = add_time(obj, tm, sformat, varargin)
obj.total_tm = obj.total_tm + tm;
obj.disp_tm = obj.disp_tm + tm;
if obj.disp_tm < obj.itv, return; end
obj.disp_tm = 0;
obj.clear();
obj.msg = sprintf([' %.0f sec) ' sformat], obj.total_tm, varargin{:});
fprintf('%s', obj.msg);
end %%%% function %%%%
function obj = clear(obj)
obj.msg(:) = sprintf('\b');
fprintf('%s', obj.msg);
end %%%% function %%%%
function obj = stop(obj)
obj.clear();
obj.stop_tm = clock;
fprintf('stop at.: %s\n', datestr(obj.stop_tm ));
fprintf('CPU time: %.0f sec\n', obj.total_tm);
end %%%% function %%%%
end % methods
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%
end % classdef
%%%%_%%%% %%%%_%%%% %%%%_%%%% %%%%_%%%%

1