#lang racket


;;CARGAMOS LA RED
(require "Bicondicional.rkt")
;la línea siguiente será diferente según sea el nombre de la Red
(define RED bicondicional)
;;CARGAMOS LOS PARAMETROS DEL PROBLEMA
(require "parametros-bicondicional.rkt");ok
;;CARGAMOS LOS MODULOS
(require "AG-Poblacion_inicial.rkt")
(require "AG-fitness-orden-parametrizacion.rkt")

(require "AG-sel-progenitores.rkt");ok
(require "AG-emparejamiento.rkt");ok
(require "AG-cruceYmutacion.rkt");ok




;;;CICLO DEL AG
(define ciclo-ag
  (lambda (pob) ;individuo=(fitness (representación))
    (let* (;eliminamos (- length-pob (* length-pob %criadores))
           ; los que eliminamos son peores por fitness
           (num-pob-aparear 
            (round (* length-poblacion %pot-repr)));%pot-repr=2/3
           (pob-aparear (take pob num-pob-aparear))
           
           ;sólo un porcentaje de éstos se tiene en cuenta
           (num-mejores
            (round (* num-pob-aparear %mejores-repr)));%mejores-repr=3/4
           (num-mejores-par
            (if (even? num-mejores) num-mejores (sub1 num-mejores)));o add1
           (pob-mejores (take pob-aparear num-mejores-par))
           
           ;aplicamos el método de Goldberg de la ruleta sobre pob-mejores
           (pob-pot-padres (metodo-goldberg-ruleta pob-mejores))
           ;habrá repetidos y eliminados respecto a pob-aparear
           
           ;hacemos parejas
           (parejas (empareja-dos-azar pob-pot-padres))
           
           ;las parejas tienen hijos
           (nueva-gen (genera-hijos parejas))
           ;habrá tantos hijos como (length pob-mejores) = num-mejores-par
           ;para una poblacion de 100, 50 hijos
           ;se calcula el fitness de los hijos
           (fit-nueva-gen (aplicar-fitness RED nueva-gen))
           
           ;temporalmente la poblacion = nueva-gen + pob-aparear 
           (temp-pob (append fit-nueva-gen pob-aparear))
           ;se ordena según el fitness
           (temp-pob+orden (orden-pob-fitness temp-pob))
           
           )
      (take temp-pob+orden length-poblacion) ) ))

(define ag
  (lambda (iteraciones . p)
    (let ((poblacion-inicial
            (gen-poblacion length-poblacion length-cromosoma haz-gen!));ok
           )
      (if (null? p)
          #t
          (set! poblacion-inicial (cons (car p) (cdr poblacion-inicial)))
          )
      (let* ((pob-ini+fitness (aplicar-fitness RED poblacion-inicial));ok
             (pobl+orden (orden-pob-fitness pob-ini+fitness));ok
             )
        (let go ((i 1)
                 (j iteraciones)
                 (poblacion pobl+orden)
                 )
          (cond
            ((= i j);<= alcanza final iteraciones sin solución
             (cons #f (car poblacion))
             )
            ((criterio-parada poblacion);<= logra una solución;criterio-parada = hay-un-optimo?
             (printf "~nIteración-~a~n" i)
             (cons #t (extrae-optimos poblacion))
             )
            (else;hace un ciclo de ag
             (when (= (remainder i 100) 0) (printf "Iteración-~a Mejor_error_medio: ~a~n" i (exact->inexact (caar poblacion))))
             (go (add1 i) j (ciclo-ag poblacion)) ;(poblacion-fitness poblacion))
             )
            )
          )
        )
      )
    ))


(printf "Porcentaje población para cruzar: ~a~n" %pot-repr)
(printf "Porcentaje de los mejores en población para cruzar: ~a~n" %mejores-repr)
(printf "Punto de cruce: ~a~n" punto-de-cruce)
(printf "Probabilidad mutación: ~a~n" prob-mutacion)
(printf "Tamaño población: ~a~n" length-poblacion)
(printf "Tamaño individuo: ~a~n" length-cromosoma)
(printf "Solución: ~a~n~n" solucion)

(define cromosoma
  (let go ((i 1)
           (j 10)
           (cromosoma (ag 100000))
           )
    (if (= i j)
        cromosoma
        (if (car cromosoma)
            (last cromosoma)
            (go (add1 i) j (ag 100000 (last cromosoma)))
            )
        )
    )
  )

(set-parametros RED cromosoma)

(require "Training_set-bicondicional.rkt")
(estimulos->red RED training)

(define q (send RED get-capas))
(send (second q) get-pesos)
(send (third q) get-pesos)
(map
 (lambda (n)
   (send n get-umbral))
 (send (second q) get-neuronas))
(map
 (lambda (n)
   (send n get-umbral))
 (send (third q) get-neuronas))