El producto cartesiano permite generar combinaciones ordenadas entre conjuntos. Esta idea aparece en variantes de productos, pruebas de software, bases de datos, grafos, relaciones y configuraciones.
El producto cartesiano no es solo una construcción teórica. En informática aparece cada vez que necesitamos combinar opciones de distintos conjuntos y considerar todas las posibilidades ordenadas.
En este tema veremos aplicaciones concretas: variantes de productos, generación de casos de prueba, relaciones entre entidades, coordenadas, grafos y combinaciones de configuración.
El producto cartesiano de A y B contiene todos los pares ordenados cuyo primer componente pertenece a A y cuyo segundo componente pertenece a B.
Si A tiene 3 elementos y B tiene 2, entonces A × B tiene 6 pares.
Una aplicación directa del producto cartesiano es generar variantes a partir de opciones. Por ejemplo, talles y colores.
Cada par representa una variante posible de un producto.
Podemos generar todas las variantes con una función de producto cartesiano.
function productoCartesiano(a, b) {
return a.flatMap(elementoA =>
b.map(elementoB => [elementoA, elementoB])
);
}
const talles = ["S", "M", "L"];
const colores = ["negro", "blanco"];
console.log(productoCartesiano(talles, colores));
El resultado contiene todas las combinaciones de talle y color.
En pruebas de software, el producto cartesiano permite generar combinaciones de parámetros.
Este producto genera escenarios como (Chrome, Windows), (Chrome, Linux) o (Firefox, macOS).
function productoCartesiano(a, b) {
return a.flatMap(elementoA =>
b.map(elementoB => [elementoA, elementoB])
);
}
const navegadores = ["Chrome", "Firefox"];
const sistemas = ["Windows", "Linux", "macOS"];
const casos = productoCartesiano(navegadores, sistemas);
casos.forEach(([navegador, sistema]) => {
console.log(`Probar en ${navegador} sobre ${sistema}`);
});
Cada par representa un caso de prueba distinto.
En bases de datos, un producto cartesiano puede representar todas las combinaciones posibles entre registros de dos tablas. Esto puede ser útil, pero también peligroso si se hace sin condiciones.
Si hay 100 clientes y 50 productos, el producto cartesiano tiene 5.000 pares. Por eso, en consultas reales se suelen agregar condiciones para obtener relaciones relevantes.
Una relación entre dos conjuntos puede verse como un subconjunto del producto cartesiano.
No todos los pares posibles tienen que formar parte de la relación. La relación selecciona solo los pares válidos.
function productoCartesiano(a, b) {
return a.flatMap(elementoA =>
b.map(elementoB => [elementoA, elementoB])
);
}
const usuarios = ["Ana", "Luis"];
const permisos = ["leer", "editar", "publicar"];
const paresPosibles = productoCartesiano(usuarios, permisos);
const permisosAsignados = [
["Ana", "leer"],
["Ana", "editar"],
["Luis", "leer"]
];
console.log(paresPosibles);
console.log(permisosAsignados);
Los pares posibles forman el producto cartesiano. Los permisos asignados forman una relación particular dentro de ese producto.
En un grafo dirigido, una arista puede representarse como un par ordenado (origen, destino). Si tenemos un conjunto de nodos, el producto cartesiano de nodos por nodos representa todas las aristas dirigidas posibles.
Luego, el grafo real se define como un subconjunto de esas aristas posibles.
Una grilla rectangular puede verse como el producto cartesiano entre filas y columnas.
Cada par ordenado identifica una celda.
function productoCartesiano(a, b) {
return a.flatMap(elementoA =>
b.map(elementoB => [elementoA, elementoB])
);
}
const filas = [1, 2, 3];
const columnas = ["A", "B", "C"];
const celdas = productoCartesiano(filas, columnas);
console.log(celdas);
El resultado contiene las posiciones [1, "A"], [1, "B"], [1, "C"] y así sucesivamente.
Algunas aplicaciones necesitan combinar más de dos dimensiones. Por ejemplo: talle, color y material.
El resultado está formado por ternas ordenadas.
function productoMultiple(...conjuntos) {
return conjuntos.reduce(
(resultado, conjunto) =>
resultado.flatMap(parcial =>
conjunto.map(elemento => [...parcial, elemento])
),
[[]]
);
}
const talles = ["S", "M", "L"];
const colores = ["negro", "blanco"];
const materiales = ["algodón", "poliéster"];
const variantesCompletas = productoMultiple(talles, colores, materiales);
console.log(variantesCompletas);
La cantidad de combinaciones crece multiplicando las cardinalidades de los conjuntos.
| Conjuntos | Cardinalidades | Combinaciones |
|---|---|---|
| Talles × colores | 3 × 2 | 6 |
| Navegadores × sistemas × idiomas | 3 × 4 × 2 | 24 |
| 5 opciones con 4 valores cada una | 4 × 4 × 4 × 4 × 4 | 1.024 |
En programación, esta multiplicación puede generar muchos casos rápidamente.
| Aplicación | Producto cartesiano | Resultado |
|---|---|---|
| Productos | Talles × colores | Variantes |
| Testing | Navegadores × sistemas | Casos de prueba |
| Permisos | Usuarios × permisos | Pares posibles de asignación |
| Grafos | Nodos × nodos | Aristas dirigidas posibles |
| Grillas | Filas × columnas | Celdas |
El producto cartesiano es una herramienta para construir posibilidades ordenadas. Su valor práctico aparece en muchas áreas de programación: desde variantes de productos hasta relaciones, grafos y pruebas automatizadas.
En el próximo tema estudiaremos el concepto de relación.