Elegir entre un modelo discreto y uno continuo cambia la forma de representar datos, diseñar algoritmos y evaluar resultados. Esta distinción permite convertir fenómenos reales en información que una computadora puede procesar.
Antes de resolver un problema con software debemos decidir qué objetos vamos a representar. Esa decisión no es solo técnica: determina qué valores son válidos, qué operaciones tienen sentido y qué precisión puede alcanzar nuestro programa.
La distinción básica es entre objetos discretos, que se presentan como elementos separados, y objetos continuos, que pueden variar sin saltos dentro de un intervalo. La matemática discreta se concentra en los primeros, mientras que el cálculo y otras ramas de la matemática continua se especializan en los segundos.
Un objeto discreto pertenece a un conjunto cuyos elementos pueden diferenciarse individualmente. A menudo podemos contarlos o enumerarlos, al menos en principio. Los números naturales, los caracteres de un texto, los vértices de un grafo y los registros de una base de datos son ejemplos típicos.
Entre dos estados de una orden no existe un estado intermedio válido, y entre los índices 3 y 4 no hay otro índice entero. Esa separación es la característica que hace discreto al modelo.
Un objeto continuo puede tomar infinitos valores dentro de cualquier intervalo, por pequeño que sea. Los números reales son el modelo habitual: entre 2 y 3 están 2,5; 2,75; 2,999 y también infinitos valores más.
Magnitudes físicas como la distancia, el tiempo, la masa, la temperatura y la velocidad suelen comenzar con un modelo continuo. Por ejemplo, una persona puede recorrer 1,2 metros, 1,23 metros o 1,234567 metros, dependiendo de la precisión con que midamos.
| Característica | Discreto | Continuo |
|---|---|---|
| Valores | Separados e identificables | Sin saltos dentro de un intervalo |
| Ejemplo matemático | Números enteros | Números reales |
| Pregunta habitual | ¿Cuántos? ¿Cuál es el siguiente? | ¿Qué valor? ¿Cómo cambia? |
| Herramientas frecuentes | Conteo, grafos, lógica, recurrencias | Límites, derivadas, integrales |
| Ejemplo de software | Usuarios, archivos, estados, caracteres | Medición de un sensor o posición física |
Un problema puede tener aspectos de ambos tipos. Un videojuego tiene una cantidad discreta de objetos y eventos, pero puede modelar posiciones y velocidades mediante números que aproximan variables continuas.
Los números naturales 0, 1, 2, 3, ... son un ejemplo central de conjunto discreto. Se usan para contar elementos, numerar posiciones y definir repeticiones. Los enteros agregan valores negativos y permiten modelar diferencias, saldos o desplazamientos.
const productosEnCarrito = 3;
const cambioDeStock = -2;
console.log(`Productos en el carrito: ${productosEnCarrito}`);
console.log(`Cambio de stock: ${cambioDeStock}`);En ambos casos los valores representan cantidades que cambian por unidades. No tendría sentido tener 2,4 productos indivisibles en un carrito si el dominio del problema establece que cada producto se cuenta como una unidad.
Muchos objetos discretos forman conjuntos finitos: los días de la semana, las opciones de un menú o los bits de un byte. Otros conjuntos discretos son infinitos, como los números naturales, pero sus elementos pueden enumerarse ordenadamente.
| Conjunto | Tipo | Ejemplo de uso |
|---|---|---|
| {true, false} | Finito | Variable booleana |
| {0, 1, ..., 255} | Finito | Valor de un byte sin signo |
| N = {0, 1, 2, ...} | Infinito numerable | Índices teóricos de una secuencia |
| Conjunto de todas las cadenas finitas | Infinito numerable | Entradas posibles de un programa |
En una computadora real la memoria es limitada, por lo que toda estructura almacenada tiene tamaño finito. Sin embargo, los modelos infinitos son útiles para razonar sobre algoritmos para entradas de cualquier tamaño.
Una computadora no puede almacenar todos los números reales ni medir con precisión infinita. Para procesar una magnitud continua utiliza una representación finita: una cantidad determinada de bits, una unidad de medida y una regla de aproximación.
Por ejemplo, una interfaz puede guardar una posición en píxeles enteros, o en coordenadas con decimales. En ambos casos el conjunto de valores realmente representables es finito dentro de la memoria disponible.
La cuantización asigna cada valor de un rango continuo a uno de un conjunto finito de niveles. Es una operación indispensable en imágenes digitales, audio, sensores y controles de interfaz.
Si un sensor entrega una temperatura y la pantalla solo muestra números enteros, podemos redondear la medición. El resultado es discreto aunque la temperatura original se modele como continua.
function nivelDeTemperatura(temperatura) {
return Math.round(temperatura);
}
console.log(nivelDeTemperatura(22.37)); // 22
console.log(nivelDeTemperatura(22.68)); // 23Cuantizar simplifica el almacenamiento y el procesamiento, pero introduce un error de aproximación. La elección de la cantidad de niveles depende de cuánta precisión necesita la aplicación.
Una señal continua, como una onda sonora, se transforma en datos digitales tomando mediciones en instantes separados. Cada medición es una muestra y la colección de muestras es una secuencia discreta.
La frecuencia de muestreo determina cuántas mediciones se toman por segundo. Tomar pocas muestras puede perder detalles importantes; tomar demasiadas aumenta el espacio necesario y el trabajo de procesamiento.
Una fotografía de una escena real puede parecer continua, pero una imagen digital se almacena como una grilla de píxeles. Cada píxel tiene una posición discreta y un color representado con valores numéricos finitos.
const imagen = [
[0, 128, 255],
[64, 192, 32]
];
console.log(`Píxel de fila 1, columna 2: ${imagen[0][1]}`);
console.log(`Cantidad de filas: ${imagen.length}`);En este ejemplo cada número representa intensidad de gris entre 0 y 255. La escena puede variar de forma continua, pero el archivo contiene una cantidad finita de posiciones y niveles de color.
El tiempo físico suele modelarse como continuo. Sin embargo, los programas lo manejan mediante instantes discretos: milisegundos, fotogramas, turnos de un juego o eventos registrados por un servidor.
Una simulación puede actualizarse 60 veces por segundo. Entre dos actualizaciones, el programa no evalúa todos los instantes posibles; calcula un nuevo estado a partir del estado anterior y de un intervalo de tiempo elegido.
function actualizarPosicion(posicion, velocidad, segundos) {
return posicion + velocidad * segundos;
}
const siguientePosicion = actualizarPosicion(10, 3, 1 / 60);
console.log(siguientePosicion); // 10.05El valor calcula una aproximación de la posición después de un fotograma. Cuanto menor sea el intervalo, mejor puede aproximarse un cambio continuo, aunque el costo computacional también aumenta.
Muchos sistemas se describen mejor mediante un conjunto finito de estados. Una orden no está «un poco pagada» desde el punto de vista de su flujo principal: puede estar pendiente, pagada, enviada, entregada o cancelada. Las transiciones válidas también forman parte del modelo.
const transiciones = {
pendiente: ["pagada", "cancelada"],
pagada: ["enviada", "cancelada"],
enviada: ["entregada"],
entregada: [],
cancelada: []
};
function puedeCambiarA(estadoActual, nuevoEstado) {
return transiciones[estadoActual].includes(nuevoEstado);
}
console.log(puedeCambiarA("pendiente", "pagada")); // true
console.log(puedeCambiarA("entregada", "enviada")); // falseEste tipo de representación aparece en interfaces, protocolos de red, procesos de negocio, videojuegos y autómatas. El modelo discreto hace visibles las transiciones que deben permitirse y las que deben rechazarse.
En JavaScript, la mayoría de los números se representan con punto flotante binario. Algunos decimales que parecen simples en base 10 no pueden representarse exactamente en esa forma, por lo que determinadas operaciones muestran pequeñas diferencias de redondeo.
const resultado = 0.1 + 0.2;
console.log(resultado); // 0.30000000000000004
console.log(resultado === 0.3); // false
console.log(Math.abs(resultado - 0.3) < 1e-10); // trueNo es un error de JavaScript en particular, sino una consecuencia de la representación finita. Para comparaciones de valores aproximados se usa una tolerancia. Para dinero, suele ser preferible almacenar unidades enteras mínimas, como centavos.
Una estrategia frecuente consiste en elegir una unidad suficientemente pequeña y trabajar solo con enteros. Por ejemplo, en lugar de guardar $19,99 como un número decimal, podemos almacenar 1999 centavos. Así evitamos errores de redondeo al sumar importes.
const precioEnCentavos = 1999;
const cantidad = 3;
const totalEnCentavos = precioEnCentavos * cantidad;
console.log(`Total: $${(totalEnCentavos / 100).toFixed(2)}`); // $59.97La unidad elegida depende del problema. Para una tienda pueden ser centavos; para un temporizador, milisegundos; para una imagen, píxeles. El objetivo es lograr precisión suficiente con una representación manejable.
No existe una única respuesta correcta para todos los problemas. Debemos analizar qué se necesita preservar y qué nivel de detalle exige la aplicación.
La diferencia entre lo discreto y lo continuo permite decidir cómo traducir un problema del mundo real a datos y operaciones de software. Un buen modelo conserva lo importante, hace explícitas sus limitaciones y permite construir algoritmos correctos.
En el próximo tema comenzaremos a estudiar técnicas de demostración matemática, que nos permitirán justificar formalmente que una afirmación o un algoritmo es válido.