#lang scheme

(require (only-in "parametros-nuevo-bidones.ss" prob-mutacion length-cromosoma punto-de-cruce muta-gen))
;(require (only-in "parametros-tsp.ss" prob-mutacion length-cromosoma punto-de-cruce muta-gen))

;;MODULO CRUCE
;;;CREAR NUEVA GENERACIÓN
(define cruce
  (lambda (c1 c2 punto-c)
    (append
     (take c1 punto-c)
     (drop c2 punto-c)) ))
;;mutaciones
(define mutacion
  (lambda (dividendo divisor)
    (let ((%mutacion (/ dividendo divisor))
          (mutar? (< (random divisor) dividendo))
          )
      mutar?
    )))

(define mutando-gen;fuerza a que el gen cambie
  (lambda (gen)
    (let ((gen-mutante (muta-gen)))
      (if (equal? gen gen-mutante)
          (mutando-gen gen)
          gen-mutante) )))

(define list-set!
  (lambda (lista n-ord val)
    (let go ((i 0)
             (j (length lista))
             )
      (if (= i j)
          '()
          (cons
           (if (= i n-ord)
               val
               (list-ref lista i))
           (go (add1 i) j)) )
      )))
;;Los padres producen hijos
;;incluye mutación
(define genera-hijos
  (lambda (padres);un padre = (fitness (representación))
    (if (null? padres)
        '()
        (let* ((prob-mut prob-mutacion)
               (mutacion ;<== v/f hay mutación
                (mutacion (car prob-mut) (cdr prob-mut)))
               (n1-gen (random length-cromosoma));número de gen a mutar en hijo1
               (n2-gen (random length-cromosoma));número de gen a mutar en hijo2
               (pareja-padres (car padres))
               (prog1 (car pareja-padres))
               (prog2 (cadr pareja-padres))
               (pcruce (if punto-de-cruce punto-de-cruce (random length-cromosoma)))
               (hijo1 (if (= pcruce 0) prog1 (cruce prog1 prog2 pcruce)))
               (hijo2 (if (= pcruce 0) prog2 (cruce prog2 prog1 pcruce)))
;               (hijo1 (cruce prog1 prog2 punto-de-cruce))
;               (hijo2 (cruce prog2 prog1 punto-de-cruce))
              )
          (when (and mutacion (> pcruce 0));se muta un gen
;            (printf "Mutando 1 gen~n")
            (set! hijo1
                  (list-set! 
                   hijo1 n1-gen 
                   (mutando-gen (list-ref hijo1 n1-gen))))
            (set! hijo2
                  (list-set! 
                   hijo2 n2-gen 
                   (mutando-gen (list-ref hijo2 n2-gen)))))
          (append
           (list hijo1 hijo2)
           (genera-hijos (cdr padres)))
          )) ))

(provide
 genera-hijos
 )