Digamos que tenemos una matriz de 5x5, llena de ceros.
myMatrix <- matrix(rep(0, 25), ncol = 5)
Ahora, escojamos un triplete de enteros entre 1 y 5.
triplet <- c(1,2,3)
Para todas las combinaciones de este triplete ahora agregamos 1 en la matriz, con esta función:
addCombinationsToMatrix <- function(.matrix, .triplet){
indexesToChange <- as.matrix(expand.grid(.triplet, .triplet))
.matrix[indexesToChange] <- .matrix[indexesToChange] + 1
.matrix
}
Usando la función, pasamos de
myMatrix
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
a
myMatrix <- addCombinationsToMatrix(myMatrix, triplet)
myMatrix
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 0 0
[2,] 1 1 1 0 0
[3,] 1 1 1 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
Si elegimos otro triplete, pasamos a
nextTriplet <- 2:4
myMatrix <- addCombinationsToMatrix(myMatrix, nextTriplet)
myMatrix
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 0 0
[2,] 1 2 2 1 0
[3,] 1 2 2 1 0
[4,] 0 1 1 1 0
[5,] 0 0 0 0 0
Entonces, las combinaciones fila-columna representan la frecuencia con la que dos enteros se han mostrado juntos en un triplete: 3 y 4 se han mostrado juntos una vez, 2 y 3 se han mostrado juntos dos veces.
Pregunta : ¿Cómo se pueden elegir trillizos, de modo que cada combinación (1-2, 1-3, 1-4 ...) se recoja al menos una vez y se minimice el número de trillizos.
Estoy buscando un algoritmo aquí que elija el próximo triplete.
Idealmente se puede extender a
- matrices arbitrariamente grandes (10x10, 100x100 ...)
- vectores arbitrariamente grandes (cuadruplets, quintillizos, n-tuplets)
- un número arbitrario de veces que una combinación debe haber sido elegida al menos
Ejemplo:
myMatrix
myMatrix <- addCombinationsToMatrix(myMatrix, 1:3)
myMatrix
myMatrix <- addCombinationsToMatrix(myMatrix, 3:5)
myMatrix
myMatrix <- addCombinationsToMatrix(myMatrix, c(1,4,5))
myMatrix
myMatrix <- addCombinationsToMatrix(myMatrix, c(2,4,5))
myMatrix
EDITAR : Solo para estar seguro: la respuesta no tiene que ser R
código. También puede ser algún otro idioma o incluso seudocódigo.
EDIT 2 : Se me ocurrió ahora, que hay diferentes formas de medir la eficiencia. En realidad quise decir que el algoritmo debería tomar la menor cantidad de iteraciones posible. El algoritmo que es rápido también es muy bueno, pero no es el objetivo principal aquí.
fuente
Aquí hay una opción que utiliza
data.table
para realizar un seguimiento del recuento de matrices yRcppAlgos
generar las combinaciones:Es un algoritmo codicioso, por lo tanto, no estoy seguro de si esto resultará en un número mínimo de tuplas.
fuente
Error in eval(onsub, parent.frame(2L), parent.frame(2L)) : object '.NATURAL' not found
Dado que esta pregunta solicita enfoques algorítmicos para cubrir diseños, proporcionaré uno que proporcione respuestas exactas (también conocido como el mejor diseño posible) utilizando la programación de enteros en R. Por cada k-tupla que esté considerando (k = 3 para usted, ya que está seleccionando trillizos), defina una variable de decisión que tome el valor 1 si lo incluye en su diseño y 0 si no. Entonces, en su caso, definiría x_123 para indicar si la tupla (1,2,3) está seleccionada, x_345 para (3,4,5), y así sucesivamente.
El objetivo del modelo de optimización es minimizar el número de tuplas seleccionadas, es decir, la suma de todas sus variables de decisión. Sin embargo, para cada t-tupla (t = 2 en su caso), debe incluir una variable de decisión que contenga esa t-tupla. Esto produce una restricción para cada t-tupla. Como ejemplo, tendríamos
x_123+x_124+x_125 >= 1
la restricción que requiere que el par12
esté en alguna tupla seleccionada.Esto produce el siguiente modelo de optimización:
Puede extender esto para requerir r repeticiones de cada t-tupla cambiando el lado derecho de cada desigualdad a "r" y requiriendo que todas las variables sean enteras en lugar de binarias.
Esto es fácil de resolver con un paquete como
lpSolve
en R:Si bien esto resuelve su problema exactamente, no escalará bien a problemas de gran tamaño. Esto se debe a que el problema es NP-hard: ningún algoritmo exacto conocido se escalará bien. Si necesita resolver grandes instancias de problemas, entonces la heurística recomendada en otras respuestas aquí es su mejor opción. O podría resolver con programación entera (como lo hacemos aquí) y establecer un tiempo de espera; entonces trabajará con la mejor solución encontrada por su tiempo de espera, que es una solución heurística al problema en general.
fuente