Home > matpower7.1 > extras > syngrid > lib > sgvm_GenerationClass.m

sgvm_GenerationClass

PURPOSE ^

SYNOPSIS ^

This is a script file.

DESCRIPTION ^

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 classdef sgvm_GenerationClass < handle
0002 %SGVM_GENERATIONCLASS collection of SGVM_INDCLASS objects
0003 %   G = SGVM_GENERATIONCLASS(MPC, INDS, OPT) inializes a new generation of INDS
0004 %   individuals (SGVM_INDCLASS objects) based on seed MATPOWER case MPC.
0005 
0006 %   SynGrid
0007 %   Copyright (c) 2018, Power Systems Engineering Research Center (PSERC)
0008 %   by Eran Schweitzer, Arizona State University
0009 %
0010 %   This file is part of SynGrid.
0011 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0012 
0013     properties
0014         init
0015         inds
0016         soln
0017         solnlist
0018         node_progen
0019         branch_progen
0020         current_gen
0021         exitflag
0022         stash
0023         basempc
0024     end
0025     methods
0026         function obj = sgvm_GenerationClass(mpc, inds, opt)
0027             if isa(mpc, 'sgvm_GenerationClass')
0028               current_gen = mpc.current_gen;
0029               mpc = mpc.basempc;
0030             else
0031               current_gen = 0;
0032             end
0033             %% initialize generation class object
0034             if ~isempty(opt.vm.opflogpath)
0035               if ~exist(opt.vm.opflogpath,'dir')
0036                   mkdir(opt.vm.opflogpath)
0037               end
0038             end
0039             obj.basempc  = mpc;
0040             obj.exitflag = false;
0041             obj.solnlist      = {};
0042                 obj.node_progen   = {};
0043                 obj.branch_progen = {};
0044                 obj.stash = sgvm_SolnStash(opt.vm.ea.select);
0045             obj.init = inds;
0046             % initials inds random branch permutations
0047                 s = warning;
0048                 warning('off','MATLAB:nearlySingularMatrix')
0049                 warning('off','MATLAB:SingularMatrix')
0050             if ~opt.vm.parallel.use %isempty(gcp('nocreate'))
0051               obj.inds = cell(1,inds);
0052               for k = 1:inds
0053                   obj.inds{k} = sgvm_IndClass(mpc, 'init', current_gen, opt);
0054               end
0055             else
0056               tmpinds = cell(1,inds);
0057               parfor k = 1:inds
0058                   tmpinds{k} = sgvm_IndClass(mpc, 'init', current_gen, opt);
0059               end
0060               obj.inds = tmpinds;
0061             end
0062             obj.current_gen = current_gen;
0063             obj.soln = {};
0064             obj.expand_soln()
0065                 warning(s); %restore normal warning state
0066         end
0067 
0068         function perm_loop(obj, type, opt)
0069             %% perform permutaton on individuals thereby generating offsprings
0070 
0071             % compare new parents with previous parents
0072             lstname = [type, '_progen'];
0073             new_parents = cellfun(@(x) x.id, obj.inds, 'UniformOutput', false);
0074             % only keep new parents
0075             new_parents = new_parents(~ismember(new_parents, obj.(lstname)));
0076             % add to list
0077             obj.(lstname) = horzcat(obj.(lstname), new_parents);
0078 
0079             % add solutions that are not on the old_parents list
0080             if (length(obj.soln) < obj.stash.size) && (length(obj.soln) > 0)
0081                 tmplist = cellfun(@(x) x.id, obj.soln, 'UniformOutput', false);
0082                 tmpmask = false(size(tmplist));
0083                 for k = 1:length(obj.soln)
0084                     if ~ismember(obj.soln{k}.id, obj.(lstname))
0085                         tmpmask(k) = true;
0086                     end
0087                 end
0088                 obj.inds = horzcat(obj.inds, obj.soln(tmpmask));
0089                 obj.(lstname) = horzcat(obj.(lstname), tmplist(tmpmask));
0090             end
0091 
0092             s = warning;
0093             warning('off','MATLAB:nearlySingularMatrix')
0094             warning('off','MATLAB:SingularMatrix')
0095             chldr = cell(1, length(obj.inds));
0096             niter = opt.vm.([type, 'perm']).niter;
0097             gen = obj.current_gen;
0098             if ~opt.vm.parallel.use %isempty(gcp('nocreate'))
0099                 % loop over individuals
0100                 for k = 1:length(obj.inds)
0101                     if ~ismember(obj.inds{k}.id, new_parents)
0102                         continue
0103                     end
0104                     % for each individuals perform permutation niter times
0105                     tmp = obj.evolve_children(obj.inds{k}, niter, type, gen, opt);
0106                     chldr{k} = tmp;
0107                 end
0108             else
0109               tmpinds = obj.inds;
0110               parfor k = 1:length(tmpinds)
0111                 if ~ismember(tmpinds{k}.id, new_parents)
0112                   continue
0113                 end
0114                 % for each individuals perform permutation niter times
0115                 tmp = obj.evolve_children(tmpinds{k}, niter, type, gen, opt);
0116                 chldr{k} = tmp;
0117               end
0118             end
0119             % merge children and orders based on objective
0120             obj.merge_children(chldr);
0121             obj.expand_soln()
0122                 obj.stash.update(obj.inds);
0123                 obj.clear_old_inds(type);
0124                 warning(s); %restore normal warning state
0125 
0126             if isempty(obj.inds)
0127               if length(obj.soln) >= opt.vm.ea.select
0128                 obj.exitflag = true;
0129               else
0130                 if opt.verbose > 0
0131                   fprintf('Empty inds cell encountered, restarting with a new initial generation.\n')
0132                 end
0133                   tmp = sgvm_GenerationClass(obj, opt.vm.ea.inds, opt);
0134                   obj.merge(tmp);
0135               end
0136             end
0137         end
0138 
0139         function update_gen(obj)
0140             obj.current_gen = obj.current_gen + 1;
0141         end
0142 
0143         function clear_old_inds(obj, type)
0144             % clear inds that will no longer produce new children
0145             % cases:
0146             %     curent gen | loop  completed | what is old?
0147             %   -----------|-----------------|--------------------------------------
0148             %       x      | branch            | anything from gen x-2 or x-1.branch
0149             %       x      | node            | anything from gen x-2 or x-1.node
0150             for k = 1:length(obj.inds)
0151                 if obj.inds{k}.gen <= obj.current_gen-2
0152                   obj.inds{k} = [];
0153                 elseif (obj.inds{k}.gen == obj.current_gen-1) && strcmp(obj.inds{k}.call, type)
0154                   obj.inds{k} = [];
0155                 end
0156             end
0157             obj.inds = obj.inds(~cellfun(@isempty, obj.inds));
0158         end
0159 
0160         function reactive_planning(obj, opt)
0161             % add shunt elements to each individual in the soln field
0162             if ~opt.vm.parallel.use %isempty(gcp('nocreate'))
0163                 for k = 1:length(obj.soln)
0164                     obj.soln{k}.add_shunts(opt);
0165                 end
0166             else
0167                 tmp = obj.soln;
0168                 parfor k = 1:length(obj.soln)
0169                     tmp{k} = tmp{k}.add_shunts(opt);
0170                 end
0171                 obj.soln = tmp;
0172             end
0173         end
0174 
0175         function merge_children(obj, children)
0176             % merge children and inds objects.
0177             % In the process individuals that
0178             % have not been solved or failed to solved are removed
0179             % also sorts individuals based on their objective function.
0180 
0181             n = sum(cellfun(@length, children)) + length(obj.inds);
0182             tmp = cell(1,n);
0183             tmplist = cell(1,n);
0184             ptr = 1;
0185             for k = 1:length(obj.inds)
0186               if obj.inds{k}.solcheck() && ~ismember(obj.inds{k}.id, tmplist(1:ptr-1))
0187                 tmp{ptr} = obj.inds{k};
0188                 tmplist{ptr} = obj.inds{k}.id;
0189               else
0190                 tmplist{ptr} = '';
0191               end
0192               ptr = ptr + 1;
0193               for h = 1:length(children{k})
0194                 if children{k}{h}.solcheck() && ~ismember(children{k}{h}.id, tmplist(1:ptr-1))
0195                   tmp{ptr} = children{k}{h};
0196                   tmplist{ptr} = children{k}{h}.id;
0197                 else
0198                   tmplist{ptr} = '';
0199                 end
0200                 ptr = ptr + 1;
0201               end
0202             end
0203             obj.inds = tmp(~cellfun(@isempty, tmp));
0204 
0205             % sort based on objective function
0206             [~, I] = sort(cellfun(@(x) x.mpc.f, obj.inds));
0207             obj.inds = obj.inds(I);
0208         end
0209 
0210         function merge_stash(obj)
0211             obj.inds = horzcat(obj.inds, obj.stash.inds(1:obj.stash.count));
0212             % sort based on objective function
0213             [~, I] = sort(cellfun(@(x) x.mpc.f, obj.inds));
0214             obj.inds = obj.inds(I);
0215         end
0216 
0217         function inds_remove_soln(obj)
0218             for k = 1:length(obj.inds)
0219                 if ismember(obj.inds{k}.id, obj.solnlist)
0220                     obj.inds{k} = [];
0221                 end
0222             end
0223             obj.inds = obj.inds(~cellfun(@isempty, obj.inds));
0224         end
0225 
0226         function select(obj, inds, randnew, opt)
0227             % Select the best inds out of obj.inds and create randnew individuals
0228             % based on mpc
0229             % assumes that obj.inds is ordered based on objective values
0230             % in ASCENDING order, therefore the best are simple obj.inds(1:inds)
0231 
0232             n = inds + randnew;
0233             if n <= 0
0234               obj.inds = {};
0235               return
0236             end
0237             if inds <= length(obj.inds)
0238               obj.inds = obj.inds(1:inds);
0239             end
0240             if nargin == 4 % don't create new individuals if not opt structure given
0241               if (randnew > 0) || (opt.vm.ea.initfill && (length(obj.inds) < inds))
0242                 tmp = sgvm_GenerationClass(obj, n - length(obj.inds), opt);
0243                 obj.merge(tmp);
0244               end
0245             end
0246         end
0247 
0248         function merge(obj, x)
0249             % merges the individuals in x into obj's inds
0250             obj.inds = horzcat(obj.inds, x.inds);
0251             obj.expand_soln();
0252         end
0253 
0254         function expand_soln(obj)
0255             % copy individual k from the inds array to the soln array
0256             for k = 1:length(obj.inds)
0257               if obj.inds{k}.iscomplete() && ~ismember(obj.inds{k}.id, obj.solnlist)
0258                 obj.soln = horzcat(obj.soln, {obj.inds{k}});
0259                 obj.solnlist = horzcat(obj.solnlist, obj.inds{k}.id);
0260               end
0261             end
0262             if ~isempty(obj.soln)
0263               [~, I] = sort(cellfun(@(x) x.mpc.f, obj.soln));
0264               obj.soln = obj.soln(I);
0265             end
0266         end
0267 
0268         function picksoln(obj, n)
0269             % pick n entries out of the solution array. Entries are already
0270             % sorted by cost, and by definition they have no overloaded branches.
0271 
0272             if length(obj.soln) <= n
0273               return
0274             end
0275             obj.soln = obj.soln(1:n);
0276             if ~any(cellfun(@(x) x.gen >= obj.current_gen-1, obj.inds)) || isempty(obj.inds)
0277               % if no individuals are from this or the previous generation, AND a
0278               % sufficient number of solutions has already been found, then exit.
0279               obj.exitflag = true;
0280             end
0281         end
0282 
0283         function [mpc_array, status] = mpc_export(obj, field)
0284             % Export the matpower cases from either soln (default) or inds, to a
0285             % cell array of matpower cases.
0286             if nargin == 1
0287               field = 'soln';
0288             end
0289 
0290             mpc_array = cellfun(@(x) x.mpc, obj.(field), 'UniformOutput', 0);
0291             status    = cellfun(@(x) x.mpc.success*x.iscomplete(2), obj.(field));
0292         end
0293 
0294         function stats(obj, field)
0295             if nargin == 1
0296               field = 'inds';
0297             end
0298             sgvm_collection_stats(obj, field);
0299         end
0300 
0301         %% ------  private methods  -----------
0302         function chldr = evolve_children(obj, parent, niter, type, gen, opt)
0303             % for each individual perform permutation
0304             % niter times
0305 
0306             chldr = cell(1,niter);
0307             breakflag = false;
0308             for h = 1:niter
0309                 if parent.solcheck()
0310                   if h == 1
0311                       chldr{h} = sgvm_IndClass(parent, type, gen, opt);
0312                   elseif chldr{h-1}.solcheck()
0313                       chldr{h} = sgvm_IndClass(chldr{h-1}, type, gen, opt);
0314                   else
0315                       chldr{h} = sgvm_IndClass(parent.mpc, 'init', gen, opt);
0316                   end
0317                 else
0318                   chldr{h} = sgvm_IndClass(parent.mpc, 'init', gen, opt);
0319                 end
0320 
0321             %     if chldr{h}.iscomplete() && strcmp(type, 'branch')
0322             %         % check whether child satisfies all constraints
0323             %         breakflag = true;
0324             %     end
0325 
0326                 if h > 1
0327                   if chldr{h-1}.comp_perm(chldr{h})
0328                     % permutation didn't change
0329                     chldr{h} = [];
0330                     breakflag = true;
0331                   end
0332                 else
0333                   if parent.comp_perm(chldr{h})
0334                     % permutation didn't change
0335                     chldr{h} = [];
0336                     breakflag = true;
0337                   end
0338                 end
0339                 if breakflag
0340                   break
0341                 end
0342             end
0343             chldr = chldr(~cellfun(@isempty, chldr));
0344         end
0345     end
0346 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005