create procedure up_evolutionary_data_mining
/* population size */
   @profile_count int,
/* number of generations to run */
   @number_generations int,
/* value we're looking for in the t_mine_relations table */
   @target_value varchar(255),
/* 
Proportion of available population that the best profile pairs
will breed to.  Ex. .333 with a @profile_count of 100
means that the best pair of parents will breed 33 children, the
next best 22 etc.  However, all parents that selected at least
one mine_rlations row will have at least one child
*/
   @population_fill_proportion float(8),
/* average number of columns we use in a profile */
   @column_portion float, /* max num of columns with non-NULL target values */
/* probability operator will be "=" */
   @equality_percent float(8),
/* 
chance a mutation will add a column.  If not a column
will be removed 
*/
   @mutation_add_column_probability float(8),
/*
Probability of a mutation in each birth
*/
   @mutation_probability float(8)
as
declare
   @new_profiles_needed int,
   @generations_done int,
   @parent1 int, @parent2 int,
   @number_to_breed int,
   @breed_step int,
   @bred_total int
begin

/*
clean up prior runs
*/
delete from t_timings
delete from t_profile_column_values
delete from t_profile_column_values_archive
delete from t_profile_archive

/* create the initial population */
exec up_create_initial_population @profile_count, @column_portion, 
   @equality_percent
select @generations_done = 0

while(@generations_done < @number_generations)
begin

   select @generations_done = @generations_done + 1

   exec up_generated_profile_Evaluator
   exec up_profile_results
--   select * from t_profile_results

   insert into t_profile_archive
     (generation,id,test,parent1,parent2,number_right, 
      number_wrong, score)
   select distinct @generations_done as generation,p.id,p.test,
      p.parent1,p.parent2,
      combined.number_right, combined.number_wrong, combined.score
   from t_profile_column_values p,
      .dbo.uf_profile_Score ('1') combined

   where 
      combined.id = p.id
   insert into t_profile_column_values_archive
      (archiveid, c_name,operator,c_value)
   select
       a.archiveid, p.c_name, p.operator,p.c_value
   from t_profile_archive a, t_profile_column_values p
   where a.id = p.id 

   /*
   get the best profiles - those with the best score
   */
   select id as id, number_right, number_wrong
   into #saved_profiles
   from t_profile_archive
   where generation = @generations_done 
   order by score desc

   if ((select count(*) from #saved_profiles) = 0)
   begin
     select 'all profiles failed in generation:' + 
         cast(@generations_done as varchar)
     return
   end
/*
saved profiles are the parents - we'll delete them after we
use them to breed.  Now delete all those that aren't parents
*/
   delete from t_profile_column_values
   where id not in ( select id from #saved_profiles) 

   select @breed_step = 1
   select @bred_total = 0


   while exists( select * from #saved_profiles)
      begin
         select top 1 @parent1 = id
         from #saved_profiles
         select top 1 @parent2 = id 
         from #saved_profiles
         where id != @parent1
        
         if @parent2 is not null and @parent1 is not null
         begin
               select @number_to_breed = 
                   ((@profile_count-@bred_total)
                    *@population_fill_proportion) + 1
               if @number_to_breed < 0
                  select @number_to_breed = 1
               select @bred_total = @bred_total + @number_to_breed
               exec up_breed_children 
                  @number_to_breed,@parent1, @parent2,
                  @mutation_add_column_probability,
                  @mutation_probability, @equality_percent
         end

         delete from #saved_profiles 
         where id = @parent1 or id = @parent2

  	      delete from t_profile_column_values
         where id = @parent1 or id = @parent2

         select @breed_step = @breed_step + 1
      end

    select ' Number Bred in generation: ' + cast(@generations_done as varchar)
       + ' was: ' + cast(@bred_total as varchar)

    drop table #saved_profiles
end

select * from t_timings

end
go


