www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/mbcOSga.m

    function out = mbcOSga(action, in)
%MBCOSGA CAGE Optimization library function
%
%   MBCOSGA contains the configuration and evaluation routines for the
%   CAGE Optimization, GA. This function is called by CAGE using the
%   syntaxes below.
%
%   OPTOBJ = MBCOSGA('OPTIONS', OPTOBJ) is called by CAGE when a
%   GA optimization is created in CAGE. This call defines the
%   structure of the optimization problem, using a CGOPTIMOPTIONS object.
%   The completed configuration for the Optimization is returned to CAGE
%   via OPTOBJ.
%
%   OPTIMSTORE = MBCOSGA('EVALUATE', OPTIMSTORE) is called by CAGE
%   when a user runs a GA optimization. Optimization parameters are
%   passed to the evaluation routine through OPTIMSTORE. The results of the
%   optimization are stored in the OPTIMSTORE object which is returned to
%   CAGE for further processing.
%
%   See also MBCOSNBI, MBCOSFMINCON, MBCOSPSEARCH

%  Copyright 2006-2015 The MathWorks, Inc.


% Deal with the action inputs
if strcmp(action, 'options')
    
    options = in;
    % Add a name
    options = setName(options, 'ga');
    
    % Add a description
    options = setDescription(options, ...
        'Single objective optimization using a genetic algorithm');
   
    % Allow objectives and constraints to be renamed
    options = setRenameMode(options, true);
    
    
    % Set up the operating point sets
    %%%% Any number of operating point sets are allowed %%%%
    options = setOperatingPointsMode(options, 'any');
 
    % Determine whether Global Optimization is available
    hasGADSToolbox = mbcCheckForToolbox(...
        'Global Optimization', ...
        'gads_toolbox', 'globaloptim');
    options = setEnabled(options, hasGADSToolbox);

    % Set up the optimization parameters
    options = addParameter(options, 'Display', ...
        {'list', {'none', 'final', 'iter', 'diagnose'}}, 'none');
    
    options = addParameter(options, 'CrossoverFcn', ...
        {'list', {'scattered', 'heuristic', 'intermediate', ...
        'singlepoint', 'twopoint', 'arithmetic'}}, 'scattered', ...
        'Crossover function');
    
    options = addParameter(options, 'CrossoverFraction', ...
        {'number', 'positive'}, 0.8, 'Crossover fraction');
    
    options = addParameter(options, 'MutationFcn', ...
        {'list', {'adaptfeasible', 'gaussian', 'uniform'}},...
        'adaptfeasible', 'Mutation function'); 
    
    options = addParameter(options, 'SelectionFcn', {'list', ...
        {'tournament', 'remainder', 'uniform', 'stochunif', 'roulette'}}, ...
        'tournament', 'Selection function');  
    
    options = addParameter(options, 'PopulationSize', ...
        {'integer', 'positive'}, 200, 'Population size');
    
    options = addParameter(options, 'Generations', ...
        {'integer', 'positive'}, 500);
    
    options = addParameter(options, 'HybridFcn', {'list', ...
        {'none', 'fminsearch', 'patternsearch', 'fminunc', 'fmincon'}},...
        'none', 'Hybrid function'); 
    
    options = addParameter(options, 'StallGenLimit', ...
        {'integer', 'positive'}, 50, 'Stall generations');
    
    options = addParameter(options, 'StallTimeLimit', ...
        {'number', 'positive'}, 20, 'Stall time limit');
    
    options = addParameter(options, 'TolFun', ...
        {'number', 'positive'}, 1e-006, 'Function tolerance');
    
    options = addParameter(options, 'TolCon', ...
        {'number', 'positive'}, 1e-006, 'Constraint tolerance');
    
    options = addParameter(options, 'TimeLimit', ...
        {'number', 'positive'}, Inf, 'Time limit');
    out = options;
elseif strcmp(action, 'evaluate')
    optimstore = in;
    optimstore = i_Evaluate(optimstore);
    out = optimstore;
else
    error(message('mbc:mbcOSga:InvalidArgument'));
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function optimstore = i_Evaluate(optimstore)

% Ensure that Global Optimization is available
[canCheckOutTlbx, errmsg] = mbcCheckForToolbox(...
    'Global Optimization', ...
    'gads_toolbox', 'globaloptim', true);
if ~canCheckOutTlbx
    error('mbc:mbcOSga:InvalidState', errmsg);
end

% Get the number of free variables for the problem
nFree = sum(getNumFreeVariables(optimstore));

% Set the genetic algorithm operators
CrossoverFcnStr = getParam(optimstore, 'CrossoverFcn');
CrossoverFcn = str2func(strcat('crossover',CrossoverFcnStr));

MutationFcnStr = getParam(optimstore, 'MutationFcn');
MutationFcn = str2func(strcat('mutation',MutationFcnStr));

SelectionFcnStr = getParam(optimstore, 'SelectionFcn');
SelectionFcn = str2func(strcat('selection',SelectionFcnStr));

