unit uexplorador_mj;

{$mode delphi}

interface

uses
  Classes, SysUtils,
  Math,
  ufechas,
  u_updownload,
  utipos_ga,
  fddp_conmatr,
  fddp,
  {$IFDEF USE_DB_CON}
  lib_dbmysql,
  {$ELSE}
  uDataSetGenerico,
  urosx,
  {$ENDIF}
  {$IFDEF data_NO_}
  udbconpg,
  {$ENDIF}
  uoddface,
  matent, matreal, xmatdefs, uexplorador;

type
  TExploradorMejorador = class(TExplorador)
  public
    constructor Create(dbconx: TDBrosxCon; Problema: TProblema; ProbPremioExito_: NReal);
    function ProponerNuevoIndividuo: TIndividuo; override;

  private
    ProbPremioExito: NReal;

    // selecciona un progenitor, aplicando la ProbPremioExito
    // para premiar entre el más exitoso o el resto y así
    // sucesivamente dentro de cada resto. El parámetro kMax
    // especifica las posición en la lista ordenada por orden decreciente
    // de mérito del último individuo que se considera candidato.
    // El valor kMax tiene que ser < que la cantidad total de indiviudos
    // en el historial global para que esté asegurado que el resultado
    // es un individuo.
    function SeleccionarProgenitor(kMax: integer): TIndividuo;
  end;


implementation



(**** Métodos de TExploradorMejorador  ****************)


constructor TExploradorMejorador.Create(dbconx: TDBrosxCon; Problema: TProblema;
  ProbPremioExito_: NReal);
begin
  inherited Create(dbconx, problema);
  self.ProbPremioExito := ProbPremioExito_;
end;

function TExploradorMejorador.ProponerNuevoIndividuo: TIndividuo;
var
  ai: TIndividuo;
  nPoblacion: integer;
begin
  ai := Problema.SeleccionarIndividuo_PorCalcular;
  if ai <> nil then
     problema.decodificar_adn(ai)
  else
  begin
    nPoblacion := Problema.CantidadDeIndividuos;
    if nPoblacion >= 1 then
    begin
      ai := Problema.SeleccionarIndividuo_PorCalcular;
      if ai = nil then
        ai := seleccionarProgenitor(nPoblacion - 1);
      problema.decodificar_adn(ai);
    end
    else
      ai := nil;
  end;
  Result := ai;
end;




function TExploradorMejorador.SeleccionarProgenitor(kMax: integer): TIndividuo;
var
  k: integer;
  lst: TIndividuos;
begin
  k := 0;
  while ( fuente.rnd > self.ProbPremioExito) and (k < kMax) do
    Inc(k);
  lst := problema.SeleccionarMejores(1, k);
  Result := lst.items[0];
  lst.Free;
end;



end.

