unit uexplorador;

{$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;
type
  // Los Exploradores son capaces de proponer un nuevo punto de evaluación en base
  // a su historia y a la historia colectiva.

  { TExplorador }

  TExplorador = class
    problema: TProblema;
    dbcon: TDBrosxCon;
    cnt_evals: integer;
    f_VE_Last: NReal;

    constructor Create(dbconx: TDBrosxCon; Problema: TProblema);

    // El explorador debe proponer un nuevo individuo dejando calculadas
    // las dos representaciones del individuo. Es decir los Genotipos y
    // la cadena de ADN.
    // Si el explorador actua directamente sobre el ADN (exploradores genéticos)
    // deben llamar a la función decodificar_ADN del problema para completar la
    // información de los Genotipos antes de retornar el individuo.
    // Si el explorador actua directamente sobre los Genotipos (exploradores de gradiente por ejemplo)
    // deben llamar a la función codificar_ADN del proeblema para completar la información
    // de la cadena de ADN antes de retornar el individuo.
    function ProponerNuevoIndividuo: TIndividuo; virtual; abstract;
    procedure DarPaso; virtual;
    // propone un nuevo individuo, lo evalúa y comunica resultados

    function rnd_Individuo: TIndividuo;
  end;




implementation


(********** Métodos de TExplorador *********************)
constructor TExplorador.Create(dbconx: TDBrosxCon; Problema: TProblema);
begin
  inherited Create;
  self.problema := Problema;
  dbcon := dbconx;
  cnt_evals:= 0;
  f_VE_Last:= -11111;
end;



procedure TExplorador.DarPaso;
var
  a: TIndividuo;
  adn_hexstr: string;
  r: TDataRecord;
  numero_de_evaluacion: integer;
  semilla_aleatoria: integer;
begin
  a := ProponerNuevoIndividuo;
  if a <> nil then
  begin

    if dbcon.tipoServidor = CTS_MySQL then
      adn_hexstr := BuffToHexStr_(a.adn[0], problema.nbytes_ADN)
    else
      adn_hexstr := PG_BuffToHexStr(a.adn[0], problema.nbytes_ADN);

    r := dbcon.sql_ficha('SELECT nid, cnt_evaluaciones FROM ' +
      problema.db_table + ' WHERE adn = ''' + adn_hexStr + ''' LIMIT 1');

    if r <> nil then
    begin
      a.nid := r.GetByNameAsInt('nid');
      numero_de_evaluacion := r.GetByNameAsInt('cnt_evaluaciones') + 1;
      r.Free;
    end
    else
    begin
      a.nid := -1;
      numero_de_evaluacion := 1;
    end;

    semilla_aleatoria := 30 + numero_de_evaluacion;

    if problema.evaluar_(a, semilla_aleatoria) then
    begin
      a.ComunicarResultado(numero_de_evaluacion);
      self.f_VE_Last:= a.f_objetivo;
      inc( self.cnt_evals );
    end;
    a.Free;
  end;
end;

function TExplorador.rnd_Individuo: TIndividuo;
var
  res: TIndividuo;
begin
  res := TIndividuo.CreateNew(dbcon, Problema);
  problema.random_adn(res);
  Result := res;
end;


end.

