ANNEX D: Proposed MATLAB code

Một phần của tài liệu Develop a project planning method based on building information model (bim) to optimally reduce activity overlaps and time cost (Trang 101 - 108)

clc;

clear;

% Main script

% Define the network Activity =

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 ,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];

Duration =

[5,2,5,2,3,3,6,4,3,4,2,3,3,4,4,1,6,5,10,7,1,11,3,5,5,7,3,3,3,3,2,6,5,2,4,2,2,2,7, 7,5,5,14,5,7,4,1,2,7,5,2];

Predecessors =

{[],1,1,3,2,4,[1,3],7,8,8,10,9,11,5,6,7,7,17,[14,15],[14,15],7,[12,13],[16,17,18]

,19,24,3,26,26,28,27,30,31,[30,31],33,33,35,34,37,30,39,32,41,[39,40],43,[37,38], [41,42],32,[21,37,38],[43,44],49,50};

Relationship =

{{},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS','FS'},{'FS'},{'FS'},{'FS'},{'FS'},{' FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS','FS'},{'FS','FS'},{'FS'},{'F S','FS'},{'FS','FS','FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'}

,{'FS'},{'FS','FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'},{'FS'

},{'FS','FS'},{'FS'},{'FS','FS'},{'FS','FS'},{'FS'},{'FS','FS','FS'},{'FS','FS'}, {'FS'},{'FS'}};

Lag =

{[0],[0],[0],[0],[0],[0],[0,0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0,0], [0,0],[0],[0,0],[0,0,0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0,0],[0],[0],[0],[0]

,[0],[0],[0],[0],[0],[0,0],[0],[0,0],[0,0],[0],[0,0,0],[0,0],[0],[0]};

RiskMoney =

[10,200,200,50,100,50,370,350,400,450,350,300,179,100,100,20,100,200,600,800,80,7 0,50,300,433,100,200,200,150,400,300,40,447,255,437,140,100,100,600,400,200,300,2 71,200,200,50,50,100,200,50,50];

% Calculate ES, EF, LS, LF, and TF

[ES, EF, LS, LF, TF] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag);

% Calculate SOR

SOR = calculateSOR(ES, EF, Duration, Activity);

% Display total initial SOR value disp('Initial SOR:');

disp(SOR);

nvars = length(Activity);

lb = zeros(1, nvars);

% Define MaxTF MaxTF = max(TF);

% Set the upper bound as the minimum of TF and MaxTF ub = min(TF, MaxTF);

intCon = 1:nvars; % Define integer constraints

% Define multi-33 fitness function

fitnessFunctionWrapper = @(x) [objective2(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag), ...

objective1(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag, RiskMoney), ...

objective3(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag)];

% Print the results

T = table(Activity', Duration', ES', EF', LS', LF', TF', RiskMoney', 'VariableNames', {'Activity', 'Duration', 'ES', 'EF', 'LS', 'LF', 'TF', 'RiskMoney'});

disp(T);

% Find the critical path

criticalPath = Activity(TF == 0);

disp("The critical path is:");

disp(criticalPath);

% Calculate project duration totalDuration = max(EF);

disp("The total project duration is:");

disp(totalDuration);

% Set GA options popSize = 500;

maxGenerations = 500;

crossoverFraction = 0.8;

stallGenLimit = 500;

options = optimoptions('gamultiobj', 'PopulationSize', popSize, 'MaxGenerations', maxGenerations, 'StallGenLimit', stallGenLimit, 'Display', 'iter', 'PlotFcn', {@myGaplotPareto},'CrossoverFcn', @myCrossoverFcn);

% Run the GA

[xPareto, fvalPareto] = gamultiobj(fitnessFunctionWrapper, nvars, [], [], [], [], lb, ub, [], intCon, options);

% Display Pareto front results disp('Pareto front results:');

disp([xPareto, fvalPareto]);

% Sort Pareto front solutions based on the total overlap days [sortedFvalPareto, sortedIdx] = sortrows(fvalPareto, 1);

sortedXPareto = xPareto(sortedIdx, :);

% Find the best solution for each objective

[minObjective1, idxObjective1] = min(fvalPareto(:, 1));

[minObjective2, idxObjective2] = min(fvalPareto(:, 2));

[minObjective3, idxObjective3] = min(fvalPareto(:, 3));

% Display the best solutions

disp('Best solution for Objective 1:');

disp(['Total Overlap Days: ', num2str(minObjective1)]);

disp('Movable Duration:');

movable_duration_obj1 = xPareto(idxObjective1, :);

disp(movable_duration_obj1);

disp(xPareto(idxObjective1, :));

disp('Best solution for Objective 2:');

disp(['Total Risk Money: ', num2str(minObjective2)]);

disp('Movable Duration:');

movable_duration_obj2 = xPareto(idxObjective2, :);

disp(movable_duration_obj2);

disp(xPareto(idxObjective2, :));

% Find the best solution for Objective 3

[minObjective3, idxObjective3] = min(fvalPareto(:, 3));

disp('Best solution for Objective 3:');

disp(['Total SOR: ', num2str(minObjective3, '%.4f')]);

disp('Movable Duration:');

movable_duration_obj3 = xPareto(idxObjective3, :);

disp(movable_duration_obj3);

disp(xPareto(idxObjective3, :));

% Calculate new ES, EF, LS, LF, and TF for the best solutions

[ES_obj1, EF_obj1, LS_obj1, LF_obj1, TF_obj1] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES + xPareto(idxObjective1, :));

[ES_obj2, EF_obj2, LS_obj2, LF_obj2, TF_obj2] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES + xPareto(idxObjective2, :));

[ES_obj3, EF_obj3, LS_obj3, LF_obj3, TF_obj3] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES + xPareto(idxObjective3, :));

% Create SOR table for objective 3

SOR_obj3 = calculateSOR(ES_obj3, EF_obj3, Duration, Activity);

% Create new tables for best solutions

T_obj1 = table(Activity', Duration', ES_obj1', EF_obj1', LS_obj1', LF_obj1', TF_obj1', RiskMoney', 'VariableNames', {'Activity', 'Duration', 'ES', 'EF', 'LS', 'LF', 'TF', 'RiskMoney'});

T_obj2 = table(Activity', Duration', ES_obj2', EF_obj2', LS_obj2', LF_obj2', TF_obj2', RiskMoney', 'VariableNames', {'Activity', 'Duration', 'ES', 'EF', 'LS', 'LF', 'TF', 'RiskMoney'});

T_obj3 = table(Activity', Duration', ES_obj3', EF_obj3', LS_obj3', LF_obj3', TF_obj3', RiskMoney', 'VariableNames', {'Activity', 'Duration', 'ES', 'EF', 'LS', 'LF', 'TF', 'RiskMoney'});

% Display the new tables

disp('New table activity for best solution of Objective 1:');

disp(T_obj1);

disp('New table activity for best solution of Objective 2:');

disp(T_obj2);

disp('New table activity for best solution of Objective 3:');

disp(T_obj3);

% Define objective functions

function totalRiskMoney = objective1(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag, RiskMoney)

% Calculate ES and EF for the given x values ES_opt = ES + x;

[ES_opt, EF_opt, ~, ~, ~] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES_opt);

% Calculate total risk money

OverlapF = zeros(length(Activity));

for i = 1:length(Activity)-1 for j = i+1:length(Activity)

OverlapF(i,j) = max(0, min(EF_opt(i), EF_opt(j)) - max(ES_opt(i), ES_opt(j)));

end end

OverlapRiskMoney = OverlapF .* (RiskMoney' + RiskMoney);

totalRiskMoney = sum(OverlapRiskMoney(:));

end

function totalOverlapDays = objective2(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag)

% Calculate ES and EF for the given x values ES_opt = ES + x;

[ES_opt, EF_opt, ~, ~, ~] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES_opt);

% Calculate total overlapping days OverlapDays = zeros(length(Activity));

for i = 1:length(Activity)-1 for j = i+1:length(Activity)

OverlapDays(i,j) = max(0, min(EF_opt(i), EF_opt(j)) - max(ES_opt(i), ES_opt(j)));

end end

totalOverlapDays = sum(OverlapDays(:));

end

function totalSOR = objective3(x, ES, EF, Duration, Activity, Predecessors, Relationship, Lag)

% Calculate ES and EF for the given x values ES_opt = ES + x;

[ES_opt, EF_opt, ~, ~, ~] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES_opt);

% Calculate SOR

SOR = calculateSOR(ES_opt, EF_opt, Duration, Activity);

% Calculate total SOR totalSOR = 0;

for i = 1:length(Activity)-1 for j = i+1:length(Activity) totalSOR = sum(sum(SOR));

end end end

function SOR = calculateSOR(ES, EF, Duration, Activity, ~) SOR = zeros(length(Activity));

for i = 1:length(Activity) for j = 1:length(Activity) if i ~= j