% Retrieve optimization parameters
TolFun              = getParam(optimstore, 'TolFun');
TolCon              = getParam(optimstore, 'TolCon');
Display             = getParam(optimstore, 'Display');
CrossoverFraction   = getParam(optimstore, 'CrossoverFraction');
PopulationSize      = getParam(optimstore, 'PopulationSize');
Generations         = getParam(optimstore, 'Generations');
StallGenLimit       = getParam(optimstore, 'StallGenLimit');
StallTimeLimit      = getParam(optimstore, 'StallTimeLimit');
TimeLimit           = getParam(optimstore, 'TimeLimit');
HybridFcnStr        = getParam(optimstore, 'HybridFcn');

% Get Bounds and linear constraints
A = getA(optimstore);
B = getB(optimstore);
lb = getLB(optimstore);
ub = getUB(optimstore);

PopInitRange = [lb;ub];

% Set up the hybrid function
if strcmp(HybridFcnStr, 'none')
    HybridFcn = [];
else            
    % Create options for hybrid function
    if strcmp(HybridFcnStr, 'patternsearch')
        HybridOptions = psoptimset('CompletePoll', 'off', ...
            'CompleteSearch', 'off', 'Cache', 'on', ...
            'MeshAccelerator', 'on', 'Vectorized', 'on', ...
            'PollingOrder', 'success', 'TolFun', TolFun, ...
            'TolCon', TolCon, 'Display', Display, ...
            'OutputFcn', @i_HybridPSearchOutput);
    else
        if strcmpi(Display, 'diagnose')
            % Optimization toolbox algorithms do not support a 'diagnose'
            % option.
            HybridDisplay = 'iter';
        else
            HybridDisplay = Display;
        end
        HybridOptions = optimset('LargeScale', 'off', ...
            'Algorithm', 'interior-point', ...
            'TolFun', TolFun, 'TolCon', TolCon, ...
            'Display', HybridDisplay, ...
            'OutputFcn', @i_HybridOptimToolboxOutput);
    end    
   HybridFcn = {str2func(HybridFcnStr), HybridOptions};
end

% Stick them all into a gaoptions structure
options = gaoptimset('TolFun',TolFun,'TolCon', TolCon', 'Display', Display, ...
    'CrossoverFraction', CrossoverFraction, 'PopulationSize', PopulationSize, ...
    'PopInitRange', PopInitRange,...
    'Generations', Generations, ...
    'StallGenLimit', StallGenLimit, 'StallTimeLimit', StallTimeLimit, ...
    'TimeLimit', TimeLimit, 'CrossoverFcn', CrossoverFcn, ...
    'MutationFcn', MutationFcn, 'SelectionFcn', SelectionFcn, ...
    'HybridFcn', HybridFcn, 'Vectorized', 'on',...
    'OutputFcns', @i_Output);

% Workaround issue in ga. If all the bounds are infinite and A, B are
% empty, ga will still pass to the bound constrained algorithm. In our
% view, it should pass to the unconstrained algorithm in this case.
if all(lb == -Inf)
    lb = [];
end
if all(ub == Inf)
    ub = [];
end

% Call optimization algorithm. Workaround issue in ga. If a function handle
% to nonlinear constraints is specified then ga will pass to the nonlinear
% constrained algorithm, even if the nonlinear constraint function returns
% no constraints. It should not pass to the nonlinear contrained algorithm
% in this case (it is currently much slower than the other algorithms).
[c, ceq] = i_evalCon(lb);
if isempty(c) && isempty(ceq)
    [bestx, bestfun, exitFlag, output] = ga(@i_evalObj, nFree, A, B, [], ...
        [], lb, ub, [], options);
else
    [bestx, bestfun, exitFlag, output] = ga(@i_evalObj, nFree, A, B, [], ...
        [], lb, ub, @i_evalCon, options);
end

% Write the results to optimstore
optimstore = setFreeVariables(optimstore, bestx);

% Set all the information in optimstore
optimstore = setExitStatus(optimstore, exitFlag, output.message);
output = rmfield(output, 'message');
optimstore = setOutput(optimstore, output);

    function y = i_evalObj(x)
        % Evaluate the objective function
        y = evaluateObjective(optimstore, x);
        ObjectiveFuncTypes = getObjectiveType(optimstore);
        switch ObjectiveFuncTypes{1}
            case 'max'
                y = -y;
            case 'min'
            otherwise
                error(message('mbc:mbcOSga:InvalidState'));
        end
    end

    function [c, ceq] = i_evalCon(x)        
        % Nonlinear inequality constraints       
        c = evaluateNonlcon(optimstore, x);
        % Nonlinear equality constraints currently not supported
        ceq = [];        
    end

    function [state, options, optchanged] = i_Output(options, state, flag, interval)
        stop = getStopState(optimstore);
        if stop
            state.StopFlag = 'Stop requested';
        end
        optchanged = false;
    end

    function stop = i_HybridOptimToolboxOutput(varargin)
        stop = getStopState(optimstore);
    end

    function [stop, options, optchanged] = i_HybridPSearchOutput(...
            unused1, options, unused2, unused3)
        stop = getStopState(optimstore);
        optchanged = false;
    end

end