Archivo categoría Geek

Tiempo exponencial y el problema del millón

Aviso: este artículo es una pequeña motivación al tema de la “eficiencia” de los algoritmos. Requiere ciertos conocimientos técnicos. Lo dejo en el blog para mantener registro de él (lo tenía escrito en un papel que encontré). ¡Comentarios bienvenidos!

Matías es un alumno de Introducción a la Programación. Para su primera tarea tiene que desarrollar un programa que escriba un número 1 en la consola. Con dos semanas de plazo para entregar, Matías —un alumno brillante— se relaja y decide aventurarse por una estrategia original. Probará todas las posibles secuencias de caracteres de largo 1, luego de largo 2, y así sucesivamente, hasta que una de ellas haga lo que pide el enunciado. De esta manera, él entregará el programa más corto posible que resuelve el problema (lo cual es motivo de orgullo).

Para conseguirlo cuenta con P computadores, cada uno con la capacidad de verificar O posibles programas por segundo (no me pregunten de dónde los sacó, sólo sabemos que los tiene). Llamemos t(n) al tiempo que tardarán todos estos computadores en verificar todos los programas de largo n (es decir, que tienen n caracteres en total). Suponiendo que Matías puede usar 256 caracteres para programar, tiene en total 256^n posibles programas de largo n. Así, el tiempo que tardará en verificarlos está dado por

t(n)=(256^n)/(P*O)

Supongamos ahora que en cada electrón del universo tenemos un supercomputador que realiza 10^50 de estas verificaciones por segundo. La cantidad estimada de electrones del universo es 10^130, por lo que

t(n)>=(256^n)/(10^50*10^130)

Ahora bien, el siguiente programa en Java escribe el número 1 en la consola. Tiene 96 caracteres.

public class Principal
{
  public static void main(String[] args) {
    System.out.println(1);
  }
}

Si eliminamos los saltos de línea innecesarios lo podemos dejar en 86 caracteres. Asumamos que éste es el programa de menor largo que es solución al enunciado.

public class Principal{public static void main(String[] args){System.out.println(1);}}

Para llegar a verificar los programas de largo 86, Matías debe verificar primero todos los de largo 85 (y darse cuenta de que ninguno le servía). En total hay 256^85 programas que verificar (es decir, exponencial respecto del largo del programa). Así, para n=85 tenemos que

Como 2^10=1024>1000=10^3, entonces

La edad estimada del universo es de 13.600 millones de años, y eso es 10^18. Esto significa que para verificar todos los programas de largo 85, Matías tardará t(85)>10^24>10^18 segundos, ¡más que la edad del universo!

¿Se van imaginando cuánto tiempo tardaría —con todo ese poder computacional— si el programa más corto que le sirve tuviera unas 200 líneas de código (que es algo más razonable que 85)?

Este simple ejemplo justifica un poco la elección del apodo “ineficiente” para los algoritmos de tiempo exponencial. Se sabe que los problemas de la clase NP pueden ser resueltos de manera determinista en tiempo a lo más exponencial (como el problema de Matías). Lo que no se sabe es si cada uno de ellos además se puede resolver en tiempo polinomial de manera determinista (P).

El problema de P y NP es uno de los más importantes en computación teórica, y ciertamente el más importante en el área de Complejidad Computacional. Tan importante es (y tan difícil), que es uno de los siete problemas por cuya solución el Instituto de Matemáticas Clay ofrece un millón de dólares.

Habrá que ponerse a estudiar.

No hay Comentarios

Conozcan a Nika

¿Recuerdan el anti-Grand-Slam de González? En el mismo sitio que recopiló la información de los ganadores de anti-Grand-Slam encontré una sección miscelánea de arte ASCII.

En ella uno de los más notables es Nika, una tierna gatita, que comparto aquí con ustedes.

   |\_._/|        |,\__/|        |\__/,|        |\_._/|
   | o o |        |  o o|        |o o  |        | 0 0 |
   (  T  )        (   T )        ( T   )        (  T  )
  .^`-^-'^.      .^`--^'^.      .^`^--'^.      .^`-^-'^.
  `.  ;  .'      `.  ;  .'      `.  ;  .'      `.  ;  .'
  | | | | |      | | | | |      | | | | |      | | | | |
 ((_((|))_))    ((_((|))_))    ((_((|))_))    ((_((|))_))

    Nika        Nika mirando   Nika mirando   Nika vio un
               a la izquierda  a la derecha      gato

   |\_._/|        |\_._/|
   |-o^o-|        |-@~@-|
   (  T  )        (  T  )
  .^`-^-'^.      .^`-^-'^.
  `.  ;  .'      `.  ;  .'            |\__/,|   (`\
  | | | | |      | | | | |          _.|o o  |_   ) )
 ((_((|))_))    ((_((|))_))     ---(((---(((---------

  Nika con       Nika con       Nika acecha al ratón
   lentes      lentes de sol

                                      ___
             |\__/,|   (`\        _.-|   |          |\__/,|   (`\
             |o o  |__ _) )      {   |   |          |o o  |__ _) )
           _.( T   )  `  /        "-.|___|        _.( T   )  `  /
 n n._    ((_ `^--' /_<  \         .--'-`-.     _((_ `^--' /_<  \
 <" _ }=- `` `-'(((/  (((/       .+|______|__.-||__)`-'(((/  (((/
  `" "
  Nika juega con el ratón      Nika juega con el ratón del computador

  |\__/,|   (`\
  |_ _  |.--.) )
  ( T   )     /
 (((^_(((/(((_>

 Nika durmiendo

Todos los créditos para Mike Rosulek, quien los dibujó cerca de 1995.

No hay Comentarios

Cambiar el primer día de la semana en Ubuntu

Una de las cosas molestas de usar Ubuntu es que por defecto el primer día de la semana es el domingo, lo cual es absolutamente ridículo (y no sólo en estas latitudes). Si bien existe una manera muy fácil de cambiar esa configuración en Evolution, no hay una opción directa para realizar este cambio en el calendario que queda en el panel.

(Re)buscando en internet, llegué a una solución, que comparto con ustedes. Supongo que funciona también en otras distribuciones basadas en Debian.

  1. Vayan a la línea de comandos (Aplicaciones > Accesorios > Terminal) y escriban:
    sudo gedit /usr/share/i18n/locales/es_ES
  2. Les pedirá la contraseña de superusuario (root) para continuar. Busquen una línea que sólo dice LC_TIME. Antes de encontrar una línea que diga END LC_TIME deberían encontrar una como la siguiente:
    first_weekday 1
  3. Cambien el 1 por un 2, de manera que resulte lo siguiente. Si la línea no existía, agréguenla en la línea anterior a LC_TIME.
    first_weekday 2
  4. Guarden, salgan del editor y finalmente en la consola ejecuten
    sudo locale-gen

Esto último regenerará los archivos correspondientes a la configuración en cuestión. Nuestro calendario del panel debería comenzar en lunes ahora.

Calendario en panel de Ubuntu

3 Comentarios

Mmm… I

Sesiones: la mayoría de los cursos se realizan sólo un día a la semana, de 19 a 21 horas. Los talleres tienen una duración de 3 horas.

Fuente: Programa de Artes Liberales, UNAB.

Tal vez demasiado liberales.

5 Comentarios

Probando

Pruébate éste!

Blogged with Flock

No hay Comentarios