%prop=geneticEstGoogle(v,indices_list, p, nv, F, varF, pp, generations,pop_size,sigma,mut,eps, iterations)

%This function uses a genetic algorithm to figure out the propensity values that lead to a desired distribution. 
%It uses an approximation of the google steady state distribution in order to evaluate the fitness of the propensities

%parameters-
%indices_list: the states we are trying to modify
%v: the corresponding values we are trying to reach in the those states
%p, nv, F, varF: corresponding to network we are looking at
%pp: the amount of noise we will use when finding the google distribution
%generations: number of times genetic algorithm iterates
%pop_size: number of members of each generation
%sigma: the size of distribution mutations are picked from-larger sigma means larger variations
%mut: the chance that each gene gets mutated
%eps: used in stopping criteria
%iterations: The number of random walks used in approximated the google distribution

%uses: fitnessEstGoogle.m, crossover.m
%Author: Jacob Miller, May 28th, 2016

function prop=geneticEstGoogle(v,indices_list, p, nv, F, varF, pp, generations,pop_size,sigma,mut,eps, iterations)

n=length(nv);%number of genes
% fitnesses=[];
propensities=cell(2*n,pop_size);


%Generate the entire first population
for i=1:pop_size
  c=rand(2,n); %Random propensities
  propensities(:,i)=num2cell(reshape(c,1,2*n)); 

end

%Calculate the probabilites of survival and most fit member of first population
[probabilities,min_index]=fitnessEstGoogle(propensities,indices_list,v,F,varF,nv,p,pp,pop_size,iterations);

%Go throught the remaining generations
for k=1:generations-1

new_propensities=cell(2*n,pop_size);%Store the propensities of the children
new_propensities(:,1)=propensities(:,min_index);

%Create a whole new population for each generation
for i=1:pop_size-1

  p1=find(probabilities>rand(1,1),1);%Pick 2 parents
  p2=find(probabilities>rand(1,1),1);
 
  parent1=cell2mat(propensities(:,p1));
  parent2=cell2mat(propensities(:,p2));
  
  %crossover parent1 and parent2 with a mut chance of mutation and a distribution with standard deviation of sigma
  child=crossover(parent1,parent2,mut,sigma);
%   new_c=reshape(child,2,n);
  new_propensities(:,i+1)=num2cell(child);
  
end

%Find most fit member and chance of survival for each member of each population
[probabilities,min_index]=fitnessEstGoogle(new_propensities,indices_list,v,F,varF,nv,p,pp,pop_size,iterations);

%Make the propensities the new reference point for the next generation
propensities=new_propensities;

end
prop=reshape(cell2mat(propensities(:,min_index)),2,n);%Return most fit set of propensities
end