Una función es biyectiva si es inyectiva y sobreyectiva al mismo tiempo. Establece un emparejamiento perfecto uno a uno entre el dominio y el codominio, permitiendo transformaciones completamente reversibles.
Hemos estudiado dos propiedades fundamentales de las funciones: la **inyectividad** (que garantiza que entradas diferentes vayan a salidas diferentes) y la **sobreyectividad** (que garantiza que todo el codominio sea alcanzado por la función).
Cuando una función cumple con **ambas propiedades simultáneamente**, se denomina **función biyectiva** o *biyección*. Las biyecciones son el tipo de relación más restrictivo y limpio, ya que emparejan de forma perfecta cada elemento de partida con un único elemento de llegada, sin que sobre ni falte nada.
Formalmente, una función f : A → B es biyectiva si cumple las siguientes dos condiciones:
Bajo una función biyectiva, cada elemento de A tiene exactamente una imagen en B, y cada elemento de B tiene exactamente una preimagen en A. Esta correspondencia mutua se conoce como **correspondencia biunívoca**.
Para conjuntos finitos, la biyectividad impone una restricción matemática muy importante sobre el tamaño de los conjuntos:
Si existe una función biyectiva f : A → B, entonces **el dominio y el codominio deben tener exactamente el mismo número de elementos**:
Prueba el simulador para analizar cómo se acoplan las flechas en una biyección. Selecciona diferentes funciones y observa cómo el sistema colorea en verde los elementos que cumplen la regla de biyectividad (reciben exactamente una flecha) y en rojo/amarillo aquellos que violan la regla (reciben 0 o más de una flecha).
Para demostrar que una función es biyectiva, se deben presentar dos pruebas independientes: la de inyectividad y la de sobreyectividad.
Ejemplo: Demostrar que f(x) = 2x + 5 de f : ℝ → ℝ es biyectiva.
Para comprobar computacionalmente si una función sobre colecciones finitas es biyectiva, podemos verificar la inyectividad y la sobreyectividad juntas mediante código.
const dominio = [1, 2, 3, 4];
const codominio = [3, 4, 5, 6];
// Función f(x) = x + 2
const f = (x) => x + 2;
function esInyectiva(dom, func) {
const salidas = dom.map(func);
return new Set(salidas).size === dom.length;
}
function esSobreyectiva(dom, codom, func) {
const salidas = dom.map(func);
return codom.every(y => salidas.includes(y));
}
function esBiyectiva(dom, codom, func) {
// Una función es biyectiva si cumple ambas propiedades
return esInyectiva(dom, func) && esSobreyectiva(dom, codom, func);
}
console.log("¿f(x) es Inyectiva?", esInyectiva(dominio, f));
console.log("¿f(x) es Sobreyectiva?", esSobreyectiva(dominio, codominio, f));
console.log("¿f(x) es Biyectiva?", esBiyectiva(dominio, codominio, f));
// ¿f(x) es Inyectiva? true
// ¿f(x) es Sobreyectiva? true
// ¿f(x) es Biyectiva? true
La importancia principal de la biyectividad radica en que **las funciones biyectivas son reversibles**. Al existir un emparejamiento perfecto uno a uno en ambas direcciones, podemos deshacer la transformación de datos sin ninguna ambigüedad. Esta reversibilidad es el pilar conceptual necesario para estudiar las funciones inversas.
En el próximo tema estudiaremos las **funciones inversas**, analizando cómo construir la función que recorre el camino de regreso desde el codominio hacia el dominio, y cómo implementarla en programación.