📄 differentialevolution.m
字号:
% display current best member if it has changed or if display is forced
if ~any(isnan(lastbestmem)) && any(size(bestmem) ~= size(lastbestmem))
error('Internal error: bestmem and lastbestmem are of different size!');
end
if any(bestmem ~= lastbestmem) || forceParameterDisplay
sendEmailThisTime = 1;
lastbestmem = bestmem;
% display state
str = sprintf('%s\n', state);
% get quantized parameter vector for display
[ignore, bestmem] = considerparametercontraints__([], paramDefCell, ...
parameterDimVector, bestmem); %#ok
switch [username '@' hostname]
case 'Markus@Edison'
prefixString = 'param.';
otherwise
prefixString = '';
end
str = [str, sprintf('Best member:\n')];
if all(bestmem == initmem) && isempty(strfind(state, 'Initial'))
str = [str(1:end-2), sprintf(' (same as initial member):\n')];
end
for parNr=1:D
if any(bestmem(parNr) == paramDefCell{parNr, 2});
markStr = '% (boundary value)';
else
markStr = '';
end
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 && ~isempty(lastSoundTime) && 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; % paramVec2: 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
minQuantization = 1e-14;
parGrid = paramDefCell{parNr, 3};
parGrid = max(parGrid, minQuantization); % quantize with at least some value larger eps, see also checkinputs__
paramVec(parNr) = parGrid * round((paramVec(parNr) - parBounds(1)) / ...
parGrid) + parBounds(1);
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, validChkHandle)
if ~exist(slaveFileDir, 'dir')
return
end
% remove all existing slave files
existingSlaveFiles = findfiles(slaveFileDir, 'iteration_*_member_*_*.mat', 'nonrecursive');
deletewithsemaphores(existingSlaveFiles);
% 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
if ~paramvecvalidity__(paramDefCell, objFctSettings, objFctParams, testmem, validChkHandle)
% parameter vector invalid
continue
end
% check if the current parameter vector was tested before
index = find(all(abs(allmem - repmat(testmem', 1, nOfCols)) < eps, 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
memberNrString = sprintf(sprintf('%%0%dd', ceil(log10(NP+1))), memberNr);
slaveFileName = strrep(slaveFileNameTemplate, 'XX', memberNrString);
sem = setfilesemaphore(slaveFileName);
objFctHandle; %#ok
argumentCell; %#ok
save(slaveFileName, 'objFctHandle', 'argumentCell');
removefilesemaphore(sem);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function valid = paramvecvalidity__(paramDefCell, objFctSettings, objFctParams, ...
testmem, validChkHandle)
if strcmp(paramDefCell{1,1}, '_1')
% pass parameters as vector
if iscell(objFctSettings)
valid = validChkHandle(objFctSettings{:}, testmem');
else
valid = validChkHandle(objFctSettings, testmem');
end
else
% pass parameters as structure objFctParams
if iscell(objFctSettings)
valid = validChkHandle(objFctSettings{:}, objFctParams);
else
valid = validChkHandle(objFctSettings, objFctParams);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [testval, testmem, nfeval, allval, allmem] = computeevaluationvalue__(...
testmem, nfeval, timeOver, objFctParams, paramDefCell, parameterDimVector, ...
objFctSettings, objFctHandle, saveHistory, allval, allmem, iterationNr, ...
memberNr, NP, slaveFileDir, maxMasterEvals, validChkHandle, XVmin, XVmax)
persistent optParVector nOfMasterEvaluations lastIterationNr
pauseTime = 0.1;
maxPauseTime = 1;
if nargin == 0
lastIterationNr = NaN;
nOfMasterEvaluations = 0;
return
end
% get constrained parameter vector
[objFctParams, testmem, testmem2] = considerparametercontraints__(...
objFctParams, paramDefCell, parameterDimVector, testmem);
% check if current parameter vector is valid
if ~paramvecvalidity__(paramDefCell, objFctSettings, objFctParams, testmem, validChkHandle)
testval = NaN;
else
% check if current parameter vector was tested before
if saveHistory && ~isempty(allmem)
index = find(all(abs(allmem - repmat(testmem', 1, size(allmem, 2))) < eps, 1));
if length(index) > 1
disp('Warning: More than one equal test vector in allmem (internal error?).');
index = index(1);
end
else
index = [];
end
if ~isempty(index)
% parameter vector was tested before
testval = allval(index);
nfeval.saved = nfeval.saved + 1;
else
% parameter vector was not tested before, compute evaluation value or
% read from slave
% build slave file name
if ~exist(slaveFileDir, 'dir')
slaveFileDir = '';
end
if lastIterationNr ~= iterationNr
lastIterationNr = iterationNr;
nOfMasterEvaluations = 0;
end
if ~isempty(slaveFileDir)
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(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 st
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -