📄 differentialevolution.m
字号:
if strcmp(paramDefCell{1,1}, '_1')
str = [str, sprintf('%10g; %s\n', bestmem(parNr), markStr)]; %#ok
else
parameterName = getparametername__(parNr, 1);
str = [str, sprintf('%s%s = %g; %s\n', prefixString, ...
[parameterName, repmat(' ', 1, maxNameLength - ...
length(parameterName))], bestmem(parNr), markStr)]; %#ok
end
end
if bestval >= 1e-5
str = [str, sprintf('Evaluation value: %2.6f\n', bestval)]; % always print zeros
else
str = [str, sprintf('Evaluation value: %2.6g\n', bestval)]; % use exponential notation for small values
end
if bestval == initval && isempty(strfind(state, 'Initial'))
str = [str(1:end-1), sprintf(' (same as initial value)\n')];
end
if ~isempty(allval)
sameEvaluationValue = length(find(allval == bestval));
if sameEvaluationValue > 1
str = [str, sprintf('Number of vectors with same evaluation value: %d\n', sameEvaluationValue)];
end
end
% display information
disp(str);
% play sound
if playSound && mbtime - lastSoundTime > 60
[x, fs, bits] = wavread('applause.wav');
soundsc(x, fs, bits);
pause(length(x) / fs + 1);
lastSoundTime = mbtime;
end
else
sendEmailThisTime = 0;
end
if ~sendEmail
return
end
% send E-mail notification
if sendEmailThisTime
% build subject and body
if bestval >= 1e-5
formatString = '%2.6f'; % always print zeros
else
formatString = '%2.6g'; % use exponential notation for small values
end
if forceParameterDisplay
if ~isempty(strfind(lower(state), 'initial'))
subject = sprintf(sprintf('Initial eval. value: %s', formatString), bestval);
else
subject = sprintf(sprintf('Best eval. value: %s', formatString), bestval);
end
else
subject = sprintf(sprintf('New best eval. value: %s', formatString), bestval);
end
if isfield(optimInfo, 'title')
subject = [subject, sprintf(' (%s, host %s)', optimInfo.title, gethostname)];
else
subject = [subject, sprintf(' (host %s)', gethostname)];
end
if mbtime - lastEmailTime < minTimeBetweenEmails
% do not send now, save data for sending later
lastSubject = subject;
lastStr = str;
sendEmailThisTime = 0;
end
elseif ~isempty(lastSubject) && mbtime - lastEmailTime >= minTimeBetweenEmails
% restore data that was not sent until now
subject = lastSubject;
str = lastStr;
sendEmailThisTime = 1;
end
if sendEmailThisTime
sendmailblat(subject, str);
lastEmailTime = mbtime;
lastSubject = [];
lastStr = [];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [objFctParams, paramVec, paramVec2] = considerparametercontraints__( ...
objFctParams, paramDefCell, parameterDimVector, paramVec)
paramVec2 = paramVec; % not quantized
for parNr = 1:length(paramVec)
% hard bound constraint
parBounds = paramDefCell{parNr, 2};
paramVec (parNr) = min(max(paramVec(parNr), parBounds(1)), parBounds(2));
paramVec2(parNr) = paramVec(parNr);
% parameter quantization
parGrid = paramDefCell{parNr, 3};
if parGrid > 0
paramVec(parNr) = parGrid * round((paramVec(parNr) - parBounds(1)) / ...
parGrid) + parBounds(1);
end
end
% set parameter vector in objFctParams
% (always use quantized value here!)
if ~isempty(objFctParams) && ~strcmp(paramDefCell{1,1}, '_1')
parNr = 1;
while parNr <= length(paramVec)
index = parNr:parNr+parameterDimVector(parNr)-1;
objFctParams.(getparametername__(parNr,2)) = paramVec(index)';
parNr = parNr + parameterDimVector(parNr);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function generatefilesforslaveprocess__(objFctHandle, objFctParams, ...
objFctSettings, paramDefCell, parameterDimVector, pop, allmem, ...
iterationNr, saveHistory, slaveFileDir)
if ~exist(slaveFileDir, 'dir')
return
end
% remove all existing slave files
existingSlaveFiles = findfiles(slaveFileDir, 'iteration_*_member_*_*.mat', 'nonrecursive');
if iterationNr == 0
% no slave process should be running when function differentialevoluation
% is in initialization!
for k=1:length(existingSlaveFiles)
delete(existingSlaveFiles{k});
end
else
deletewithsemaphores(existingSlaveFiles);
end
% build slave file name
slaveFileNameTemplate = concatpath(slaveFileDir, ...
sprintf('iteration_%02d_member_XX_parameters.mat', iterationNr));
% generate new slave files
NP = size(pop,1);
if saveHistory
allmem = [allmem, nan(size(pop,2), NP)];
else
allmem = nan(size(pop,2), NP);
end
nOfCols = size(allmem,2);
for memberNr = NP:-1:1
testmem = pop(memberNr,:);
% get constrained parameter vector
[objFctParams, testmem] = considerparametercontraints__(...
objFctParams, paramDefCell, parameterDimVector, testmem); %#ok
% check if the current parameter vector was tested before
index = find(all(abs(allmem - repmat(testmem', 1, nOfCols)) < 1e-12, 1));
if length(index) > 1
disp('Warning: More than one equal test vector in allmem (internal error?).');
elseif ~isempty(index)
continue
end
% save testmem in allmem, so that no two files with the same parameters are saved
allmem(:,nOfCols-memberNr+1) = testmem';
% get cell array of function arguments
if strcmp(paramDefCell{1,1}, '_1')
% pass parameters as vector
if iscell(objFctSettings)
argumentCell = [objFctSettings, {testmem}];
else
argumentCell = {objFctSettings, testmem};
end
else
% pass parameters as structure objFctParams
if iscell(objFctSettings)
argumentCell = [objFctSettings, {objFctParams}];
else
argumentCell = {objFctSettings, objFctParams};
end
end
% save file
objFctHandle; %#ok
argumentCell; %#ok
memberNrString = sprintf(sprintf('%%0%dd', ceil(log10(NP+1))), memberNr);
slaveFileName = strrep(slaveFileNameTemplate, 'XX', memberNrString);
sem = setfilesemaphore(slaveFileName);
save(slaveFileName, 'objFctHandle', 'argumentCell');
removefilesemaphore(sem);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [testval, testmem, nfeval, allval, allmem] = computeevaluationvalue__(...
testmem, nfeval, timeOver, objFctParams, paramDefCell, parameterDimVector, ...
objFctSettings, objFctHandle, saveHistory, allval, allmem, ...
iterationNr, memberNr, NP, slaveFileDir, maxMasterEvals, XVmin, XVmax)
persistent optParVector nOfMasterEvaluations lastIterationNr
pauseTime = 0.01;
maxPauseTime = 1;
% get constrained parameter vector
[objFctParams, testmem, testmem2] = considerparametercontraints__(...
objFctParams, paramDefCell, parameterDimVector, testmem);
% check if the current parameter vector was tested before
if saveHistory && ~isempty(allmem)
index = find(all(abs(allmem - repmat(testmem', 1, size(allmem, 2))) < 1e-12, 1));
if length(index) > 1
disp('Warning: More than one equal test vector in allmem (internal error?).');
end
else
index = [];
end
if ~exist(slaveFileDir, 'dir')
slaveFileDir = '';
end
if isempty(lastIterationNr) || lastIterationNr ~= iterationNr
lastIterationNr = iterationNr;
nOfMasterEvaluations = 0;
end
if ~isempty(slaveFileDir)
% build slave file name
memberNrString = sprintf(sprintf('%%0%dd', ceil(log10(NP+1))), memberNr);
slaveFileName = concatpath(slaveFileDir, sprintf('iteration_%02d_member_%s_result.mat', ...
iterationNr, memberNrString));
% remove slave parameter file if existing
if nOfMasterEvaluations < maxMasterEvals
slaveParameterFileName = strrep(slaveFileName, 'result', 'parameters');
sem = setfilesemaphore(slaveParameterFileName);
if existfile(slaveParameterFileName)
delete(slaveParameterFileName);
end
removefilesemaphore(sem);
end
end
if isempty(index)
% parameter vector was not tested before
if ~isempty(objFctHandle)
testval = [];
% check if the current parameter vector was tested before by slave process
if ~isempty(slaveFileDir)
while 1
sem = setfilesemaphore(slaveFileName);
if existfile(slaveFileName)
load(slaveFileName, 'testval');
delete(slaveFileName);
nfeval.slave = nfeval.slave + 1;
end
removefilesemaphore(sem);
if ~isempty(testval)
% result of slave process was loaded
break
end
if nOfMasterEvaluations < maxMasterEvals
% master will evaluate current member
break
else
% wait until member was evaluated by slave
% if any of the slave processes is interrupted, this loop will
% never be left!!
pause(pauseTime);
pauseTime = min(2*pauseTime, maxPauseTime);
end
end
end
% evaluate objective function
if isempty(testval) && nOfMasterEvaluations < maxMasterEvals
% run function
if ~timeOver
if strcmp(paramDefCell{1,1}, '_1')
% pass parameters as vector
if iscell(objFctSettings)
testval = objFctHandle(objFctSettings{:}, testmem');
else
testval = objFctHandle(objFctSettings, testmem');
end
else
% pass parameters as structure objFctParams
if iscell(objFctSettings)
testval = objFctHandle(objFctSettings{:}, objFctParams);
else
testval = objFctHandle(objFctSettings, objFctParams);
end
end
nOfMasterEvaluations = nOfMasterEvaluations + 1;
else
testval = NaN;
end
end
% check returned value
if isempty(testval)
error('Objective function returned empty evaluation value!');
elseif ~isscalar(testval)
error('Objective function returned vector as evaluation value!');
elseif isnan(testval) && ~timeOver
error('Objective function returned NaN as evaluation value!');
end
else
% compute distance to randomly chosen vector for testing
if isempty(optParVector)
optParVector = XVmin + rand(1, length(XVmin)) .* (XVmax - XVmin);
end
testval = sqrt(sum(testmem - optParVector).^2);
pause(0.2);
end
if ~isnan(testval)
% count the overall number of function evaluations
nfeval.local = nfeval.local + 1;
% save tested vector and resulting cost value
if saveHistory
allmem(:,end+1) = testmem';
allval (end+1) = testval;
end
end
else
% parameter vector was tested before
testval = allval(index);
nfeval.saved = nfeval.saved + 1;
end
% write non-quantized value into population
testmem = testmem2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -