Puede alguien demostrar para mí un algoritmo de producto cartesiano más eficiente que el que estoy usando actualmente (suponiendo que hay uno). Miré alrededor de SO y busqué en Google un poco, pero no puedo ver nada obvio, así que podría perderme algo.eficiente algoritmo de producto cartesiano
foreach (int i in is) {
foreach (int j in js) {
//Pair i and j
}
}
Esta es una versión muy simplificada de lo que hago en mi código. Los dos números enteros son las operaciones de búsqueda teclas que se utilizan para recuperar una/varias objetos y todos los objetos de las dos búsquedas se emparejen en nuevos objetos.
Este pequeño bloque de código en un sistema más complejo mucho más grande se convierte en un importante cuello de botella como el conjunto de datos se está operando en escalas. Algo de esto probablemente podría mitigarse mediante la mejora de las estructuras de datos utilizadas para almacenar los objetos y las operaciones de búsqueda involucrados, pero el principal problema que siento es todavía el cálculo del propio producto cartesiano.
Editar
Así algunos antecedentes más en mi uso específico del algoritmo para ver si puede haber algún truco que puedo usar en respuesta al comentario de Marc. El sistema global es un motor de consulta SPARQL que procesa consultas SPARQL sobre conjuntos de datos gráfica, SPARQL es un lenguaje basado patrón de modo que cada consulta consta de una serie de patrones que se compara con el gráfico (s). En el caso en que dos patrones subsiguientes no tengan variables comunes (son disjuntos), es necesario calcular el producto cartesiano de las soluciones producidas por los dos patrones para obtener el conjunto de soluciones posibles para la consulta general. Puede haber cualquier número de patrones y voy a tener que calcular cartesianas productos varias veces lo que puede conducir a una expansión bastante exponencial de las posibles soluciones si la consulta se compone de una serie de patrones disjuntos.
alguna manera de las respuestas existentes Dudo que haya ningún tipo de trucos que se podría aplicar
actualización
así que pensé que iba a publicar una actualización sobre lo que he implementado con el fin de reducir al mínimo la necesidad de hacer cartesiana productos y así optimizar el motor de consultas en general. Tenga en cuenta que no siempre es posible eliminar por completo la necesidad de productos, pero casi siempre es posible optimizarlo, por lo que el tamaño de los dos conjuntos que se unen es mucho menor.
Puesto que cada BGP (Patrón Gráfico básico), que es un conjunto de patrones triple es ejecutado como un bloque (en esencia) el motor es libre de cambiar el orden de patrones dentro de un BGP para un rendimiento óptimo. Por ejemplo, considere la siguiente BGP:
?a :someProperty ?b .
?c :anotherProperty ?d .
?b a :Class .
Ejecutado como es la consulta requiere un producto cartesiano ya que los resultados del primer patrón son disjunta de la segunda patrón de lo que los resultados de los dos primeros patrones es un producto cartesiano de su resultados individuales Este resultado contendrá muchos más resultados de los que realmente necesitamos, ya que el tercer patrón restringe los posibles resultados del primer patrón, pero no aplicamos esta restricción hasta después. Pero si reordenamos así:
?b a :Class .
?a :someProperty ?b .
?c :anotherProperty ?d .
Todavía necesitará un producto cartesiano para obtener los resultados finales, ya que la 2ª y 3ª patrones son todavía desunido pero reordenando se restringe el tamaño de los resultados del segundo patrón lo que significa que el tamaño de nuestro producto cartesiano será mucho más pequeño.
Existen algunas otras optimizaciones que hacemos, pero no las voy a publicar aquí ya que comienzan a entrar en una discusión bastante detallada de las partes internas del motor SPARQL. Si alguien está interesado en más detalles, simplemente dejar un comentario o enviarme un tweet @RobVesse
http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx – tugberk