% Calculate SOR based on different cases if ES(j) <= ES(i) && EF(j) <= EF(i)

SOR(i,j) = (EF(j) - ES(i))/Duration(j); % Case 1

elseif ES(j) <= ES(i) && EF(j) >= EF(i)

SOR(i,j) = (EF(i) - ES(i))/Duration(j); % Case 2

elseif ES(j) >= ES(i) && EF(j) <= EF(i) SOR(i,j) = 1; % Case 3

elseif ES(j) >= ES(i) && EF(j) >= EF(i)

SOR(i,j) = (EF(i) - ES(j))/Duration(j); % Case 4

elseif ES(j) >= EF(i) || EF(j) <= ES(i) SOR(i,j) = 0; % Case 5

end

% Set negative SOR values to 0 if SOR(i, j) < 0

SOR(i, j) = 0;

end end end end end

function [ES, EF, LS, LF, TF] = calculateProjectTimes(Duration, Activity, Predecessors, Relationship, Lag, ES_initial)

if nargin < 6

ES_initial = [];

end

% Calculate ES and EF n = length(Activity);

ES = zeros(1, n);

EF = zeros(1, n);

if ~isempty(ES_initial)

ES = ES_initial;

end

for i = 1:n

if isempty(ES_initial)

if isempty(Predecessors{i}) ES(i) = 0;

else

tempES = zeros(1, length(Predecessors{i}));

for j = 1:length(Predecessors{i}) pred = Predecessors{i}(j);

relation = Relationship{i}{j};

lag = Lag{i}(j);

if strcmp(relation, 'FS') tempES(j) = EF(pred) + lag;

elseif strcmp(relation, 'FF')

tempES(j) = EF(pred) - Duration(i) + lag;

elseif strcmp(relation, 'SS') tempES(j) = ES(pred) + lag;

elseif strcmp(relation, 'SF') tempEF = EF(pred) + lag;

tempES(j) = tempEF - Duration(i);

end end

ES(i) = max(tempES);

end end

EF(i) = ES(i) + Duration(i);

end

% Calculate LF and LS LF = zeros(size(Activity));

LS = zeros(size(Activity));

LF(end) = EF(end);

LS(end) = ES(end);

for i = length(Activity)-1:-1:1

successors = find(cellfun(@(x) ismember(i, x), Predecessors));

if isempty(successors) LF(i) = EF(end);

else

tempLF = ones(1, length(successors)) * inf;

for k = 1:length(successors) suc = successors(k);

for j = 1:length(Predecessors{suc}) if Predecessors{suc}(j) == i rel = Relationship{suc}{j};

lag = Lag{suc}(j);

switch rel case 'FS'

tempLF(k) = min(tempLF(k), LS(suc) - lag);

case 'FF'

tempLF(k) = min(tempLF(k), LF(suc) - lag);

case 'SS'

tempLF(k) = min(tempLF(k), LS(suc) + Duration(i) - lag);

case 'SF'

tempLF(k) = min(tempLF(k), LF(suc) + Duration(i) - lag);

otherwise

error('Invalid relationship type.');

end end end end

LF(i) = min(tempLF);

end

LS(i) = LF(i) - Duration(i);

end

% Calculate TF TF = LS - ES;

end

function [xoverKids] = myCrossoverFcn(parents, options, nvars, FitnessFcn, unused,thisPopulation)

%MYCROSSOVERFCN Custom crossover function that implements multi-point crossover

% [xoverKids] = MYCROSSOVERFCN(PARENTS, OPTIONS, NVARS, FITNESSFCN, UNUSED, THISPOPULATION)

% Determine crossover points numCrossoverPoints = 2;

crossoverPoints = randi([1 nvars],1,numCrossoverPoints);

% Create offspring solutions by swapping gene values between parents at crossover points

nKids = length(parents)/2;

xoverKids = zeros(nKids,nvars);

index = 1;

for i=1:nKids

parent1 = thisPopulation(parents(index),:);

parent2 = thisPopulation(parents(index+1),:);

for j=1:numCrossoverPoints

xoverKids(i,crossoverPoints(j):end) = parent2(crossoverPoints(j):end);

xoverKids(i,crossoverPoints(j):end) = parent1(crossoverPoints(j):end);

end

index = index + 2;

end end

Một phần của tài liệu Develop a project planning method based on building information model (bim) to optimally reduce activity overlaps and time cost (Trang 101 - 108)

Tải bản đầy đủ (PDF)

(108 trang)