Minimum Set Cover es una pregunta en la que debe encontrar el número mínimo de conjuntos necesarios para cubrir cada elemento.
Por ejemplo, imaginemos que tenemos un conjunto de X=array(1,2,3,4,5,6)
y 5 otra serie S, dondeCubierta del conjunto mínimo [PHP]
S[1]=array(1, 4)
S[2] =array(2, 5)
S[3] =array(3, 6)
S[4] =array(1, 2, 3)
S[5] =array(4, 5, 6)
El problema es encontrar el número mínimo de conjuntos de S
que cubren todos los elementos de X.
Así que, obviamente, la cubierta conjunto mínimo en nuestro caso serán S [4] y S [5] porque cubren todos los elementos.
¿Alguien tiene una idea de cómo implementar este código en PHP? Tenga en cuenta que esto es NP-complete por lo que no hay un algoritmo rápido para resolverlo. Cualquier solución en PHP será bienvenida. Y por cierto, no es una tarea, necesito usar este algoritmo en mi aplicación web para generar una lista de sugerencias.
Gracias de antemano.
Actualización 1
Hay muchas aplicaciones de conjunto que abarca problema. Algunos de los más interesantes son:
- Construcción de circuitos lógicos Optimal
- Programación Aire tripulación
- Planta de fabricación de equilibrio
- Recuperación de la información
- galería de arte problema
- de Secuenciación del Genoma
- Problema SetCover rojo-azul
Actualización 2
Por ejemplo, here se puede ver la versión de trabajo del problema que he mencionado. Aquí, incluso muestra visualmente los conjuntos. Pero necesito el código PHP puro para eso, si alguien lo tiene, por favor tenga la amabilidad de proporcionarnos el ejemplo de trabajo en PHP. Gracias
Actualización 3
Por último, he resuelto el problema en PHP. Mi solución basada en el algoritmo propuesto en un libro muy famoso llamado Introduction to Algorithms, sección El problema set-covering. Aquí cómo mi solución parece:
$MainSet=array(1, 2, 3, 4, 5, 6, 7);
$SubSet=array(array(1,4), array(2, 5), array(3, 6), array(1, 2, 3), array(4, 5, 6));
$UncoveredElements=$MainSet;
$CoveringSets=array();
while (count($UncoveredElements)>0){
$S=SubSetS($UncoveredElements, $SubSet);
if (is_array($S)){
$UncoveredElements=array_diff($UncoveredElements, $S);
$CoveringSets[]=$S;
}else
break; //finish work
}
echo "Sets that cover MainSet are:";
var_dump($CoveringSets);
//Subset S is chosen that covers as many uncovered elements as possible
function SubSetS($UncoveredElements, $SubSetArr){
$max=0; $s=array();
foreach($SubSetArr as $SubSet){
$intersectArr=array_intersect($UncoveredElements, $SubSet);
$weight=count($intersectArr);
if ($weight>$max){
$max=$weight;
$s=$SubSet;
}
}
if ($max>0)
return $s;
else
return 0;
}
Cualquier comentario e ideas acerca de mi solución? Para mí, soluciona mi problema, eso es lo que quería. Pero si sugiere alguna optimización, corrección al código, rellene gratis.
Por cierto, muchas gracias a los participantes de la pregunta por sus valiosas respuestas.
Informe final de actualización
Este enfoque codicioso para un conjunto que abarca problema no siempre garantiza una solución óptima. Considere el siguiente ejemplo:
Dado: Elementos del conjunto principal = {1, 2, 3, 4, 5, 6}
Ahora, considere 4 subconjuntos de la siguiente manera: Subconjunto 1 = {1, 2}, Subconjunto 2 = { 3, 4}, Subconjunto 3 = {5, 6}, Subconjunto 4 = {1, 3, 5}.
El algoritmo codicioso para la recogida por encima de subconjuntos da Set cobertura mínima como: Set cobertura mínima contiene los subconjuntos = {1, 2, 3, 4}.
Por lo tanto, aunque el mínimo de recogida de subconjuntos que cubren todos los elementos del conjunto principal son los primeros tres subconjuntos, obtenemos la solución que contiene todos los 4 subconjuntos.
Puede encontrar cada cubierta de conjunto posible y luego verificar cuál es la mínima ... – Himadri
¿Alguien tiene un código de trabajo real en PHP para este problema? O nadie se ha enfrentado con este problema antes? – Bakhtiyor
@Bakhtiyor: lo tengo, pero está en casa, así que no puedo publicarlo ahora (desde el trabajo) - publicaré mi solución cuando esté en casa en 6-7 horas (18:00 UTC + 1) – oezi