#lang racket


;;El módulo o programa principal
;;CARGAMOS LOS PARAMETROS DEL PROBLEMA
(require "parametros-nuevo-bidones.rkt");ok
;(require "parametros-tsp.rkt");ok
;;CARGAMOS LOS MODULOS
(require "AG-poblacion-ini.rkt");ok
(require "AG-apply-fitness-orden.rkt");ok
(require "AG-sel-progenitores.rkt");ok
(require "AG-emparejamiento.rkt");ok
(require "AG-cruceYmutacion.rkt");ok
;;CARGAMOS LOS MODULOS auxiliares
(require "AG-auxiliares.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 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)
    (let* ((poblacion-inicial
            (gen-poblacion length-poblacion length-cromosoma haz-gen!))
           (pob-ini+fitness (aplicar-fitness poblacion-inicial))
           (pobl+orden (orden-pob-fitness pob-ini+fitness));redundante?
           
           )
      (let go ((i 0)
               (j iteraciones)
               (poblacion pobl+orden)
               (pob+fit (poblacion-fitness pobl+orden))
               )
        (cond
          ((= i j);<= alcanza final iteraciones sin solución
           (printf "~a Iteración-~a Poblacion fitness: ~a~n" 
                   (make-string 10 #\space) i (poblacion-fitness poblacion))
           (print-poblacion poblacion)
           #f
           )
          ((criterio-parada poblacion);<= logra una solución
           (printf "~a Iteración-~a Poblacion fitness: ~a~n" 
                   (make-string 10 #\space) i (poblacion-fitness poblacion))
           (print-poblacion poblacion)
           #t
           )
          (else;hace un ciclo de ag
               (when (= (remainder i 100) 0)
                 (printf "~a Iteración-~a Poblacion fitness: ~a~n" 
                       (make-string 10 #\space) i pob+fit))
           (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" solucion)
(printf "~nBucle-~a con 20000 iteraciones como máximo~n" 1)
(let go ((i 2)
         (j 3)
         (ag-result (ag 20000))
         )
  (if ag-result;(= i j)
      'hecho
      (begin
        (printf 
         "Bucle-~a con 20000 iteraciones como máximo~n" i)
        (printf 
         "Genera nueva población inicial~n~n")
        (collect-garbage)
        (go (add1 i) j (ag 20000)) )))

