-
Notifications
You must be signed in to change notification settings - Fork 1
/
new_generation.m
111 lines (87 loc) · 3.95 KB
/
new_generation.m
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
function parent = new_generation(parent,PerfA,sort_str,options)
% This function generate the next generation of individuals
MaxVar=options.MaxFeatures;
MinVar=options.MinFeatures;
ConfFact=options.ConfoundingFactors;
crsovFcn=options.CrossoverFcn;
mutFcn=options.MutationFcn;
mutation_rate=options.MutationRate;
POP_SIZE = size(parent,1) ;
VAR_NUM = size(parent,2) ;
POP_xover = POP_SIZE/2 ;
POP_elite = floor( (options.Elitism/100)*POP_SIZE ) ;
mutation_prop = .2 ; % TODO: Make this a parameter in options
%% Selection
%TODO: Check if this sort calculation is still needed, as a sort is
%performed in the main function (AlgoGen or GA_GUI)
% sort parent generation by increasing or decreasing performance
[BestPerfA BestPerfAIdx] = sort(PerfA,sort_str);
% Pass down the X% best performers to the next generation
elderly = parent( BestPerfAIdx(1:POP_elite) , : ) ;
% Select the 1st half of the population to undergo cross-over
repro = parent( BestPerfAIdx(1:POP_xover) , : ) ;
%% Cross-over
[ children ] = feval(crsovFcn, repro );
%% Mutation
[ children ] = feval(mutFcn, children, [mutation_prop, mutation_rate]);
% Children currently contains the population without the elitist genomes
%% Make sure that confounding factors are still included + Max/Min vars
if ~isempty(ConfFact) && ~isnan(ConfFact) && (length(ConfFact)>1 || ConfFact~=0)
% Force confounding factors
children(:,ConfFact)=true(size(children,1),length(ConfFact));
end
% TODO: Possible to save on processing time when MinFeat=MaxFeat ?
varSum=sum(children,2);
if MaxVar>0 % Ensure number of features < MaxVar
% Find locations which have too many variables
maxVarIdx=find((varSum>MaxVar) == 1);
% Randomly select true bits to flip
for k=1:length(maxVarIdx) % TODO: Good luck vectorizing this.
kthChild=find(children(maxVarIdx(k),:)==1); % Indices of true bits
[~,maxRandPerm] = sort(rand(1,varSum(maxVarIdx(k)))); % Random indices of true bits
% The number of parameters we must flip ..
nFlip=length(maxRandPerm)-MaxVar;
% Do not flip confounding factors
maxRandPerm=setdiff(maxRandPerm,ConfFact);
if nFlip<=length(maxRandPerm) % Still have enough factors to flip
children(maxVarIdx(k),kthChild(maxRandPerm(1:nFlip)))=0;
else
% Oh well, flip what we can and complain
children(maxVarIdx(k),kthChild(maxRandPerm(1:end)))=0;
warning('GA:AlgoGen:new_generation:CounfingFactorsConflict', ...
['More confounding factors entered than maximally\n' ...
'allowed features. The MaxFeatures parameter should\n' ...
'be lowered.']);
end
end
% [trueBitsI,trueBitsJ]=ind2sub(size(children(maxVarIdx,:)),find(children(maxVarIdx,:)==1)); % Linear index
end
if MinVar>0 % Ensure number of features > MinVar
% Find locations which have too few variables
minVarIdx=find((varSum<MinVar) == 1);
% Randomly select false bits to flip
for k=1:length(minVarIdx) % TODO: Good luck vectorizing this.
kthChild=find(children(minVarIdx(k),:)==0); % Indices of false bits
[~,minRandPerm] = sort(rand(1,varSum(minVarIdx(k)))); % Random indices of false bits
children(minVarIdx(k),kthChild(minRandPerm(1:MinVar-varSum(k))))=1;
end
end
%% Replace twins by aliens
twins = 1;
diff = ones(2*POP_xover,2*POP_xover);
% nonTwinIdx=true(2*POP_xover,1);
% twinCmpFcn=@(children,i) any(sqrt(sum((children(i,:)-children(1:i-1,:)).^2))==0);
for i = 1:2*POP_xover
for j=(i+1):2*POP_xover
diff(i,j) = sum((children(i,:)-children(j,:)).^2);
end
end
[r,c] = find(diff==0);
twins = unique([r ; c]);
if ~isempty(twins)
options.PopulationSize=length(twins); % Temporary change.
children(twins,:) = initialize_pop(options,VAR_NUM);
end % Some twins might still be present after generation of random aliens BUT we don't care that much
parent = [elderly ; children] ;
parent = parent(1:POP_SIZE,:);
end