eneReinas <- function ()
  {
    ## parámetros
    nRei <- 8                           # número de reinas
    nIte <- 5000                        # número máximo de iteraciones
    nPob <- 100                         # tamaño de la población
    nCan <- 5                           # candidatos a reproductores
    pMut <- 1                           # probabilidad de mutación

    ## contenedores
    media <- minimo <- maximo <- c()

    ## prepara población y la evalúa
    poblacion <- t (replicate (nPob, sample (nRei)))
    adapPobla <- apply (poblacion, 1, calculaAdaptacion)

    ## bucle principal
    for (iter in 1:nIte)
      {
        ## reproductores
        iCandidatos <- sample (nPob, nCan)
        indice      <- order (adapPobla[iCandidatos])
        iPadres     <- iCandidatos[indice[1:2]]
        padres      <- poblacion[iPadres,]

        ## sobrecruce
        pos   <- sample (nRei-1,1)
        hijo1 <- padres[1,1:pos]
        hijo1 <- c (hijo1, setdiff (c (padres[2,(pos+1):nRei], padres[2,1:pos]),
                                    hijo1))
        hijo2 <- padres[2,1:pos]
        hijo2 <- c (hijo2, setdiff (c (padres[1,(pos+1):nRei], padres[1,1:pos]),
                                    hijo2))
        ## mutación
        if (rbinom (1, 1, pMut))
          {
            pos        <- sample (nRei, 2)
            hijo1[pos] <- hijo1[rev(pos)]
          }
        if (rbinom (1, 1, pMut))
          {
            pos        <- sample (nRei, 2)
            hijo2[pos] <- hijo2[rev(pos)]
          }

        ## evaluación
        adapHijos <- c (calculaAdaptacion (hijo1),
                        calculaAdaptacion (hijo2))

        ## selección
        indice    <- order (adapPobla)
        poblacion <- rbind (poblacion[indice[1:(nPob-2)],],
                            hijo1, hijo2)
        adapPobla <- c (adapPobla[indice[1:(nPob-2)]], adapHijos)

        ## eco
        cat (iter, ": media=", mean (adapPobla),
             " min=",          min  (adapPobla),
             " max=",          max  (adapPobla), "\n")

        ## dibujos
        media  <- c (media,  mean (adapPobla))
        minimo <- c (minimo, min  (adapPobla))
        maximo <- c (maximo, max  (adapPobla))
        minmin <- min (minimo, maximo)
        maxmax <- max (minimo, maximo)
        plot  (media,  col = 2, type = "l", ylim = c (minmin, maxmax))
        lines (minimo, col = 3)
        lines (maximo, col = 4)

        ## criterio de parada
        if (min (adapPobla) == 0L)
          {
            solucion <- poblacion[which.min(adapPobla),]
            tablero  <- matrix (0, nRei, nRei)
            tablero[cbind(1:nRei,solucion)] <- 1
            print (tablero)
            return (iter)
          }
      }
  }

calculaAdaptacion <- function (disposicion)
  {
    nRei <- length (disposicion)
    adaptacion <- 0
    for (i in 1:(nRei-1))
      for (j in (i+1):nRei)
        adaptacion <- adaptacion +
                      ((j - i) == abs (disposicion[i] - disposicion[j]))
    adaptacion
  }