                         Lecture Notes CC4102
                         ====================

Author: Jérémy Barbay <jeremy.barbay@dcc.uchile.cl>
Date: 2010-11-18 18:13:05 XXX


Table of Contents
=================
1 Presentacion y Evaluacion 
    1.1 Presentaciones 
        1.1.1 Quien somos 
        1.1.2 Quien son? 
        1.1.3 El curso 
    1.2 Programaci{\'o}n 
    1.3 Conceptos b{\'a}sicos (test) 
        1.3.1 Notaciones 
        1.3.2 Definiciones 
        1.3.3 Complejidad Computacional 
    1.4 Busqueda y Codificacion de Enteros (BONUS) 
2 1. Conceptos b{\'a}sicos y complejidad (3 semanas = 6 charlas) 
    2.1 Resultados de Aprendisajes de la Unidad 
    2.2 Principales casos de estudio 
    2.3 Repaso del proceso de diseño y an{\'a}lisis de un algoritmo. 
    2.4 Minimo Maximo: Cota inferior 
    2.5 Minimo Maximo: Cota superior 
    2.6 T\'ecnicas para demostrar cotas inferiores: adversario, teoria de la informacíon, reduccion 
    2.7 Metodologia de experimentaci{\'o}n 
        2.7.1 Al inicio, Ciencias de la computacion fue solamente experimentacion. 
        2.7.2 Sobre la "buena" manera de experimentar 
        2.7.3 Sobre la "buena" manera de presentar sus resultados experimentales. 
        2.7.4 Sobre la "buena" manera de describir una investigacion en general: 
        2.7.5 Otras referencias: 
    2.8 Resumen de la Section 
        2.8.1 Controles y Tareas 
        2.8.2 Recurrencias y Introduccion a la programacion dinamica 
        2.8.3 Resumen de la Section 
3 2. Algoritmos y Estructuras de Datos para Memoria Secundaria (3 semanas = 6 charlas) 
    3.1 Modelo de computaci{\'o}n en memoria secundaria. Accesos secuenciales y aleatorios 
    3.2 Diccionarios en Memoria Externa 
    3.3 Colas de prioridad en memoria secundaria. Cotas inferiores. 
    3.4 Ordenamiento en memoria secundaria: Mergesort. Cota inferior. 
    3.5 Resultados de Aprendisajes de la Unidad Dos 
4 3. T\'ecnicas avanzadas de diseño y an{\'a}lisis de algoritmos (4 semanas = 8 charlas) 
    4.1 Presentacion de la Unidad 3 
    4.2 Uso de *dominios discretos y finitos* en el diseño de algoritmos y estructuras de datos 
        4.2.1 Algorimos de Busqueda (Interpolation Search, Extrapolation Search) 
        4.2.2 Estructuras de Datos de Busqueda 
        4.2.3 Algoritmos de Ordenamiento ( Counting Sort, Bucket sort, radix sort, string sort) 
    4.3 *An{\'a}lisi amortizado* de algoritmos y estructuras de datos 
        4.3.1 An{\'a}lisis amortizada 
        4.3.2 Colas de Prioridades 
    4.4 *Algoritmos en línea*. Competividad. Adaptividad. 
        4.4.1 List Accessing 
        4.4.2 Paginamiento Deterministico 
    4.5 Conclusion Unidad 3 
5 4. Algoritmos no convencionales (5 semanas = 10 charlas) 
    5.1 Descripcion de la Unidad 
        5.1.1 Resultados de Aprendisajes de la Unidad 
        5.1.2 Principales casos de estudio: 
    5.2 *Aleatorizacion* (1 semana = 2 charlas) 
        5.2.1 Definiciones 
        5.2.2 El poder de un algoritmo aleatorizado 
        5.2.3 Aleatorizacion de la entrada 
        5.2.4 *Relacion con Problemas NP-Dificiles* 
        5.2.5 Complejidad de un algoritmo aleatorizado 
        5.2.6 Tecnicas de cotas inferiores de la complejidad aleatorizada 
        5.2.7 Algoritmos tipo Monte Carlo y Las Vegas 
        5.2.8 Primalidad 
        5.2.9 Clases de complejidad aleatorizada
    5.3 Nociones de *aproximabilidad* (2 semanas = 4 charlas) 
        5.3.1 Intro: Aproximaci{\'o}n de problemas de optimizaci{\'o}n NP-dificiles 
        5.3.2 *$p(n)$-aproximaci{\'o}n*:  Definicin 
        5.3.3 Ejemplo: Bin Packing (un problema que es 2-aproximable) 
        5.3.4 Ejemplo: Recubrimiento de Vertices (Vertex Cover) 
        5.3.5 Ejemplo: Vendedor viajero (Traveling Salesman) 
        5.3.6 Ejemplo: Vertex Cover con pesos 
        5.3.7 PTAS y FPTAS: Definiciones 
        5.3.8 Ejemplo: Problema de la mochila 
    5.4 Algoritmos *paralelos* y distribuidos (2 semanas = 4 charlas) 
        5.4.1 Modelos de paralelismo 
        5.4.2 Modelo PRAM 
        5.4.3 Como medir el "trade-off" entre recursos (cantidad de procesadores) y tiempo? 
        5.4.4 PROBLEMA: Calcular Max(A[1,...,N]) 
        5.4.5 LEMMA de Brent, Trabajo y Consecuencias 
        5.4.6 PROBLEMA: Ranking en listas 
        5.4.7 PROBLEMA: Prefijos en paralelo ("Parallel Prefix") 
        5.4.8 Conclusion del Parallelismo: 
    5.5 Conclusion Unidad 
6 CONCLUSION del curso 


1 Presentacion y Evaluacion 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1.1 Presentaciones 
===================

1.1.1 Quien somos 
------------------
 - franco-ingles-castellano
 - curso interactivo?
 - dos auxiliares

1.1.2 Quien son? 
-----------------
       * Quien
         - tomo el curso CC40A en los ultimos semestres?
         - toma CC53A
       * Quien
         - piensa seguir en la universidad despues de magister?

1.1.3 El curso 
---------------
  * Tematicas 
    1. Conceptos b{\'a}sicos y complejidad (3 semanas = 6 charlas)
    2. Algoritmos y Estructras de Datos para Memoria Secundaria (3 semanas = 6 charlas)
    3. T\'ecnicas avanzadas de diseño y an{\'a}lisis de algoritmos (4 semanas = 8 charlas)
    4. Algoritmos no convencionales  (5 semanas = 10 charlas)
  * Modo
   - *Clases expositivas* del profesor de c{\'a}tera
     - buscando la participaci{\'o}n de los alumnos en pequeños
       problemas que se van proponiendo durante la exposici{\'o}n.
   - *Clases auxiliares* dedicadas a explicar ejemplos m{\'a}s
     extensos, resolver ejercicios propuestos, y preparaci{\'o}n pre y
     post controles.
   - *Exposici{\'o}n* de las mejores tareas de los alumnos, como casos
     de estudio de implementaci{\'o}n y experimentaci{\'o}n.
  * Evaluacion
       - [2/9] Control 1 (unidades 1, 2 y parte de 3)
       - [2/9] Control 2 (unidades 3,4)
       - [2/9] Examen (todas unidades)
       - [1/9] Tarea 1
       - [1/9] Tarea 2
       - [1/9] Tarea 3
  * Nota Final      
    - controles y examen se promedian a partes iguales (el
      examen reemplaca el peor control si la nota del examen es
      mayor.)
    - tareas se promedian a partes iguales
    - nota final es 2/3 nota de controles y 1/3 de la nota de
      tarea.

1.2 Programaci{\'o}n 
=====================
   - Cuanto memoria hay en un computador? Como se maneja?
   - Cual es la diferencia entre el disque duro y la memoria?
   - Cuanto procesadores hay en un computador? Como se programan?
   - Cual algoritmo elegir a implementar para un problema dicho?
   - Cual es la diferencia entre programacion imperativa y funcional?

1.3 Conceptos b{\'a}sicos (test) 
=================================

1.3.1 Notaciones 
-----------------
     - $O(), o(), \Omega(), \omega(), \Theta(), \theta()$

1.3.2 Definiciones 
-------------------
     - Complejidad en el peor caso
     - Complejidad en promedio
     - Otros modelos computacionales?

1.3.3 Complejidad Computacional 
--------------------------------
     - Cual Algoritmos conocen? Cual son sus complejidad?
       - para buscar en un arreglo (ordenado? no ordenado?)
       - para ordenar un arreglo (en el modelo de comparaciones o no?)
     - Cual cotas inferiores conocen?
       - buscar?
       - ordenar?
     - Cual problemas dificiles conocen?
       - elegir sus cursos
       - assignar salas y horarios a los cursos
       - assignar infermeros a hospitales

1.4 Busqueda y Codificacion de Enteros (BONUS) 
===============================================
    - A VER EN CASA O TUTORIAL

2 1. Conceptos b{\'a}sicos y complejidad (3 semanas = 6 charlas) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2.1 Resultados de Aprendisajes de la Unidad 
============================================
    - Comprender el concepto de complejidad de un problema como cota inferior
    - conocer t\'ecnicas elementales para demostrar cotas inferiores
    - Conocer algunos casos de estudio relevantes
    - Adquirir nociones b{\'a}sicas de experimentaci{\'o}n en algoritmos. 

2.2 Principales casos de estudio 
=================================
    - cota inferior para mínimo y m{\'a}ximo de un arreglo
    - caso promedio del quicksort
    - cota inferior para búsqueda en un arreglo con distintas probabilidades de acceso

2.3 Repaso del proceso de diseño y an{\'a}lisis de un algoritmo. 
========================================================================
    * Problema de la Torre de Hanoi 
      - definition
      - cota superior
      - cota inferior
      - A VER EN CASA
    * Variantes de la Torre de Hanoi
      - pesos distintos?
      - Disk Pile Problem (n discos pero h<n tamanos)
        - cota inferior en funcion de n, en funcion de n,h 
        - cota superior en funcion de n, en funcion de n,h
      - A VER EN CASA
    * Minimo (resp. maximo) de un arreglo
      - cota superior
      - cota inferior
    * Minimo Maximo de un arreglo
      - cota superior
      - cota inferior

2.4 Minimo Maximo: Cota inferior 
=================================
    * Sean las variables siguentes:
      - $O$ los $o$ elementos todavia no comparados;
      - $G$ los $g$ elementos que ``gaaron'' todas su
        comparaciones hasta ahora;
      - $P$ los $p$ elementos que ``perdieron'' todas su
        comparaciones hasta ahora;
      - $E$ las $e$ valores eliminadas (que perdieron al menos
        una comparacin, y gaaron al menos una comparacion);
    -  $(o,g,p,e)$ describe el estado de cualquier algoritmo:
      -  siempre $o+g+p+e=n$;
      -  al inicio, $g=p=e=0$ y $o=n$;
      -  al final, $o=0$, $g=p=1$, y $e=n-2$.
    -  Despues una comparacion $a?b$ en cualquier algoritmo del
      modelo de comparacion, $(o,g,p,e)$ cambia en funcion del
      resultado de la comparacion de la manera siguente:
      $$
      \begin{array}{c|c|c|c|c}
               & a\in O        & a\in G               & a\in P               & a\in E      
        \hline %--------------------------------------
        b\in O & o-2,g+1,p+1,e & o-1,p,e+1            & o-1,g,p,e+1          & o-1,g+1,p,e 
               &               & o-1,g,p+1,e          & o-1,g+1,p,e          & o-1,g,p+1,e 
        \hline %--------------------------------------
        b\in G &               & o,g-1,p,e+1          & o,g,p,e              & o,g,p,e     
               &               &                      & o,g-1,p-1,e+2        & o,g-1,p,e+1 
        \hline %--------------------------------------
        b\in P &               &                      & o,g,p-1,e+1          & o,g,p,e     
               &               &                      &                      & o,g,p-1,e+1 
        \hline %--------------------------------------
        b\in E &               &                      &                      & o,g,p,e
      \end{array}
      $$
    -  En algunas configuraciones, el cambio del vector estado
      depende del resultado de la comparacion: un adversario puede
      maximisar la complejidad del algoritmo eligando el resultado
      de cada comparacion. El arreglo siguente contiene en graso las
      opciones que maximizan la complejidad del algoritmo:
      $$
      \begin{array}{c|c|c|c|c}
               & a\in O        & a\in G               & a\in P               & a\in E           
        \hline %--------------------------------------
        b\in O & o-2,g+1,p+1,e & o-1,p,e+1            & o-1,g,p,e+1          & o-1,g+1,p,e      
               &               & \mathbf{o-1,g,p+1,e} & \mathbf{o-1,g+1,p,e} & o-1,g,p+1,e      
        \hline %--------------------------------------
        b\in G &               & o,g-1,p,e+1          & \mathbf{o,g,p,e}     & \mathbf{o,g,p,e} 
               &               &                      & o,g-1,p-1,e+2        & o,g-1,p,e+1      
        \hline %--------------------------------------
        b\in P &               &                      & o,g,p-1,e+1          & \mathbf{o,g,p,e} 
               &               &                      &                      & o,g,p-1,e+1      
        \hline %--------------------------------------
        b\in E &               &                      &                      & o,g,p,e
      \end{array}
      $$
    -  Con estas opciones, hay
      -  $\lceil n/2\rceil$ transiciones de $O$ a $G\cup P$, y
      -  $n-2$ transiciones de $G\cup P$ a $E$.
    -  Eso resulta en una complejidad en el peor case de $\lceil
      3n/2 \rceil-2 \in 3n/2 +O(1)$ comparaciones.

2.5 Minimo Maximo: Cota superior 
=================================

    * Calcular el minimo con el algoritmo previo, y el maximo
     con un algoritmo simetrico, da una complejidad de $2n-2$
     comparaciones, que es demasiado.
    * El algoritmo siguente calcula el max y el min en
     $\frac{3n}{2}-2$ comparaciones:
     1. Dividir $A$ en $\lfloor n/2 \rfloor$ pares (y
        eventualemente un elemento mas, $x$).
     2. Comparar los dos elementos de cada par.
     3. Ponga los elementos superiores en el grupo $S$, y los
        elementos inferiores en el grupo $I$.
     4. Calcula el minima $m$ del grupo $I$ con el algorimo de la
        pregunta previa, que performa $\lfloor n/2 \rfloor-1$ comparaciones
     5. Calcula el maxima $M$ del grupo $I$ con un algoritmo
        simetrico, con la misma complejidad.
     6. Si $n$ es par,
       + $m$ y $M$ son respectivamente el minimo y el maximo de $A$.
     7. Sino, si $x<m$, 
        + $x$ y $M$ son respectivamente el minimo y el maximo de $A$.
     8. Sino, si $x>M$, 
        + $m$ y $x$ son respectivamente el minimo y el maximo de $A$.
     9. Sino
        + $m$ y $M$ son respectivamente el minimo y el maximo de $A$.
    * La complejidad total del algoritmo es
     -  $n/2+2(n/2-1)=3n/2-2\in 3n/2 + O(1)$ si $n$ es par
     -  $(n-1)/2 + 2(n-1)/2 +2 = 3n/2 + 1/2\in 3n/2 + O(1)$ si
        $n$ es impar.
     -  en la clase $3n/2 + O(1)$ en ambos casos.


2.6 T\'ecnicas para demostrar cotas inferiores: adversario, teoria de la informacíon, reduccion 
=======================================================================================================
    1) Busqueda Ordenada (en el modelo de comparaciones)
       1. Cota superior: $2\lg n$ vs $1+\lg n$
       2. Cota inferior en el peor caso: Strategia de Adversario
          cota inferior en el peor caso de $1+\lg n$
       3. Cota inferior en el caso promedio uniforme
          - Teoria de la Informacion
          - = Arbol de Decision
          - cota inferior de lg(2n+1), i.e. de $1+\lsup\lg(n+1/2)\\rsup$
       4. La complejidad del problema
          - en el peor caso es $\Theta(\lg n)$
          - en el caso promedio es $\Theta(\lg n)$
       5. Pregunta: en este problema las cotas inferiores en el peor
          caso y en el mejor caso son del mismo orden. Siempre es verdad?
    2) Busqueda desordenada
       1. Complejidad en el peor caso es $\Theta(n)$
       2. Complejidad en el caso promedio?
          - cota superior
            - Move To Front
            - ?BONUS? Transpose
          - cota inferior
            - algoritmo offline, lemma del ave
          - A VER EN CASA O TUTORIAL: Huffman?
    3) Ordenamiento (en el modelo de comparaciones)
       - cota superior $O(n\lg n)$
       - cota inferior en el peor caso
         - cual tecnica?
           - lema del ave?
           - Strategia de Adversario?
           - Arbol Binario de Decision
         - Resultado:
           - $\Omega(n \lg n)$
       - cota inferior en el caso promedio
         - $\Omega(n \lg n)$
    4) BONUS: complejidad en promedio y aleatorizada
       - La relacion entre 
         - complejidad en promedio de un algoritmo deterministico
         - complejidad en el peor caso de un algoritmo aleatorizado (promedio sobre su aleatoria)

2.7 Metodologia de experimentaci{\'o}n 
=======================================

2.7.1 Al inicio, Ciencias de la computacion fue solamente experimentacion. 
---------------------------------------------------------------------------
* Turing y el codigo Enigma 
  - el importante estaba de solucionar la instancia del dia
    (romper la llave del dia, basado en los messages de
    meteo, para decryptar los messages mas importantes)
  - no mucho focus en el problema, aunque Turing si escribio
    la definicion de la Maquina universal.
* Experimentacion basica 
  - correga hasta que fonciona (o parece foncionar)
  - correga hasta que entrega resultados correctos (o que parecen correctos)
  - mejora hasta que fonciona en tiempo razonable (en las instancias que tenemos)
* Problemas: 
  - Demasiado "Ah Hoc"
  - falta de rigor, de reproducibilidad
  - desde el inicio, no "test bed" estandard, cada uno tiene sus tests.
  - mas tarde, no estandard de maquinas 
* Respuestas: Knuth et al. 
  - complejidad asymptotica: independancia de la maquina
  - complejidad en el peor caso y promedio: independancia del "test bed"
  - todavia es necesario de completar las estudias teoricas
    con programacion y experimentacion: el modelo teorico es
    solamente una simplificacion.
* Theoreticos desarollaron un lado "mathematico" de ciencias 
  de la computacion, con resultados importantes tal que
  - NP-hardness
  - "Polynomial Hierarchy" ([http://en.wikipedia.org/wiki/Polynomial_hierarchy])
* Theoria y Practica se completen, pero hay conflictos en ambos lados: 
  - demasiado theorias sin implementaciones (resultado del
    ambiante social tambien).
  - todavia hay estudios experimentales "no reproducibles"

2.7.2 Sobre la "buena" manera de experimentar 
----------------------------------------------
     ("A Theoretician's Guide to the Experimental Analysis of Algorithms", David S. Johnson, 2001)
* Fija una hipothesis *antes* de programar. 
  - aunque el objetivo sea de programar un software
    completo, solamente es necesario de implementar de
    manera eficiente la partes relevantes. El resto se puede
    implementar de manera "brutal". (E.g. "Intersection Problem")
* "Incremental Programming" 
  - busca en la red "Agile Programming", "Software Engineering".
  - una experimentacion es tambien un proyecto de software, y
    las tecnicas de ingeniera de software se aplican tambien.
  - Construe un simulador en etapas, donde a cada etapa
    fonctiona el simulador entero.          
* "Modular Programming" 
  - Experimentacion es Investigacion, nunca se sabe por
    seguro que se va a medir despues.
  - Hay que programar de manera modular por salgar tiempo en
    el futuro.
  

2.7.3 Sobre la "buena" manera de presentar sus resultados experimentales. 
--------------------------------------------------------------------------
("Presenting Data from Experiments in Algorithmics", Peter Sanders, 2002)
* El proceso: 
  * Experimentacion tiene un ciclo:
    1. "Experimental Design" (inclue la eleccion de la hypothesis)
    2. "Description of Measurement"
    3. "Interpretation"
    4. vuelve al paso 1.
  * La presentacion sigue la misma estructura, pero solamente
    exceptionalemente describe mas que una iteracion (la
    mejor, no necesaramiente la ultima) del ciclo.
  
* Eliges que quieres comunicar. 
  - el mismo dato se presenta diferamente en funcion de la
    emfasis del reporte.
  - pero, siempre la descripcion debe permitir la
    *reproducibilidad* de la experimentacion.
  
* Tables vs 2d vs 3d plot 
  * tables 
    - son faciles, y buenas para menos de 20 valores
    - son sobre-usadas
  * Grafes 3d
    - mas modernos, impresionantes, pero
    - en impresion no son tan informativos
    - tiene un futuro con interactive media donde el usuario
      puede cambiar el punto de vista, leer las valores
      precisas, activar o no las surfacas.
  * Grafes 2d
    - en general preferables, pero de manera inteligente!
    - cosas a considerar:
      - log scale en x y/o y
      - rango de valores en x y/o y.
      - regla de "banking to 45 deg":
        - "The weighted average of the slants of the line
          segments in the figure should be about 45"
        - se puede aproximar on un grafo en "paysage"
          siguiendo el ratio de oro.
      - factor out la informacion ya conocida 
  * Maximiza el Data-Ink ratio.
  
      ``Toward an Experimental method for algorithm simulation,'' INFORMS Journal on 
      Computing, Vol 8, No 1  Winter 1995.
  
      ``Analyzing Algorithms by simulation:  Variance Reduction Techniques and 
      Simulation Speedups,'' ACM Computing Surveys, June 1992.
  
  3.  For a good book on introductory statistics with computer science
      examples, I recommend 
      - Cohen: Empirical Methods for Artificial Intelligence
      - Thomas Bartz-Beielstein et al, on Empirical Methods for the
        Analysis of OPtimization Algorithms 
      - Catherine McGeoch, A Guide to Experimental Algorithmics, (January 2011)
  
  

2.7.4 Sobre la "buena" manera de describir una investigacion en general: 
-------------------------------------------------------------------------
     [http://www.amazon.com/Making-Sense-Students-Engineering-Technical/dp/019542591X]
     Making sense; a student's guide to research and writing;
     engineering and the technical sciences, 2d ed.  Northey, Margot
     and Judi Jewinski.  Oxford U. Press 2007 252 pages $32.50
     Paperback

2.7.5 Otras referencias: 
-------------------------
     - Research Design: Qualitative, Quantitative, and Mixed Methods Approaches 
       John W. Creswell
       [http://www.amazon.com/Research-Design-Qualitative-Quantitative-Approaches/dp/1412965578/ref=ntt_at_ep_dpi_1]

2.8 Resumen de la Section 
==========================

2.8.1 Controles y Tareas 
-------------------------

 - TAREA 1: Busqueda Binaria vs others  
 - TAREA 2: static cache-oblivious tree 
 - TAREA 3: Interpolation vs others     
 - CONTROL 1                            
 - TAREA 4: Hashing
 - TAREA 5: Paginamiento                              
 - TAREA 6: Vertex Cover                             
 - CONTROL 2                            
 - EXAMEN                              

Las tareas se hacen en dos semanas.

2.8.2 Recurrencias y Introduccion a la programacion dinamica 
-------------------------------------------------------------
     - $X_n = X_{n-1} + a_n$
     - Torre de Hanoi
     - Fibonacci 
     - Subsecuencia de suma maximal
     - Subsecuencia commun mas larga
       + solucion ingenua
       + Solucion en tiempo polynomial (pero espacio $O(n^2)$)
       + Solucion en espacio lineal (y tiempo $O(n^2)$)
       + (BONUS) Solucion de Hirshberg en tiempo $O(nm)$ y espacio $\min(n,m)$

2.8.3 Resumen de la Section 
----------------------------
     1. Conceptos Basicos
        - $O(), o(), \Omega(), \omega(), \Theta(), \theta()$
        - Complejidad en el peor caso, en promedio
        - Modelos computacionales:
          - modelo de comparaciones
          - modelo de memoria externa
     2. Tecnicas de Cotas Inferiores
        - lema del ave (reduccion)
        - strategia de adversario
        - teoria de la informacion (arbol de decision binario)
        - Analisis fine
     3. Metodologia de experimentacion
        - Porque?
        - Como hacer la experimentacion
        - Como analizar y presentar los resultados
     4. Casos de Estudios
        - Torre de Hanoi
        - "Disk Pile problem"
        - Busqueda y Codificacion de Enteros (busqueda doblada)
        - Busqueda binaria en $\Theta(1+\lg n)$ (mejor que $2\lg n$)
        - Algoritmo en $2n/3 + O(1)$ comparaciones para min max

3 2. Algoritmos y Estructuras de Datos para Memoria Secundaria (3 semanas = 6 charlas) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

3.1 Modelo de computaci{\'o}n en memoria secundaria. Accesos secuenciales y aleatorios 
=======================================================================================
    1. Arquitectura de un computador: la memoria
       1) Muchos niveles de memoria
          - Procesador
          - registros
          - Cache L1
          - Cache L2
          - Memory
          - Cache 
          - Disco Duro magnetico /  Memory cell  
          - Akamai cache
          - Discos Duros en la red
          - CD y DVDs tambien son "memoria"
       2) Diferencias
          - velocidad
          - precio de construccion
          - relacion fisica entre volumen y velocidad
          - volatil o no
          - accesso arbitrario en tiempo constante o no.
          - latencia vs d\'ebito
       3) Modelos formales
          - RAM
          - Jerarquia con dos niveles, paginas de tamaño B
          - Jerarquia con k niveles, de paginas de tamaños $B_1,...,B_k$
          - "Cache oblivious"
          - Otros... mas practicas, mas dificil a analizar.

3.2 Diccionarios en Memoria Externa 
====================================
    1. B-arbol
       1) $(2,3)$ Arbol: un arbol de busqueda donde
          - cada nodo tiene 1 o 2 llaves, que corresponde a 2 o 3
            hijos, con la excepcion de la raiz;
          - todas las hojas son al mismo nivel (arbol completamente balanceado)
          - Propiedades: 
            - altura de un $(2,3)$ arbol?
            - tiempo de busqueda?
            - insercion en un $(2,3)$ arbol?
            - delecion en un $(2,3)$ arbol?
       2) $(d,2d)$ Arbol un arbol donde
          - cada nodo tiene de $d$ a $2d$ hijos, con la excepcion de la
            raiz (significa $d-1$ a $2d-1$ llaves).
          - todas las hojas son al mismo nivel (arbol completamente
            balanceado)
          - Propiedades: 
            - altura de un $(d,2d)$ arbol?
            - tiempo de busqueda?
            - insercion en un $(d,2d)$ arbol?
            - delecion en un $(d,2d)$ arbol?
       3) B-Arbol, y variantes
          - B-Arbol
            - [http://www.youtube.com/watch?v=coRJrcIYbF4]
            - [http://en.wikipedia.org/wiki/B-tree]
          - B^* arbol
            - otros nodos que la raiz son llenos al menos hasta $2/3$ (en vez de $1/2$)
            - [http://en.wikipedia.org/wiki/B*-tree]
          - B^+ arbol
            - the leaf nodes of the tree are chained together in the form of a linked list. 
            - [http://www.youtube.com/watch?v=GsY3-K4-J-8&feature=related]
    2. Van Emde Boas arbol (vEB)
       [http://en.wikipedia.org/wiki/Van_Emde_Boas_tree]
       1) Historia:
          - Originalemente (1977) un estructura de datos normal, que
            suporta todas las operaciones en $O(\lg\lg n)$, inventada
            por el equipo de Peter van Emde Boas.
          - No considerado utiles en practica para "pequeños"
            arboles.
          - Applicacion a "Cache-Oblivious" algoritmos  y estructuras de datos
            - optimiza el cache sin conocer el tamaño $B$ de sus paginas
            - => optimiza todos los niveles sin conocer $B_1,...,B_k$
          - otras applicaciones despues en calculo parallelo (?)
       2) Definicion
          - Cada nodo contiene un arbol van EmdeBoas sobre $\sqrt{n}$ elementos
          - $\lg\lg n$ niveles de arboles
          - operadores:
            * Findnext
            * Insert
            * Delete
       3) Analisis
          - Busqueda en "tiempo" O(\lg n / \lg B) a cualquier nivel
            $i$, donde el tiempo es la cuantidad de accessos al cache
            del nivel considerado
          - Insercion
          - Delecion
    3. Finger Search Tree: la busqueda doblada de los arboles de busqueda
       1) Estructura de datos
       2) algorimo de busqueda
       3) analisis: busqueda en $O(\lg p)$ 

3.3 Colas de prioridad en memoria secundaria. Cotas inferiores. 
================================================================
    1) Colas de Prioridades tradicional: 
       - que se necesita?
         * Operadores 
           - /insert(key,item)/
           - /findMind()/
           - /extractMin()/
         * Operadores opcionales
           - /heapify/
           - /increaseKey, decreaseKey/
           - /find/
           - /delete/
           - /successor/predecessor/
           - /merge/
           - ...
       - diccionarios: demasiado espacio para que se pide
         - menos operadores que diccionarios 
           - => mas flexibilidad en la representacion
           - => mejor tiempo y/o espacio
       - *binary heap*: una estructura a dentro de muchas otras:
         - sequence-heaps
         - binomial queues
         - Fibonacci heaps
         - leftist heaps
         - min-max heaps
         - pairing heaps
         - skew heaps
         - /van Emde Boas queues/

       - *van Emde Boas queues*
         [http://www.itl.nist.gov/div897/sqg/dads/HTML/vanemdeboas.html]

         - Definicion: 

           "An efficient implementation of priority queues where
           insert, delete, get minimum, get maximum, etc. take O(log
           log N) time, where N is the total possible number of
           keys. Depending on the circumstance, the implementation
           is null (if the queue is empty), an integer (if the queue
           has one integer), a bit vector of size N (if N is small),
           or a special data structure: an array of priority queues,
           called the bottom queues, and one more priority queue of
           array indexes of the bottom queues."

          - rendimiento en memoria secundaria de "binary heap": muy malo?

    3) Colas de Prioridades en Memoria Secundaria: diseno  
       * Reference: 
         + [http://www.dcc.uchile.cl/~gnavarro/algoritmos/tesisRapa.pdf]
           - paginas 9 hasta 16
         + Otras referencias en [http://www.leekillough.com/heaps/]
       - El equivalente de B-Arbol
       - Muchas alternativas en practica
          - Buffer trees
          - M/B-ary heaps
          - array heaps
          - R-Heaps
          - Array Heaps
          - sequence heaps
          - Mas en "An experimental study of priority queues in external memory"
            [http://portal.acm.org/citation.cfm?id=351827.384259]

     3) Colas de Prioridades en Memoria Secundaria: cota inferior?
        - Cota inferior para dictionaries es una cota inferior por
          colas de prioridades o no?
          - No. La reduccion es en la otra direccion.
        - Cual es la cota inferior mas simple que se puede imaginar?
          - $\Omega(n/B)$

    4) /REFERENCES/
       - [http://en.wikipedia.org/wiki/Priority\_queue]
       - [http://en.wikipedia.org/wiki/Heap\_data\_structure]
       - "An experimental Study of Priority Queues in External Memories" by Brengel, Crauser, Ferragina and Meyer

3.4 Ordenamiento en memoria secundaria: Mergesort. Cota inferior. 
==================================================================
    1. Un modelo mas fino

       1) Cuantos paginas quedan en memoria local?
          - no tan importante para busqueda
          - muy importante para applicaciones de computacion con mucho
            datos.

       2) Nuevas notaciones

          - B = Tamano pagina
          - N = cantidad de elementos en total
          - n = cantidad de paginas con elementos = $N/B$
          - M = cantidad de memoria local
          - m = cantidad de paginas locales = $M/B$
          - mnemotechnique: 
            - $N,M,B$ en cantidad de palabras maquinas (=bytes?)
            - $n,m$ en cantidad de paginas
            - $n<<N$, $m<<M$

       3) En estas notaciones, usando resultos previos:

          * Insertion Sort (en un B-Arbol) 
            - usa dictionarios en memoria externa
            - $N \lg N / \lg B = N \log_B N$

          * Heap Sort 
            - usa colas de prioridades en memoria externa
            - $N \lg N / \lg B = N \log_B N$

          * Eso es optimo o no?

    2. Cotas Inferiores en Memoria Secundaria 
       * para buscar en un diccionario?
         - en modelo RAM? (de comparaciones)
           - $\lg N$
         - en modele Memoria Externa? (de comparaciones)
           - $\lg N / \lg B = \log_B N$    (ajustado)

       * para fusionar dos arreglos ordenados?
         - en modelo RAM?
           - $N$
         - en modelo Memoria Externa con paginas de tamaño B?
           - $N/B = n$   (ajustado)

       * para fusionar k arreglos ordenados?
         - en modelo RAM? 
           - $N$
         - en modelo de Memoria Externa con M paginas de tamaño B?
           - $N/B = n$ (si $M > kB$)

       * para Ordenar
         (corrige y adapte la prueba de [http://www.daimi.au.dk/~large/ioS06/Alower.pdf] )
            - en modelo RAM de comparaciones 
              - $n \lg n$
            - en modelo Memoria Externa con $n/B$ paginas de tamaño B
              * $\Omega( N/B \frac{ \lg(N/B) }{ \lg(M/B) }  )$
              * que se puede notar mas simplamente $\Omega( n\lg_m n )$
            - Prueba:

              * en vez de considerar el problema de ordenamiento,
                supponga que el arregla sea una permutacion y
                considera el problema (equivalente en ese caso) de
                identificar cual permutacion sea.

              * inicialemente, pueden ser n! permutaciones.
                - supponga que cada bloque de B elementos sea ya
                  ordenado (impliqua un costo de al maximo n=N/B
                  accessos a la memoria externa).
                - queda $N! / ( (B!)^n )$ permutaciones posibles.

              * para cada accesso a una pagina de memoria externo,
                cuantos permutaciones potenciales podemos eliminar?
                - con $M$ entradas en memoria primaria
                - $B$ nuevas entradas se pueden quedar de ${M \choose B}
                  = \frac{M!}{B!(M-B)!}$ maneras distintas
                - calcular la union de los $M+B$ elementos reduce la
                  cuantidad de permtuaciones por un factor de
                  $1 / {M \choose B}$
                - despues de t accessos (distintos) a la memoria
                  externa, se reduci la cuantidad de permutaciones a
                  $N! / (  (B!)^n  {M \choose B}^t  )$

              * cuanto accessos a la memoria sean necesarios para que
                queda al maximo una permutacion?
                - $N! / (  (B!)^n  {M \choose B}^t )$ debe ser al maximo uno.
                - usamos las formulas siguientes:
                  - $\log(x!) \approx x\log x$
                  - $\log {M \choose B} \approx B \lg \frac{M}{B}$

                  N!        \leq          (B!)^n {M \choose B}^t           
                 ---------+-------------+---------------------------------
                  N \lg N   \leq          n B \lg B + t B \lg \frac{M}{B}  
                 ---------+-------------+---------------------------------
                  t         \geq  \frac   { N\lg N - nB \lg B }            
                                          { B \lg(M/B) }                   
                 ---------+-------------+---------------------------------
                            \geq  \frac   { N \lg(N/B) }                   
                                          { B \lg(M/B) }                   
                 ---------+-------------+---------------------------------
                            \geq  \frac   { n \lg n }                      
                                          { \lg m }                        
                 ---------+-------------+---------------------------------
                            \geq          n \log_m n                       



       * BONUS: Para ordenar strings, un caso particular (donde la
         comparacion de dos elementos tiene un costo variable):
         [http://www.brics.dk/~large/Papers/stringsstoc97.pdf]
         - $\Omega( N_1/B \log_{M/B}(N_1/B) + K_2 \lg_{M/B} K_2 + N/B )$
         - donde
           - $N_1$ es la suma de los tamanos de las caldenas mas cortas que $B$
           - $K_2$ es la cuantidad de caldenas mas largas que $B$

    3. Ordenar en Memoria Externa N elementos (en $n=N/B$ paginas)
       [http://en.wikipedia.org/wiki/External_sorting]

       * Usando dictionarios o colas de prioridades en memoria externa
         - $N \lg N / \lg B = N \log_B N$
         - No es "ajustado" con la cota inferior
         - impliqua 
           - o que hay un mejor algoritmo
           - o que hay una mejor cota inferior

       * Queda un algoritmo de ordenamiento: MergeSort
         - usa la fusion de $m-1$ arreglos ordenados en memoria
           externa:
           1) carga en memoria principal $m-1$ paginas, cada una la
              primera de su arreglo.
           2) calcula la union de estas paginas en la pagina $m$ de
              memoria principal, 
              - botando la pagina cuando llena
              - cargando una nueva pagina (del mismo arreglo) cuando
                vacilla
           3) La complejidad es $n$ accessos. 
         - Algoritmo:
           1) ordena cada de las $n$ paginas \rightarrow $n$ accessos
           2) Cada nodo calcula la union de $m$ arreglos y escribe su
              resultado, pagina por pagina, en la memoria
              externa. 
         - Analisis:
           - Cada nivel de recurencia costa $n$ accessos
           - Cada nivel reduce por $m-1$ la cantidad de arreglos
           - la complejidad total es de orden $n\log_m n$ accessos. (ajustado)

    4. *BONUS* cota inferior para una cola de prioridad?
       - una cola de prioridad se puede usar para ordenar (con $N$ accessos)
       - hay una cota inferior para ordernar de $n \log_m n$
       - entonces????

3.5 Resultados de Aprendisajes de la Unidad Dos 
================================================
    - Comprender el modelo de costo de memoria secundario
    - Conocer algoritmos y estructuras de datos b{\'a}sicos que son eficientes en memoria secundaria, 
    - y el analisis de su desempeño.

4 3. T\'ecnicas avanzadas de diseño y an{\'a}lisis de algoritmos (4 semanas = 8 charlas) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4.1 Presentacion de la Unidad 3 
================================
     1) Dominios discretos y finitos 
        - Interpolacion
        - hash
        - hash en memoria Secundaria
        - algoritmos de ordenamientos con universo finito 
     2) An{\'a}lisis amortizada
      - an{\'a}lisi completo,
      - contabilidad de costos, 
      - funci{\'o}n potencial
     3) Algoritmos en linea 
        - "ski renting" problema
        - analisis competitiva ("Competitive Analysis")

4.2 Uso de *dominios discretos y finitos* en el diseño de algoritmos y estructuras de datos 
===================================================================================================

4.2.1 Algorimos de Busqueda (Interpolation Search, Extrapolation Search) 
-------------------------------------------------------------------------

     1) Interpolacion

        1. Introduccion:             
           - Hagaria busqueda binaria en un anuario telefonico para
             el nombre "Barbay"? En un diccionario para la ciudad
             "Zanzibar"?
           - ojala que no: se puede provechar de la informacion
             que da la primera letra de cada palabra

        2. Algoritmo

           - Interaccion

        3. Analisis
           * La analisis *en promedio* es complicada: conversamos
             solamente la intuicion matematica (para mas ver la
             publicacion cientifica de SODA04, Demaine Jones y
             Patrascu):
             - si las llaves son *distribuidas uniformamente*, la
               distancia en promedio de la posicion calculada por
               interpolacion *lineal* hasta la posicion real es de
               $\sqrt{r-l}$.
             - entonces, se puede reducir el tamaño del subarreglo
               de $n$ a $\sqrt{n}$ cada (dos) comparaciones
             - la busqueda por interpolacion 
               - en promedio, 
               - si las llaves son *distribuidas uniformamente*,
               - toma $O(\lg \lg n)$ comparaciones

           * La analisis *en el peor caso*

             - Interaccion.

        4. Variantas

           1. Interpolacion non-lineal

              - en un anuario telefonico o en un diccionario, las
                frecuencias de las letras *no* son uniformes

           2. Busqueda por Interpolacion Mixta con Binaria

              - Se puede buscar en tiempo 
                - $O(\lg n)$ en el peor caso Y
                - $O(\lg \lg n)$ en el caso promedio?

              - Solucion facil

              - Solucion mas compleja

           3. Busqueda por Extrapolacion
              
              - Tarea 3

           4. Busqueda por Extrapolacion Mixta con Doblada

              - Tarea 3

     3) Discussion:

        - Porque todavia estudiar la complejidad en el modelo de comparaciones? 

          - Cuando el peor caso es importante

          - Cuando la distribucion no es uniforme o no es conocida

          - cuando el costo de la evaluacion es mas costo que una
            simple comparacion (en particular para la interpolacion
            non lineal)



4.2.2 Estructuras de Datos de Busqueda 
---------------------------------------
* From Tries to Suffix Arrays 
  + Tries o Arboles Digitales 
    Ordenamos usualmente como pre-computaci{\'o}n para buscar despu\'es. En el
    caso donde n es demasiado grande, ordenar puede ser demasiado
    carro. Consideramos alternativas para buscar.
    
    1. Ejemplo de trie
    
       - Insertar los nodos siguiente en un trie
         - hola
         - holistico
         - holograme
         - hologramas
         - ola
         - ole
    
       - .
         - h
           - o
             - l
                - a \rightarrow hola
                - i \rightarrow holistica
                - o 
                  - g
                    - r
                      - a
                        - m
                          - a
                            - $ \rightarrow holograma
                            - s \rightarrow hologramas
         - o
           - l
             - a \rightarrow ola
             - e \rightarrow ole
    
    2. Búsqueda
    
       - con arreglos de tamaño \sigma en cada nodo: 
         - O(l) tiempo, pero O(L\sigma) espacio
       - con arreglos de tamaño variables en cada nodo:
         - O(l \lg sigma) tiempo (búsqueda binaria),  O(L) espacio
           ({\'o}ptima).
       - con hashing
         - O(l) tiempo en promedio, O(L) espacio.
    
    3. Inserci{\'o}n
    
       - Insertar "hora" en el arbol precedente
         - .
           - h
             - o
               - l
                  - a \rightarrow hola
                  - i \rightarrow holistica
                  - o 
                    - g
                      - r
                        - a
                          - m
                            - a
                              - $ \rightarrow holograma
                              - s \rightarrow hologramas
               - r
                 - a \rightarrow *hora*
           - o
             - l
               - a \rightarrow ola
               - e \rightarrow ole
    
       - Insertar "holistico" en el arbol precedente
         - .
           - h
             - o
               - l
                  - a \rightarrow hola
                  - i
                    - s
                      - t
                        - i
                          - c
                            - a \rightarrow holistica
                            - o \rightarrow holistico
                  - o 
                    - g
                      - r
                        - a
                          - m
                            - a
                              - $ \rightarrow holograma
                              - s \rightarrow hologramas
               - r
                 - a \rightarrow *hora*
           - o
             - l
               - a \rightarrow ola
               - e \rightarrow ole
    
       - Borrar "hola" y "holistica"
         - (TAREA)
         - Tiene de "limpiar", pero no costo mas que un factor
           constante de la búsqueda.
    
    
    
    4. BONUS: PAT Trie
    
       - Comprime las ramas de nodos de grado uno en una sola arista.
       - La caldena ("string") etiquetando la arista se guarda en el
         nodo hijo de la arista.
       - Superio tan en tiempo que en espacio en practica.
    
  + Arboles y Arreglos de Sufijos 
    
    1) Arbol de Sufijos 
    
       - Espacio $O(n)$
    
       - Construcci{\'o}n $O(n)$
    
       - Búsqueda $O(m)$
    
       - expresi{\'o}n regular O(n^\lambda) donde $0\leq \lambda \leq 1$
    
    2) Arreglo de Sufijos
    
       - Lista de sufijos ordenados
       - búsqueda de patrones = dos búsquedas binarias, donde cada
         comparaci{\'o}n costa \leq m, resultando en una complejidad de
         $O(m \lg n)$
    
    
    3) BONUS: Rank en Bitmaps
    
       - $\mathtt{rank}(B,i)$ = cantidad de unos en $B[1,i]$
       - consideramos 
         - $B$ est{\'a}tico
         - se puede almacenar $\lg n$ bits.
    
       - Solucion de Munro, Raman y Raman:
    
         - $b= 1/2 \lg n$   y    $s = \lg^2  n$
    
         - Dividimos el index de $B$ en 
    
           - $s$ Superbloques de tamaño $n/s \lg n$ bits
    
           - $b$ Mini bloques de tamaño $n/b \lg s$ bits
             - $\frac{n}{1/2 \lg n} \lg(\lg^2 n) $
             - $= \frac{4n \llg n}{\lg n}$
             - $\in o(n)$
    
           - un diccionario con todos los bit vectores de tamaño
    
             - $\sqrt{n} \lg n /2 \llg n  \in o(n)$
* Hashing 
  + Introduccion 
    * Motivaciones      
      - Mejor tiempo *en promedio*
      - Uso de todos la herramientas que tenemos
        - dominio de las valores
        - distribuciones de probabilidades de las valores
    * Terminologia 
      - Tabla de Hash
        - Arreglo de tamaño $N$ 
        - que contiene $n$ elementos a dentro de un universo [1..U]
      - Funccion de Hash $h(K)$
        - $h:[1..U] \rightarrow [0..N-1]$
        - se calcula rapidamente
        - distribue uniformemente (mas o menos) las llaves en la tabla
          en el caso ideal, $P[h(K)=i] = 1/N, \, \forall K,i$
      - Collision 
        - cuando $h(K_{1))= h(K_{2})$
        - la probabilidad es alta: "Paradoxe del cumpleanos"
    
        - Cual es la probabilidad que en una pieca de $n$ personas,
          dos tiene la misma fecha de cumpleaños (a dentro de $365$
          dias)?
    
          - probabilidad que cada cumpleaños es unico:
            $ 364! \over {(365 - n)!} \over { 365^{n-1} }$
    
          - Probabilidad que hay al menos un cumpleanos compartido:
            $ 1 - 364! \over {(365 - n)!} \over { 365^{n-1} }$
    
                n      Proba  
             -----+----------
               10        .12  
               23         .5  
               50        .97  
              100   .9999996  
    
  + Hashing Abierto 
    
    1) Idea principal:
       - resolver las colisions con caldenas
    
    2) Ejemplo:  (muy irealistico)
       - $h(K) = K \mod 10$
       - Secuencia de insercion $52,18,70,22,44,38,62$
         - Insertando al final (si hay que probar por repeticiones)
             0         70  
             1             
             2   52,22,62  
             3             
             4         44  
             5             
             6             
             7             
             8      18,38  
             9             
         - Insertando al final (si no hay que probar por repeticiones)
             0         70  
             1             
             2   62,22,52  
             3             
             4         44  
             5             
             6             
             7             
             8      38,18  
             9             
          
    3) Analisis:
    
       - factor de carga es $\lambda= {n \over N}$
       - Rendimiento en el peor caso: $O(n)$
    
    
  + Hashing Cerrado 
    
    1) Idea principal:
       - resolver las colisiones con busqueda, i.e. 
         - $( h(K)+f(i) ) mod N$
       - differentes tipos de busqueda:
         - lineal  $f(i) = i$
           - primary "clustering" (formacion de secuencias largas)           
         - cuadratica $f(i) = i^2$
           - secundario "clustering" (si $h(K_1)=h(K_2)$, la
             secuencias son las mismas.
         - doble hashing $f(i) = i . h'(K)$
           - $h'(K)$ debe ser prima con N
    
    2) Ideal Hashing
    
       - Imagina una funcion de hash que genera una secuencia que
         parece aleatoria.
    
       - cada posicion tiene la misma probabilidad de ser la
         proxima
          - Probabilidad $\lambda$ de elegir una posicion ocupada
          - Probabilidad $1-\lambda$ de elegir une posicion libre
          - la secuencia de prueba puede tocar la misma posicion
            mas que una vez.
          - llaves identicas todavia siguen la misma secuencia.
       - Cual es el costo promedio $u_j$ de una busqueda negativa
         con $j$ llaves en la tabla?
    
         - $\lambda= \frac{j}{N}$
    
         - $u_j = 1 (1-\lambda) + 2\lambda(1-\lambda)+r\lambda^2(1-\lambda)+....$
    
         - $= 1 + \lambda + \lambda^2 + ...$
    
         - $= \frac{1}{1-\lambda}$
    
         - $= \frac{1}{1-j/N}$
    
         - $= \frac{N}{N-j} \in[1..N]$
    
       - Cual es el costo promedio de una busqueda positiva $s_i$
         para el $i$-th elemento insertado?
         
         - $s_i = \frac{1}{1- i/N} = \frac{N}{N-i}$
    
         - $s_n = 1/n \sum \frac{N}{N-i} $
    
         - $= \frac{N}{n} \sum_{i=0}^{n-1} \frac{1}{N-i}$
    
         - $= \frac{1}{\alpha} \sum_{i=0}^{n-1} \frac{1}{N-i}$
           con $\alpha = \frac{n}{N}$
    
         - $< \frac{1}{\alpha} \integral_{N-n}^{N} 1/x dx$
    
         - $= 1/\alpha \ln\frac{N}{N-n}$
    
         - $= 1/\alpha \ln\frac{1}{\alpha}$
    
       - Para $\alpha = 1/2$, el costo promedio es $1.387$
    
       - Para $\alpha = 0.9$, el costo promedio es $2.559$
    
  + Universal Hashing 
    
    - $h(K) = ( (aK+b) \mod p) \mod N$
    - $a \in [1..p-1]$ elegido al azar
    - $b \in [0..p-1]$ elegido al azar
    - $p$ es primo y mas grande que $N$ 
    - $N$ no es necesaramente primo
    
  + Hashing en memoria externa 
    
    1) Que pasa si la tabla de hashing no queda en memoria?
    
       - IDEA: Simula un B-arbol de altura dos
         - organiza el dato con valores de hash
         - guarda un index en el nodo raiz
         - usa solamente *una parte* de la valor de hash para elegir
           el sobre-arbol
         - extiende el index cuando mas dato es agregado
    
    2) Descripci{\'o}n
       
       - $B$ - cantidad de elementos en una pagina
       - $h$ - funcion de hash \rightarrow $[0..2^k-1]$
       - $D$ - *profundidad general*, con $D\leq k$
         - la raiz tiene $2^D$ punteros a las paginas horas
         - la raiz es indexada con los $D$ primeros bits de cada
           valor de hash.
       - $d_l$ - *profundidad local* de cada hora $l$
         - Las valores de hash en $l$ tienen en comun los primeros
           $d_l$ bits.
         - Hay $2^{D-d_l}$ punteros a la hora $l$
         - Siempre, $d_l\leq D$
    
    3) Ejemplo
    
       - $B=4, k=6, D=2$
    
           $d_l=2$   000100  
                     001000  
                     001011  
                     001100  
    
           $d_l=2$   010101  
                     011100  
                             
                             
    
           $d_l=1$   100100  
                     101101  
                     110001  
                     111100  
    
    4) Algoritmos
    
       - Buscar
       - Insertar
       - Remover
    
    5) Analisis
    
       - Buscar, insertar remover
         - 1 acceso a la memoria secundariaa si el index se queda
       - cantidad Promedio de paginas para tener $n$ llaves
         - $\frac{n}{B\lg 2}\approx 1.44 \frac{n}{B}$
         - paginas son llenas a $69\%$ mas o menos.
    
    
    

4.2.3 Algoritmos de Ordenamiento ( Counting Sort, Bucket sort, radix sort, string sort) 
----------------------------------------------------------------------------------------
* Counting Sort   $O(\sigma + n)$ 
  
  1. for j=1 to \sigma do C[j] \leftarrow 0
  2. for i=1 to n do C[A[i]]++
  3. p\leftarrow1 
  4. for j=1 to \sigma do
     - for i=1 to C[j] do
       - A[p++] \leftarrow j
  
       Este algoritmo es bueno para ordenar multi conjuntos (donde
       cada elementos puede ser presente muchas veces), pero pobre
       para diccionarios, para cual es mejor usar la extensi{\'o}n
       l{\'o}gica, Bucket Sort.
  
* Bucket Sort   $O(\sigma+n)$ 
  
  1. for j=1 to \sigma do C[j] \leftarrow 0
  2. for i=1 to n do C[A[i]]++
  3. P[1] \leftarrow 1
  4. for j\leftarrow 2 to \sigma do 
     - P[j] \leftarrow P[j-1] + C[j-1]
  5. for i\leftarrow1 to n
     - B[P[A[i]]++] \leftarrow A[i]
  
  Este algoritmo es particularmente practica para ordenar
  llaves asociadas con objetos, donde dos llaves pueden ser
  asociadas con algunas valores distintas. Nota que el
  ordenamiento es *estable*.
  
* Radix Sort $O(n \lg_n \sigma) = O(c n)$ 
  
  
  - Considera un arreglo A de tamaño n sobre alfabeto $\sigma$
    - si $\sigma=n$, se recuerdan que bucket sort puede
      ordenar A en $O(n)$
    - si $\sigma=n^2$, bucket sort puede ordenar A en $O(n)$:
      - 1 ves con los $\lg n$ bits de la derecha
      - 1 ves con los $\lg n$ bits de la izquierda
        (utilizando la estabilidad de bucket sort)
    - si $|A|=n^c$, bucket sort puede ordenar A 
      - en tiempo $O(cn)$
      - con espacio 2n + \sigma \approx 3n
        (\sigma \approx n a cada iteraci{\'o}n de bucket sort)
  
    El espacio se puede reducir a 2n+\sqrt{n} con \lg n/ 2
    bits a cada iteraci{\'o}n de Bucketsort, cambiando la
    complejidad solamente por un factor de 2.
  
    En final, si $A$ es de tamaño $n$ sobre un alfabeto de
    tamaño $\sigma$, radix sort puede ordenar $A$ en tiempo
    O( n \lceil \frac{\lg \sigma}{\lg n}\rceil )
  
* BONUS Provechando de las repeticiones en el modelo de Comparaciones 
  - Se puede o no?
  
  - Ordenar en $n H_i$ comparaciones
  
* BONUS String Sort 
  
  + Problema: Ordenar $k$ strings sobre alfabeto [\sigma], de
    largo total $n=\sum_i n_i$.
  
  + Si $\sigma \leq k$, y cada string es de mismo tamaño.
  
    - Si utilizamos bucket-sort de la derecha a la izquierda,
      podemos ordenar en tiempo $O(n)$, porque $O(n \lceil \lg
      \sigma/\lg l \rceil )$ y $\sigma<n$.
  
  + Si $\sigma \in O(1)$
  
    - Radix Sort sobre $c$ simboles, donde $c$ es el tamaño
      mínima de una string, y iterar recursivamente sobre el
      restos de la strings mas grande con mismo prefijo.
  
    - En el peor caso, la complejidad corresponde a la suma de
      las superficias de los bloques, aka $O(n)$.
  

4.3 *An{\'a}lisi amortizado* de algoritmos y estructuras de datos 
==================================================================

4.3.1 An{\'a}lisis amortizada 
------------------------------

       * Costo Amortizado:
         - Se tiene una secuencia de n operaciones con costos
           $c_1,c_2,...,c_n$. 
         - Se quiere determinar $C=\sum c_i$.
         - Se puede tomar el peor caso de ci\leq t para tener una
           cota superior de $C\leq t n$.
         - Un mejor an{\'a}lisis puede analizar el costo amortizado,
           con varias t\'ecnicas:
           - an{\'a}lisis agragada
           - contabilidad de costos
           - funci{\'o}n potencial.

       * Ejemplo simple: Incremento binario

          - Incrementar $n$ veces un numero binario de $k$ bits,
          - e.g. desde cero hasta $2^k-1$, con $n=2^k$.
          - costo $\leq k n$   (brute force)
          - costo $\leq n + n/2 + ... \leq 2n$ (costo amortizado)
          - La t\'ecnica usada aquí es la contabilidad de costos:
            - un flip de 0 a 1 cuesta 2
            - un flip de 1 a 0 cuesta 0
            - cada incremento cuesta 2.


       * Funci{\'o}n Potencial para contar el costo

         - $\phi_0 = 0$
         - $\phi_i$ es el tamaño de la bolsa luego de ejecutar $c_1,\ldots,c_i$
         - $\Delta \phi_i = \phi_i - \phi_{i-1}$
         - costo amortizado = $\overline{c_i} = c_i + \Delta\phi_i$
         - $\sum \overline{c_i} = \sum c_i + \phi_n -\phi_0 \geq \sum c_i$

           - Ejemplo : la analisis del algoritmo para min y max al mismo tiempo.

       * En el ejemplo de Incrementacion binaria: 
         - $\phi$ = cantidad de unos en el numero
         - $\phi_0 = 0$
         - $c_i = l+1$ cuando hay $l$ unos
         - $\Delta \phi_i = -l+1$
         - $\sum \overline{c_i} = \sum c_i + \phi_n -\phi_0 
                              \geq 2$

       * Ejemplo: realocaci{\'o}n amortizada

         - considera el tipo "Vector" en Java.
         - de tamaño fijo $n$
         - cuando accede a $n+1$, crea un otro arreglo de tamaño $2n$, y
           copia todo.
         - cual es el costo amortizado si agregando elementos uno a
           uno?



4.3.2 Colas de Prioridades 
---------------------------

         * REFERENCIAS:  
           - [http://www.leekillough.com/heaps/]
         
         * Problema: Dado un conjunto (din{\'a}mica) de $n$ tareas con
           valores, elegir y remudar la tarea de valor m{\'a}xima.

         * operaciones b{\'a}sicas:
           - M.build({e1,e2,...,2n})
           - M.insert(e)
           - M.min
           - M.deleteMin

         * operaciones adicionales ("Addressable priority queues")
           - M.insert(e), volviendo un puntero h ("handle") al elemento insertado
           - M.remove(h), remudando el elemento especificado para h
           - M.decreaseKey(h,k), reduciendo la llave del elemento especificado para h
           - M.merge(Q), agregando el heap Q al heap M.
            
         * Soluciones (conocidas o no):

                Linked List   Binary Tree     (Min-)Heap      Fibonacci Heap   Brodal Queue [1]  
 -------------+-------------+---------------+---------------+----------------+------------------
  insert        $O(1)$          O(log n)        O(log n)        $O(1)$             $O(1)$              
  accessmin     $O(n)$          $O(1)$            $O(1)$            $O(1)$             $O(1)$              
  deletemin     $O(n)$          O(log n)        O(log n)        O(log n)*        O(log n)          
  decreasekey   $O(1)$          O(log n)        O(log n)        $O(1)$*            $O(1)$              
  delete        $O(n)$          $O(n)$            O(log n)        O(log n)*        O(log n)          
  merge         $O(1)$          O(m log(n+m))   O(m log(n+m))   $O(1)$             $O(1)$              


      1) Colas de prioridades binarias ("Binary Heaps")

         * La soluci{\'o}n tradicional 
           - un arreglo de n elementos
           - hijos del nodo i en posiciones 2i y 2i+1
           - la valor de cada nodo es mas pequeña que las valores de su hijos.

         * Complejidad: Espacio n+O(1), y 
             Operaci{\'o}n                 Tiempo    
            -------------------------+----------
             M.build({e1,e2,...,2n})   $O(n)$      
             M.insert(e)               O(\lg n)  
             M.min                     $O(1)$      
             M.deleteMin               O(\lg n)  

         * Detalles de implementacion (mejorando las constantes)

           - Cuidado de no implementar M.build({e1,e2,...,2n}) con n
             inserciones (sift up \rightarrow $O(n\lg n)$), pero con $n/2$
             sift-down (\rightarrow $O(n)$).

           - En M.deleteMin(), algunas variantes de implementaci{\'o}n
             (despu\'es de cambiar el min con A[n]):
             1. dos comparaciones en cada nivel hasta encontrar la
                posici{\'o}n final de A[n] 
                - 2\lg n comparaciones en el peor caso
                - \lg n copias
             2. una comparaci{\'o}n en cada nivel para definir un camino
                de tamaño lg n, y una búsqueda binaria para encontrar
                la posici{\'o}n final
                - \lg n + O(\lg \lg n) comparaciones en el peor caso
                - \lg n copias en el peor caso
             3. una comparaci{\'o}n en cada nivel para definir un camino
                de tamaño lg n, y una búsqueda *secuencial* up para encontrar
                la posici{\'o}n final
                - 2\lg n  comparaciones en el peor caso
                - \lg n copias en el peor caso
                - pero en practica y promedio mucho mejor.


         * Flexibilidad de estructuras
           + Porque la complejidad es mejor con un heap que con un
             arreglo ordenado?
             - Para cada conjunto, hay solamente un arreglo ordenado
               que puede representarlo, pero muchos heaps posibles:
               eso da mas flexibilidad para la mantenci{\'o}n din{\'a}mica de
               la estructura de datos.

           + Colas de prioridades con punteros ("Addressable priority queues")
             - Algún que mas flexible que los arreglos ordenados, las
               colas de prioridades binarias todavía son de estructura
               muy estricta, por ejemplo para la union de
               filas. Estructuras mas flexibles consideran un "bosque"
               de arboles. Adem{\'a}s, estas estructuras de arboles son
               implementadas con puntadores (en ves de implementarlos
               en arreglos).
             - Hay diferentes variantes. Todas tienen en común los
               puntos siguientes:
               - un puntero *minPtr* indica el nodo de valor mínima
                 en el bosque, raíz de alguno arbol.
               - *insert* agregas un nuevo arbol al bosque en tiempo $O(1)$
               - *deleteMin* remudas el nodo indicado par minPtr,
                 dividiendo su arbol en dos nuevos arboles. Buscamos
                 para el nuevo min y fusionamos algunos arboles (los
                 detalles diferencian las variantes)
               - *decreaseKey(h,k)* es implementado cortando el arbol
                 al nodo indicado por h, y rebalanceando el arbol
                 cortado.
               - *delete()* es reducido a *decreaseKey(h,0)* y
                 *deleteMin*

      2) "Pairing Heaps"
         
         - Malo rendimiento en el peor caso, pero bastante buena en
           practica.

         - rebalancea los arboles solamente en deleteMin, y solamente
           con pares de raises (i.e. la cantidad de arboles es
           reducida por dos a cada deleteMin).

             Operaci{\'o}n   Amortizado                  
            ------------------+----------------------------
             Insert(C,x)        $O(1)$                      
             Merge              $O(1)$                      
             ExtractMin         $O(\lg n)$                  
             decreaseKey(h,k)   $\Omega(n \lg n \lg\lg n)$  


      3) Colas de prioridades binomiales ("Binomial Heaps")

         [http://en.wikipedia.org/wiki/Binomial_heap]
         o p136 de Melhorn y Sanders

         * Definici{\'o}n
           - Un *arbol binomial* (de orden $k$) tiene exactamente $k$
             hijos de orden distintos $k-1,k-2,..., 0$. [Un arbol
             binomial de orden 0 tiene 0 hijos.]
           - Un *bosque binomial* es un conjunto de arboles binomiales
             de orden *distintas* (i.e. hay cero o uno arboles de cada
             orden).

         * Propiedades
           - Para cada arbol $T$
             - $h(T) \leq lg |T|$
             - $|T| \geq 2^{h(T)}$
           - Para el bosque
             - \forall n hay solamente uno bosque binomial con n nodos.
             - al m{\'a}xima tiene $\lfloor \lg (n+1) \rfloor$ arboles.
             - la descomposici{\'o}n del bosque en arboles de orden k
               corresponde a la descomposici{\'o}n de n en base de dos.

         * Definici{\'o}n
           - una *cola binomial* es un bosque binomial donde cada nodo
             almacena una clave, y siempre la clave de un padre es
             inferior o igual a la clave de un hijo.

         * Operaciones
             Operaci{\'o}n   Peor Caso   
            ------------------+------------
             Merge              $O(\lg n)$  
             FindMin            $O(\lg n)$  
             ExtractMin         $O(\lg n)$  
             Insert(C,x)        $O(\lg n)$  
             Heapify            $O(n)$      
            ------------------+------------
             remove(h)          $O(\lg n)$  
             decreaseKey(h,k)   $O(\lg n)$  
             merge(Q)           $O(\lg n)$  

         * Union

           - Union de dos arboles binomiales de mismo orden:
             - agrega $T_2$ a $T_1$ si $T_1$ tiene la raíz mas pequeña.
           - Union de dos bosques binomiales:
             - si hay uno arbol de orden $k$, es lo de la union
             - si hay dos arboles de orden $k$, calcula la union en un arbol de orden $k+1$
             - la propagaci{\'o}n es similar a la suma de enteros en binario.

           - Complejidad 
             - $O(\lg n)$ en el peor caso 

         * Insert
           - agrega un arbol de orden 0 y hace la union si necesitado
           - Complejidad $O(\lg n)$ en el peor caso
           - Puede ser $O(1)$ sin corregir el bosque, que tiene de ser
             corregido mas tarde, que puede ser en tiempo $O(n)$ peor
             caso, pero sera $O(\lg n)$ en tiempo amortizado.

         * Mínima
           - leí la lista de al m{\'a}xima $\lfloor \lg (n+1) \rfloor$ raíces
           - Complejidad $O(\lg n)$
           - Puede ser $O(1)$ si precalculando un puntero al mínima, que
             tiene de ser corregido (en tiempo $O(\lg n))$ a cada modificaci{\'o}n.

         * DeleteMin
           - encontra el min
           - remuda el min de su arbol (la raíz)
           - reordena su hijos para su orden, en un bosque binomial
           - hace la union con el bosque binomial original, menos el arbol del min
           - complejidad $O(\lg n)$

         * DecreaseKey
           - sigue el camino abajo hasta que la condici{\'o}n del heap es
             corregida.
           - cada arbol tiene altura lg n, entonces la complejidad es
             $O(\lg n)$ en el peor caso.

         * Delete 
           - reducido a DecreaseKey+DeleteMin
        


      4) Colas de prioridades de Fibonacci ("Fibonacci Heaps")

         [http://en.wikipedia.org/wiki/Fibonacci_heap] o pagina 135 de
         Melhorn y Sanders.


         * Diferencia con la cola binomial:

           - relax la estructura de los arboles (heap-forma), pero de
             forma controlada.
           - el tamaño de un sub-arbol cual raíz tiene $k$ hijos es al
             m{\'a}xima $F_k+2$, donde $F_k$ es el $k$-\'esimo numero de
             Fibonacci.

         * Operaciones
             Operaci{\'o}n   Peor Caso    Amortizado  
            ------------------+------------+------------
             Merge              $O(\lg n)$   $O(1)$        
             FindMin            $O(\lg n)$   $O(1)$        
             ExtractMin         $O(\lg n)$   .           
             Insert(C,x)        $O(\lg n)$   $O(1)$        
             Heapify            $O(n)$         .           
            ------------------+------------+------------
             remove(h)          $O(\lg n)$   .           
             decreaseKey(h,k)   $O(\lg n)$   $O(1)$        
             merge(Q)           $O(\lg n)$   $O(1)$        

      5) Overview
         (copy de [http://en.wikipedia.org/wiki/Fibonacci_heap])


                           Linked List   Binary Tree     (Min-)Heap      Fibonacci Heap   Brodal Queue [1]  
            -------------+-------------+---------------+---------------+----------------+------------------
             insert        $O(1)$          O(log n)        O(log n)        $O(1)$             $O(1)$              
             accessmin     $O(n)$          $O(1)$            $O(1)$            $O(1)$             $O(1)$              
             deletemin     $O(n)$          O(log n)        O(log n)        O(log n)*        O(log n)          
             decreasekey   $O(1)$          O(log n)        O(log n)        $O(1)$*            $O(1)$              
             delete        $O(n)$          $O(n)$            O(log n)        O(log n)*        O(log n)          
             merge         $O(1)$          O(m log(n+m))   O(m log(n+m))   $O(1)$             $O(1)$              

      6) BONUS Heapsort

         - in place
         - O(n lg n) con cualquiera de estas variantes.


4.4 *Algoritmos en línea*. Competividad. Adaptividad. 
=============================================================

4.4.1 List Accessing 
---------------------

     REFERENCIA: Capitulo 1 en "Online Computation and Competitive
     Analysis", de Allan Borodin y Ran El-Yaniv

     1) "List Accessing"

        - Considera la secuencia de búsqueda de tamaño $n$, en un
          diccionario de tamaño $\sigma$:
          "1,1,1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,..."

        - Cual es el rendimiento de una estructura de diccionario
          *est{\'a}tica* (tal que AVL) en este secuencia?
          - $n\lg\sigma$
          
        - Se puede mejorar?
          - si, utilizando la *localidad* de las consultas, en
            *estructuras de datos din{\'a}micas*.

     2) Soluciones

        1. MTF ("Move To Front"): 
           - pone las llaves en un arreglo desordenado
           - buscas secuencialmente en el arreglo
           - muda la llave encontrada en frente
        2. TRANS ("Transpose"):
           - pone las llaves en un arreglo desordenado
           - buscas secuencialmente en el arreglo
           - muda la llave encontrada de una posici{\'o}n mas cerca del  frente
        3. FC ("Frequency Count"):
           - mantiene un contador para la frecuencia de cada elemento
           - mantiene la lista ordenada para frecuencia decreciente.

        4. Splay Trees (y otras estructuras con propiedades de localidad)
           ([http://www.dcc.uchile.cl/~cc30a/apuntes/Diccionario/#8b])


     3) Estos son "Algoritmos en Linea"
        - algoritmo de optimizaci{\'o}n
        - que conoce solamente una parte de la entrada al tiempo t.
        - se compara a la competitividad con el algoritmo offline que
          conoce toda la instancia.

        - Como se puede medir su complejidad?
          - cada algoritmo ejecuta $O(n)$ comparaciones para cada
            búsqueda en el peor caso!!!!
          - tiene de considerar instancies "f{\'a}ciles" y "difíciles"
          - una medida de dificultad
          - e.g. el rendimiento del *mejor algoritmo "offline"*


     4) Competitive Analysis: instancias "difíciles" o "f{\'a}ciles"

        - Las estructuras de datos din{\'a}micas pueden aprovechar de
          secuencias "f{\'a}ciles" de consultas: eso se llama "online".

        - pero para muchos problemas online, todas las heurísticas se
          comportan de la misma manera en el peor caso.

        - Por eso se identifica una medida de dificultad de las
          instancias, y se comparan los rendimientos de los
          algoritmos sobre instancias que tienen una valor fijada de
          este medida de dificultad.

        - Tradicionalmente, esta medida de dificultad es el
          rendimiento del mejor algoritmo "offline": eso se llama
          *competitive analysis*, resultando en el *competitive
          ratio*, el ratio entre la complejidad del algoritmo ONLINE
          y la complejidad del mejor algoritmo OFFLINE.

          - por ejemplo, veamos que MTF tiene un competitive ratio de
            2

        - Pero todavía hay algoritmos con performancia practicas muy
          distintas que tienen el mismo competitive ratio. Por eso se
          introduce otras medidas de dificultadas mas sofisticadas, y
          mas especialidades en cada problema.

     5) Competitividad

        * Optimizaci{\'o}n/aproximaci{\'o}n

          - A es *k(n) competitiva*  para un problema de *minimizaci{\'o}n* si
            - \exist b, \forall n,x |x|=n
              - C_A(x) - k(n) C_{OPT}(x) \leq b

          - A es *k(n) competitiva*  para un problema de *maximizaci{\'o}n* si
            - \exist b, \forall n,x |x|=n
              - C_{OPT}(x) - k(n) C_{A}(x) \leq b

        * Competitiva Ratio

          - an algoritmo en linea es *c-competitiva* si
            - \exists \alpha, \forall I 
              - ALG(I) \leq c OPT(I) + \alpha

          - an algoritmo en linea es *estrictamente c-competitiva* si
            - \forall I 
              - ALG(I) \leq c OPT(I) 

     6) Sleator-Tarjan sobre MTF

          - costo de una búsqueda negativa (la llave NO esta en el
            diccionario)
            - $\sigma$
          - costo de una búsqueda positiva (la llave esta en el
            diccionario)
            - la posici{\'o}n de la llave, no mas que $\sigma$
            - en promedio para una distribuci{\'o}n de probabilidad fijada:
              - $MTF \leq 2 OPT$, 
            - Prueba: (from my notes in my CS240 slides)

              How does MTF compare to the optimal ordering?            
              - Assume that:
                - the keys $k_1,\ldots,k_n$ have probabilities 
                  $p_1 \ge p_2 \ge \ldots \ge p_n \ge 0$
                - the list is used sufficiently to reach a steady state.
              - Then: 
                $$C_{MTF} < 2\cdot C_{OPT}$$
              - Proof:
                \begin{eqnarray*}
                C_{OPT} & = & \sum_{j=1}^{n} jp_j 
                C_{MTF} & = & \sum_{j=1}^{n} p_j(\mbox{cost of finding $k_j$}) 
                & = & \sum_{j=1}^{n} p_j(1+\alert{\mbox{number of keys before } k_j})
                \end{eqnarray*}
 
                - To compute the average number of keys before $k_j$:
                  \begin{eqnarray*}
                  \Pr[\mbox{ $k_i$ before $k_j$}] &=& \frac{p_i}{p_i+p_j} 
                  E(\mbox{ \alert{number of keys before $k_j$}}) &=&
                  \sum_{i\neq j} \frac{p_i}{p_i+p_j} 
                  \end{eqnarray*}

                - $k_i$ is before $k_j$ if and only if
                  $k_i$ was accessed more recently than $k_j$. 

                - Consider the last time either $k_i$ or $k_j$ was looked up. What is the probability that it was $k_i$?
                  \begin{eqnarray*}
                  P(k_i \textrm{ before } k_j) &=
                  %& P(k_i \textrm{ chosen }|\ k_i \textrm{ or }k_j\textrm{ chosen }) \\ &=
                  & \frac{P(k_i \textrm{ chosen })}{P(k_i \textrm{ or } k_j \textrm{ chosen })} 
                  &=& \frac{p_i}{p_i+p_j}
                  \end{eqnarray*}

                - Therefore,
                  \begin{eqnarray*}
                  C_{MTF} & = & \sum_{j=1}^{n} p_j (1+\sum_{i\not = j} \frac{p_i}{p_i+p_j}) 
                  \mbox{\hspace{.5cm} (Joining both previous formulas.)}
                  
                  & = & 1 + 2 \sum_{j=1}^n \sum_{i<j} \frac{p_i p_j }{p_i+p_j} 
                  \mbox{\hspace{1cm} (By reordering the terms.)}
                  
                  & \leq &  1 + 2 \sum_{j=1}^n p_j (\sum_{i<j} 1) 
                  \mbox{\hspace{2cm} (Because $\frac{p_i}{p_i+p_j}\leq1$.)}
                  
                  & = & 1 +  2 \sum_{j=1}^n p_j (j-1) 
                  
                  & = & 1 + 2C_{OPT} + 2 \sum_{j=1}^n(-p_j) 
                  
                  & = & 2C_{OPT}-1.
                  \mbox{\hspace{3cm} (Because $\sum_{j=1}^n(p_j)=1$.) \qedhere}
                  \end{eqnarray*}  



     7) [BONUS] Applicaciones a la compression de textos
                  

        * [Bentley, Sleator, Tarjan and Wei] proponieron de
          comprimir un texto utilizando una lista din{\'a}mica, donde el
          c{\'o}digo para un símbolo es la posici{\'o}n del símbolo en la
          lista.

          - Experimentalmente, se compara a Huffman:
            - a veces mucho mejor
            - nunca mucho peor.

        * [Burrows and Wheeler] proponieron una transformaci{\'o}n
          (biyectiva) del texto, y de comprimir el resultado de esta
          transformaci{\'o}n con MTF

          - Experimentalmente, 6% mejor que GZip, que es enorme!

4.4.2 Paginamiento Deterministico 
----------------------------------

     REFERENCIA: Capitulo 2 en "Online Computation and Competitive
     Analysis", de Allan Borodin y Ran El-Yaniv
     
     1) Paginamiento

        - Definici{\'o}n:
          - elegir cual paginas guardar en memoria, dado
            - una secuencia online de $n$ consultas para paginas, y
            - un cache de $k$ paginas.
        - Políticas:     
          - LRU (Least Recently Used)
          - CLOCK (1bit LRU)
          - FIFO (First In First Out)
          - LFU (Least Frequently Used)
          - LIFO = MRU (Most Recently Used)
          - FWF (Flush When Full)
          - LFD (Offline, Longuest Forward Distance)

        - Ustedes tienen una idea de cuales son las peores/mejores?

     2) Relaci{\'o}n con "List Accessing"

        1. Cada "List accessing" algoritmo corresponde a un algoritmo
           de paginamiento:
           - cada miss, borra el ultimo elemento de la lista y
             "inserta" el nuevo elemento.
        2. No hay una reducci{\'o}n tan clara en la otra direcci{\'o}n.


     3) Offline analysis

        - LFD performa O(n/k) misses
        - Cualquier algoritmo Offline performa Omega(n/k) en el peor
          caso.

     4) Online an{\'a}lisis: resultados b{\'a}sicos

        1. $\forall A$ online, hay una entrada con $n$ fallas.

           - Estrategia de adversario.

        2. No algoritmo online puede ser mejor que $k$ competitivo.

           - Obvio, comparando con LFD.

        3. MRU=LIFO NO es competitivo
           - Considera S=
             p_1,p_2,\ldots,p_k,p_{k+1},p_k,p_{k+1},p_k,p_{k+1},p_k,...
           - despu\'es las k primeras consultas, MRU va a tener un miss
             cada consulta, cuando LFD nunca mas.

        4. LFU no es competitivo 
           - Considera l>0 y S=
             p_1^l,p_2^l,\ldots,p_{k-1}^l,(p_k,p_{k+1})^{l-1}
           - Despu\'es de las (k-1)l primeras consultas, LFU va a tener
             un miss cada consulta, cuando LFD solamente dos.

        5. Que tal de FWF?

           - MRU=LIFO es un poco estúpido, su mala rendimiento no es
             una sorpresa.

           - FWF es un algoritmo muy ingenuo tambi\'en, pero vamos a
             ver que no tiene un rendimiento tan mal "en teoría".

     5) BONUS: Competive Analysis: Algoritmos a Marcas

        1. $k$-fases particiones

           Para cada secuencia $S$, partitionala en secuencias
           $S_1,\ldots,S_\delta$ tal que 
           - $S_0 = \emptyset$
           - $S_i$ es la secuencia Maxima despu\'es de $S_{i-1}$ que
             contiene al m{\'a}ximum $k$ consultas distintas.

           - Llamamos "fase $i$" el tiempo que el algoritmo considera
             elementos de la subsecuencia $S_i$.
           - Nota que eso es independiente del algoritmo considerado.

        2. Algoritmo con marcas 

           - agrega a cada pagina de memoria lenta un bit de marca.

           - al inicio de cada fase, remuda las marcas de cada
             pagina en memoria.

           - a dentro de una fase, marca una pagina la primera vez
             que es consultada.

           - un algoritmo a marca ("marking algorithm") es un
             algoritmo que nunca remuda una pagina marcada de su
             cache.

        3. Un algoritmo con marcas es $k$-competitiva

           - En cada fase, 
             - un algoritmo ONLINE con marcas performa al m{\'a}ximum $k$ miss.
             - Un algoritmo OFFLINE (e.g. LFD) performa al mínimum
               $1$ miss.
           - QED

        4. LRU, CLOCK y FWF son  algoritmos con marcas

        5. LRU, CLOCK y FWF tienen un ratio competitivo {\'O}PTIMO


     6) Mas resultados:

        1. La an{\'a}lisis se puede generalizar al caso donde el
           algoritmo offline tiene h paginas, y el algoritmo online
           tiene $k\geq h$ paginas.

           - Cada algoritmo *con marcas* es
             $\frac{k}{k-h+1}$-competitiva.

        2. Definici{\'o}n de algoritmos (conservadores) da resultado
           similar para FIFO (que no es con marcas pero es
           conservador).

        4. En practica, sabemos que LRU es mucho mejor que FWF (for
           instancia). Había mucha investigaci{\'o}n para intentar de
           mejorar la an{\'a}lisis por 20 anos, ahora parece que hay una
           an{\'a}lisis que explica la mejor rendimiento de LRU sobre
           FWF, y de variantes de LRU que pueden saber $x$ pasos en
           el futuro (Reza Dorrigiv y Alex Lopez-Ortiz).



4.5 Conclusion Unidad 3 
========================
  * Resultados de Aprendisajes de la Unidad
        - Comprender las tecnicas de algoritmos de 
          - costo amortizado, 
          - uso de finitud, y 
          - algorimos competitivos
        - Ser capaz de diseñar y analzar algoritmos y estructuras de
          datos basados en estos principios.
        - conocer algunos casos de estudio relevantes
  * Principales casos de estudio: 
         - estructuras para union-find, 
         - colas binomiales
         - splay trees,
         - búsqueda por interpolacíon
         - radix sort
         - {\'a}rboles de van Emde Boas
         - {\'a}rboles de sufijos
         - t\'ecnica de los cuatro rusos,
         - paginamiento
         - búsqueda no acotada (unbounded search, doubling search)

5 4. Algoritmos no convencionales (5 semanas = 10 charlas) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

5.1 Descripcion de la Unidad 
=============================

5.1.1 Resultados de Aprendisajes de la Unidad 
----------------------------------------------
     - Comprender el concepto de algoritmos 
       - aleatorizados, 
       - probabilísticos, 
       - aproximados
       - paralelos
     - y cuando son relevantes
     - ser capaz de diseñar y analizar algoritmos de estos tipos
     - Conocer algunos casos de estudio relevantes

5.1.2 Principales casos de estudio: 
------------------------------------
     - primalidad
     - Karp Rabin para búsqueda en strings
     - número mayoritario
     - {\'a}rboles binarios de búsqueda aleatorizados 
     - quicksort
     - hashing universal y perfecto
     - aproximaciones para recubrimiento de v\'ertices
     - vendedor viajero
     - mochila
     - ordenamiento paralelo
     - paralel prefix

5.2 *Aleatorizacion* (1 semana = 2 charlas) 
============================================
[2010-10-14 Thu]--[2010-10-19 Tue]

  * REFERENCIA: 
    - Capitulo 1 en "Randomized Algorithms", de Rajeev Motwani and Prabhakar Raghavan.

5.2.1 Definiciones 
-------------------

       - *Algoritmos deterministico*
         - algoritmo que usa solamente instrucciones
           *deterministicas*. 
         - algoritmo de cual la ejecucion (y, entonces, el
           rendimiento) depende solamente del input.

       - *Algoritmos aleatorizados*
         - algoritmo que usa una instruccion *aleatorizada*
           (potentialemente muchas veces)
         - una distribucion de probabilidades sobre una familia de
           algoritmos deterministicos.

       - *An{\'a}lisis probabilistica*
         - analysis del rendimiento de un algoritmo, en promedio
           sobre
           - el aleatorio de la entrada, o 
           - el aleatorio del algoritmo, o 
           - los dos.
         - veamos que son nociones equivalentes.


5.2.2 El poder de un algoritmo aleatorizado 
--------------------------------------------
  - Nota: Trae los juguetes/cajas de colores, con un tesoro a esconder a dentro.

     Ejemplos de algoritmos o estructuras de datos aleatorizados

        1. *hidden coin*
           - Decidir si un elemento pertenece en un lista
             desordenada de tamaño k, o si hay una moneda a dentro
             de una de las $k$ caja.
           - cual son las complejidades determinisitica y
             aleatorizada del problema de encontrar *una* moneda,
             con $c$ la cantidad de monedas,
             - si $c=1$?
             - si $c=n-1$?
             - si $c=n/2$?
           - Respuestas:
             - Si una sola instancia de la valor buscada
               - k en el peor caso deterministico
               - k/2 en (promedio y en) el peor caso aleatorio
                 - con una direcci{\'o}n al azar
                 - con lg(k!) bits aleatorios
             - Si r instancias de la valor buscada
               - k-r en el peor caso deterministico
               - O(k/r) en (promedio y en) el peor caso aleatorio
        3. Decidir si un elemento pertenece en una lista ordenadas
           de tamaño n
           * \Theta(\lg n) comparaciones en ambos casos,
             deterministico y probabilístico.
        4. *problema de union* 
           * Decidir si un elemento pertenece en una de las k listas
             ordenadas de tamaño n
           * Si una sola lista contiene la valor buscada
             - k búsquedas en el peor caso deterministico, que da
               k\lg(n) comparaciones
             - k/2 búsquedas en (promedio y en) el peor caso
               aleatorio, que da k\lg(n)/2 comparaciones
           * Si r<k listas contienen la valor buscada
             - k-r búsquedas en el peor caso deterministico, que dan
               (k-r)\lg(n) comparaciones
             - k/r búsquedas en (promedio y en) el peor caso
               aleatorio, que dan (k/r)\lg(n) comparaciones
           * Si r=k listas contienen la valor buscada
             - k búsquedas en el peor caso deterministico, en
               promedio y en el peor caso aleatorio, que dan k\lg n
               comparaciones

        5. *problema de interseccion*
           - dado $k$ arreglos ordenados de tamaño $n$ cada uno, y un
             elemento $x$.
           - cual son las complejidades determinisitica y aleatorizada
             del problema de encontrar *un* arreglo que no contiene
             $x$ (i.e. mostrar que la interseccion de {x} con \cap A
             es vacilla)? 
             - si $c=1$ arreglo contiene $x$?
             - si $c=n-1$ arreglos contienen $x$?
             - si $c=n/2$ arreglos contienen $x$?

               $c$     deterministica   aleatorizada                      
              -------+----------------+--------------+-------------------
               $1$     2\lg n           < 2\lg n                          
               $k-1$   k\lg n           < (k-1)\lg n                      
               $k/2$   (k/2+1)\lg n     < 2\lg n       HUGE IMPROVEMENT!  
              -------+----------------+--------------+-------------------
               $c$     (c+1)\lg n       <                                 

        6. Eso se puede aplicar a la intersecci{\'o}n de posting lists
           (Google Queries).



5.2.3 Aleatorizacion de la entrada 
-----------------------------------

     * Independencia de la distribucion  de la entrada

       - Si el input sigue una distribucion non-conocida, el input
         perturbado tiene una distribucion conocida (para una
         perturbacion bien elegida)

       - Ejemplo:
         - flip $b$ de una bit con probabilidad $p$ que puede ser
           distinta de $1/2$.
         - suma-lo modulo 1 con un otro bit aleatorizado, con
           probabilidad $1/2$ de ser uno.
         - la suma es igual a uno con probabilidad $1/2$.

     * Estructuras de datos aleatorizadas

        - *funciones de hash*:
          - estructura de datos aleatorizada, 
          - donde (a,b) son elegidos al azar.

        - *skiplists*
          - estructura de datos aleatorizada, 
          - que simula en promedio un arbol binario



* SkipLists 
  
  1) Estructuras de datos para diccionarios
  
   - [X] Arreglo ordenado
   - [ ] "Move To Front" list (did they see it already?)
   - [X] Arboles binarios
   - [X] Arboles binarios aleatorizados
   - [X] Arboles 2-3   ( they saw it already?)
   - [X] Red-Black Trees  ( they saw it already?)
   - [X] AVL
   - [X] Skip List 
   - [ ] Splay trees
  
  2) Skip Lists
  
     1. Motivaci{\'o}n
        - un arbol binario con entradas aleatorizadas tienen una
          altura $O(\lg n)$, pero eso supone un orden de input
          aleatorizados.
        - El objetivo de las "skip lists" es de poner el aleatorio
          a dentro de la estructura.
        - tambi\'en, es el equivalente de una búsqueda binaria en
          listas via un resumen de resumen de resumen...
  
     2. Definici{\'o}n 
        
        - una skip-list de altura $h$ para un diccionario $D$ de
          $n$ elementos es una familia de lists $S_0,\ldots,S_h$ y
          un puntero al primero elemento de $S_h$, tal que
  
          - $S_0$ contiene $D$;
          - cada $S_i$ contiene un subconjunto aleatorio de $S_{i-1}$
            (en promedio la mitad) 
          - se puede navegar de la izquierda a la derecha, y de la
            cima hasta abajo.
  
        - se puede ver como $n$ torres de altura aleatorizadas,
          conectadas horizontalmente con punteros de la
          izquierda a la derecha.
  
        - la informaci{\'o}n del diccionario est{\'a}n solamente en S_0 (no
          se duplica)
  
     3. Ejemplo
  
        4   X         -    -    -    -    -    -    \rightarrow   X       
        3   X         -    \rightarrow   X    -    -    -    \rightarrow   X       
        2   X         -    \rightarrow   X    X    \rightarrow   X    \rightarrow   X       
        1   X         X    \rightarrow   X    X    \rightarrow   X    \rightarrow   X       
        0   X         X    X    X    X    X    X    X    X       
       ---+---------+----+----+----+----+----+----+----+--------
            -\infty   10   20   30   40   50   60   70   \infty  
  
     4. Operaciones
  
        * Search(x): 
          - Start a the first element of $S_h$
          - while not in $S_0$
            - go down one level
            - go right till finding a key larger than x
  
        * Insert(x)
          - Search(x)
          - create a tower of random height (p=1/2 to increase
            height, typically)
          - insert it in all the lists it cuts.
  
        * Delete(x)
          - Search(x)
          - remove tower from all lists.
  
     5. Ejemplos 
  
        * Insert(55) con secuencia aleatora (1,0)
  
        4   X         -    -    -    -    -      -      -    \rightarrow   X       
        3   X         -    \rightarrow   X    -    -      -      -    \rightarrow   X       
        2   X         -    \rightarrow   X    X    -      \rightarrow     X    \rightarrow   X       
        1   X         X    \rightarrow   X    X    *\rightarrow*   *X*    X    \rightarrow   X       
        0   X         X    X    X    X    X      *X*    X    X    X       
       ---+---------+----+----+----+----+------+------+----+----+--------
            -\infty   10   20   30   40   50     *55*   60   70   \infty  
  
        * Insert(25) con (1,1,1,1,0)
  
        5   *X*       -    -      -      -    -    -    -    -    *\rightarrow*   *X*     
        4   X         -    *\rightarrow*   *X*    -    -    -    -    -    \rightarrow     X       
        3   X         -    *\rightarrow*   *X*    X    -    -    -    -    \rightarrow     X       
        2   X         -    *\rightarrow*   *X*    X    X    -    \rightarrow   X    \rightarrow     X       
        1   X         X    *\rightarrow*   *X*    X    X    \rightarrow   X    X    \rightarrow     X       
        0   X         X    X      *X*    X    X    X    X    X    X      X       
       ---+---------+----+------+------+----+----+----+----+----+------+--------
            -\infty   10   20     *25*   30   40   50   55   60   70     \infty  
  
        * Delete(60) 
  
  
        5   X         -    -    -    -    -    -    -    \rightarrow     X       
        4   X         -    \rightarrow   X    -    -    -    -    \rightarrow     X       
        3   X         -    \rightarrow   X    X    -    -    -    \rightarrow     X       
        2   X         -    \rightarrow   X    X    X    -    -    *\rightarrow*   X       
        1   X         X    \rightarrow   X    X    X    \rightarrow   X    \rightarrow     X       
        0   X         X    X    X    X    X    X    X    X      X       
       ---+---------+----+----+----+----+----+----+----+------+--------
            -\infty   10   20   25   30   40   50   55   70     \infty  
  
     6. Analisis
  
        * Espacio: Cuanto nodos en promedio?
          - cuanto nodos en lista S_i?
            - $n/2^i$ en promedio
          - Summa sobre todos los niveles
            - $n \sum 1/2^i < 2n$
  
        * Tiempo: 
          - altura promedio es O(\lg n)
          - tiempo promedio es O(\lg n)
  
  
  + Paginamiento al Azar :OPTIONAL:
    - REFERENCIA: 
      - Capitulo 3 en "Online Computation and Competitive Analysis", de
        Allan Borodin y Ran El-Yaniv
      - Capitulo 13 en "Randomized Algorithms", de Rajeev Motwani and
        Prabhakar Raghavan, p. 368
    
    
    1) Tipos de Adversarios (cf p372 [Motwani Raghavan]
    
       * Veamos en el caso deterministico un tipo de adversario
         offline, como medida de dificultad para las instancias online.
         Para el problema de paginamiento con k paginas, el ratio
         {\'o}ptima entre un algoritmo online y offline es de $k$
         (e.g. entre LRU y LFD).
       
       * DEFINICI{\'O}N: 
    
         En el caso aleatorizado, se puede considerar mas tipos de
         adversarios, cada uno definiendo una medida de dificultad y
         un modelo de complejidad.
    
         1. Adversario "Oblivious" ("Oblivious Adversary")
    
            El adversario conoce $A$ pero no $R$: el elija su instancia
            completamente al inicial, antes de la ejecuci{\'o}n online del
            algoritmo.
    
         2. Adversario Offline adaptativo
    
            Para este definici{\'o}n, es mas f{\'a}cil de pensar a un
            adversario como un agente distinto del algoritmo offline
            con quien se compara el algoritmo online.
    
            El adversario conoce $A$ en total, pero $R$ online, y le
            utiliza para generar una instancia peor $I$. Este instancia
            $I$ es utilizada de nuevo para ejecutar el algoritmo
            offline (quien conoce el futuro) y producir las
            complejidades (a cada instante online) con cual comparar la
            complejidad del algoritmo online.
    
         3. Adversario Online adaptativo
    
            En este definici{\'o}n, el algoritmo conoce $A$ en total,
            construir la instancia $I$ online como en el caso
            precedente, pero tiene de tiene de resolverla online tambi\'en
            (de una manera, no se ve en el futuro).
    
       * Comparaci{\'o}n de los Tipos de adversarios.
    
         - Por las definiciones, es claro que 
           - el adversario offline adaptativo 
             - es mas poderoso que
           - el adversario online adaptativo
             - es mas poderoso que
           - el adversario oblivious
    
       * Competitiva Ratios
    
         * Para un algoritmo online $A$
           - Para cada tipo de adversario se define un competitivo ratio:
             - C_A^{obl}: competitivo ratio con adversario oblivious
             - C_A^{aon}: competitivo ratio con adversario adaptativo online
             - C_A^{aof}: competitivo ratio con adversario adaptativo offline
    
           - Es obvio que, para $A$ fijada, considerando un adversario
             mas poderoso va aumentar el competitivo ratio:
             C_A^{obl} \leq C_A^{aon} \leq C_A^{aof}
    
         * Para un problema
           - el competitivo ratio de un problema es el competitivo
             ratio mínima sobre todos los algoritmos correctos para
             este problema.
             C^{obl} \leq C^{aon} \leq C^{aof} \leq C^{det}
           - donde  C^{det} es el competitivo ratio de un algoritmo
             online deterministico.
    
    
    
  + Arboles Binarios de Busqueda aleatorizados 
    - Conrado Martínez. Randomized binary search trees. Algorithms
      Seminar. Universitat Politecnica de Catalunya, Spain, 1996.
    
    - Conrado Martínez and Salvador Roura. Randomized binary search
      trees. J. ACM, 45(2):288–323, 1998.
    
    - [http://en.wikipedia.org/wiki/Treap#Randomized_binary_search_tree]
    
  + Complejidad Probabilistica: cotas inferiores 
    * REFERENCIA: 
      - Capitulo 1 en "Randomized Algorithms", de Rajeev Motwani and Prabhakar Raghavan.
    
    * Notes:
     1) Problema
    
         - Strategia de adversario no funciona
    
         - En algunos casos, teoría de c{\'o}digos es suficiente 
           - e.g. búsqueda en arreglo ordenado
           - eso es una cota inferior sobre el tamaño del
             certificado
    
         - En otros caso, teoría de c{\'o}digos no es suficiente
           - en particular, cuando el precio para verificar un
             certificado es mas pequeño que de encontrarlo.
           - En estos casos, utilizamos otras t\'ecnicas:
             - teoría de juegos (que vamos a ver) y equilibro de Nash
             - cotas sobre la comunicaci{\'o}n en un sistema de
               "Interactive Proof"
    
     2) Algunas Notaciones Algebraicas
    
        Sea:
    
        - A una familia de $n_a$ algoritmos deterministicos
        - $a$ un vector (0,...,0,1,0,...,0) de dimensi{\'o}n $n_a$
        - $\alpha$ una distribuci{\'o}n de probabilidad de dimensi{\'o}n $n_a$
    
        - B una familia de $n_n$ instancias
        - $b$ un vector (0,...,0,1,0,...,0) de dimensi{\'o}n $n_b$
        - $\beta$ una distribuci{\'o}n de probabilidad de dimensi{\'o}n $n_b$
    
        - M una matriz de dimensi{\'o}n $n_a\times n_b$ tal que M_{a,b}
          es el costo del algoritmo $a$ sobre la instancia $b$.
          Por definici{\'o}n,
          - a^t M b = M_{a,b}
          - \alpha^t M b es la complejidad en promedio (sobre el
            aleatorio del algoritmo \alpha) de \alpha sobre b
          - a^t M \beta es la complejidad en promedio (sobre la
            distribuci{\'o}n de instancias \beta) de a sobre \beta
          - \alpha^t M \beta es la complejidad en promedio del
            algoritmo aleatorizados \alpha sobre la distribuci{\'o}n de
            instancia \beta.
    
    
     3) von Neuman's theorem: infsup = supinf = minmax = maxmin
    
        1. OPCIONAL Existencia de $\tilde{\alpha}$ et $\tilde{\beta}$ 
    
           Dado  $\phi$ y $\psi$ definidas sobre $\mathbb{R}^m$ y $\mathbb{R}^n$ por
           $$\phi(\alpha) = \sup_\beta \alpha ^T M \beta 
           \,\mbox{  y  }\,
           \psi(\beta)  = \inf_\alpha \alpha ^T M \beta$$
           Entonces:
    
           - $\phi(\alpha) = \max_\beta \alpha ^T M \beta$ 
           - $\psi(\beta)  = \min_\alpha \alpha ^T M \beta$
           - hay estrategias mixtas  
             - $\tilde{\alpha}$ por \A\
             - $\tilde{\beta}$ por \B\ 
           - tal que 
             - $\phi$ es a su mínima  en $\tilde{\alpha}$ y
             - $\psi$ es a su m{\'a}xima en $\tilde{\beta}$.
    
        2. Resultado de von Neuman: 
    
           Dado un juego $\Gamma$ definido por la matrica  $M$~:
           $$
           \min_\alpha \max_\beta  \alpha ^T M \beta 
           =
           \max_\beta  \min_\alpha \alpha ^T M \beta 
           $$
    
        3. Interpretaci{\'o}n:
    
           + Este resultado significa que si consideramos ambos
             distribuciones sobre algoritmos y instancias, no
             importa el orden del max o min:
                - podemos elegir el mejor algoritmo (i.e. minimizar
                  sobre los algoritmos aleatorizados) y despu\'es
                  elegir la peor distribuci{\'o}n de instancias para el
                  (i.e. maximizar sobre las distribuciones de
                  instancias), o al reves
                - podemos elegir la peor distribuci{\'o}n de instancias
                  (i.e. maximizar sobre las distribuciones de
                  instancias), y considerar el mejor algoritmo
                  (i.e. minimizar sobre los algoritmos
                  aleatorizados) para este distribuci{\'o}n.
           + ATENCI{\'O}N!!!!  Veamos que 
             - El promedio (sobre las instancias) de las
               complejidades (de los algoritmos) en el peor caso
             - no es igual 
             - al peor caso (sobre las instancias) de la complejidad
               en promedio (sobre el aleatorio del algoritmo)
             - donde el segundo termo es realmente la complejidad de
               un algoritmo aleatorizados.
    
           + Todavía falta la relaci{\'o}n con la complejidad en el
             peor caso $b$ de un algoritmo aleatorizados $\alpha$:
    
             $\max_b  \min_\alpha \alpha ^T M b$
    
    
     4) Lema de Loomis 
    
        * Dado una estrategia aleatoria $\alpha$, emite una instancia
          $b$ tal que $\alpha$ es tan mal en $b$ que en el
          peor $\beta$.
    
          $$
          \forall \alpha \exists b,
          \max_\beta \alpha^T M \beta = \alpha^T M b
          $$
    
        * Dado una distribuci{\'o}n de instancias $\beta$, existe un
          algoritmo deterministico $a$ tal que $a$ es tan
          bien que el mejor algoritmo aleatorizados $\alpha$ sobre
          la distribuci{\'o}n de instancias $\beta$:
    
          $$
          \forall \beta \exists a,
          \min_\alpha \alpha^T M \beta = a^T M \beta
          $$
    
        * Interpretaci{\'o}n:
    
          + En frente a una distribuci{\'o}n de instancias especifica,
            siempre existe un algoritmo deterministico {\'o}ptima en
            comparaci{\'o}n con los algoritmos aleatorizados (que
            incluen los deterministicos).
    
          + En frente a un algoritmo aleatorizados, siempre existe
            una instan ca tan mal que la pero distribuci{\'o}n de
            instancias.
    
     5) Príncipe de Yao
    
        * Del leima de Loomis podemos concluir que 
    
          $$
          \max_\beta \alpha^T M \beta = \max_b \alpha^T M b
          $$
    
          $$
          \min_\alpha \alpha^T M \beta = \min_a a^T M \beta
          $$
    
        * Del resultado de von Neuman sabemos que maxmin=minmax
          (sobre \alpha y \beta):
    
           $$
           \min_\alpha \max_\beta  \alpha ^T M \beta 
           =
           \max_\beta  \min_\alpha \alpha ^T M \beta 
           $$
    
        * Entonces    
    
          $$
          \min_alpha \max_b \alpha^T M b
          = (Loomis)
          \min_\alpha \max_\beta  \alpha ^T M \beta 
          = (von Neuman)
          \max_\beta  \min_\alpha \alpha ^T M \beta 
          = (Loomis)
          \max_\beta \min_a a^T M \beta
          $$
    
        * Interpretaci{\'o}n
    
           \min_\alpha   \max_b   \alpha^T M b                                     
                                  \_______       La complejidad                    
               \______  _______   ________       del mejor algoritmo aleatorizado  
                         \___     ___________    en el peor caso                   
    
          es igual a 
    
           \max_\beta   \min_a    \alpha^T M b                                             
                                  \_______       La complejidad                            
                        \___      ___________    del mejor algoritmo deterministico        
           \______      _______   ________       sobre la peor distribuci{\'o}n de instancias  
    
    
          "El peor caso del mejor algoritmo aleatorizado
          corresponde a
          la peor distribuci{\'o}n para el mejor algoritmo deterministico."
    
    
    * Ejemplos de cotas inferiores:
    
      1. Decidir si un elemento pertenece en una lista ordenadas de tamaño n
    
         - Cual es el peor caso $b$ de un algoritmo aleatorizado $\alpha$?
         - Buscamos una distribuci{\'o}n $\beta_0$ que es mala para todos
           los algoritmos deterministicos $a$ (del modelo de comparaciones)
         - Consideramos la distribuci{\'o}n uniforma.
         - Cada algoritmo deterministico se puede representar como un
           arbol de decisi{\'o}n (binario) con $2n+1$ hojas.
    
         - Ya utilizamos para la cota inferior deterministica que la
           altura de un tal arbol es al menos $\lg(2n+1)\in\Omega(\lg
           n)$. Esta propiedad se muestra por recurrencia.
         - De manera similar, se puede mostrar por recurrencia que la
           altura en promedio de un tal arbol binario es al menos
           $\lg(2n+1)\in\Omega(\lg n)$.
    
         - Entonces, la complejidad promedio de cada algoritmo
           deterministico $a$ sobre $\beta_0$ es al menos
           $\lg(2n+1)\in\Omega(\lg n)$.
    
         - Entonces, utilizando el principie de Yao, la complejidad en
           el peor caso de un algoritmo aleatorizado en el modelo de
           comparaciones es al menos $\lg(2n+1)\in\Omega(\lg n)$.
    
         - El corolario interesante, es que el algoritmo
           deterministico de búsqueda binaria es *oprima* a dentro de
           la clase mas general de algoritmos aleatorizados.
    
      2. Decidir si un elemento pertenece en un lista desordenada de tamaño k
         * Si una sola instancia de la valor buscada ($r=1$)
           * Cotas superiores
             - k en el peor caso deterministico
             - (k+1)/2 en el peor caso aleatorio
               - con una direcci{\'o}n al azar
               - con lg(k!) bits aleatorios
           * Cota inferior
             - Buscamos una distribuci{\'o}n $\beta_0$ que es mala para
               todos los algoritmos deterministicos $a$ (en el modelo de
               comparaciones).
             - Consideramos la distribuci{\'o}n uniforma (cada algoritmo
               reordena la instancia a su gusto, de toda manera,
               entonces solamente la distribuci{\'o}n uniforma tiene
               sentido): cada posici{\'o}n es elegida con probabilidad $1/k$
             - Se puede considerar solamente los algoritmos que no
               consideran mas que una ves cada posici{\'o}n, y que
               consideran todas las posiciones en el peor caso:
               entonces cada algoritmo puede ser representado por una
               permutaci{\'o}n sobre $k$.
    
             - Dado un algoritmo deterministico $a$, para cada
               $i\in[1,k]$, hay una instancia sobre cual el performe
               $i$ comparaciones. Entonces, su complejidad en promedio
               en este instancia es $\sum_i i/k$, que es $k(k+1)/2k =
               (k+1)/2$. Como eso es verdad para todos los algoritmos
               deterministicos, es verdad para el mejor de ellos
               tambi\'en.
    
             - Entonces, utilizando el principio de Yao, la complejidad
               en el peor caso de un algoritmo aleatorizado en el
               modelo de comparaciones es al menos $(k+1)/2$.
    
         * Si r instancias de la valor buscada
           * Cotas superiores
             - k-r en el peor caso deterministico
             - O(k/r) en (promedio y en) el peor caso aleatorio
           * Cota inferior
             - Buscamos una distribuci{\'o}n $\beta_0$ que es mala para
               todos los algoritmos deterministicos $a$ (en el modelo de
               comparaciones).
             - Consideramos la distribuci{\'o}n uniforma (cada algoritmo
               reordena la instancia a su gusto, de toda manera,
               entonces solamente la distribuci{\'o}n uniforma tiene
               sentido): cada posici{\'o}n es elegida con probabilidad $1/k$
             - Se puede considerar solamente los algoritmos que no
               consideran mas que una ves cada posici{\'o}n. 
             - De verdad, no algoritmo tiene de considerar mas
               posiciones que $k-r+1$, entonces hay menos algoritmos
               que de permutaciones sobre $k$ elementos. Para
               simplificar la prueba, podemos exigir que los algoritmos
               especifican una permutaci{\'o}n entera, pero no vamos a
               contar las comparaciones despu\'es que un de las $r$
               valores fue encontrada.
    
    
    
      3. Decidir si un elemento pertenece en k listas ordenadas de tamaño n/k
         * Cotas superiores
            * Si una sola lista contiene la valor buscada
              - k búsquedas en el peor caso deterministico, que da
                k\lg(n/k) comparaciones
              - k/2 búsquedas en (promedio y en) el peor caso
                aleatorio, que da k\lg(n/k)/2 comparaciones
            * Si r<k listas contienen la valor buscada
              - k-r búsquedas en el peor caso deterministico, que dan
                (k-r)\lg(n/(k-r)) comparaciones
              - k/r búsquedas en (promedio y en) el peor caso
                aleatorio, que dan (k/r)\lg(n/k) comparaciones
            * Si r=k listas contienen la valor buscada
              - k búsquedas en el peor caso deterministico, en promedio y
                en el peor caso aleatorio, que dan k\lg(n/k) comparaciones
    
      4. Aplicaci{\'o}n: 
    
         algoritmos de intersecci{\'o}n de listas ordenadas.
    
    
    
    * Conclusi{\'o}n:
    
      * Relaci{\'o}n fuerte entre algoritmos aleatorizados y complejidad en
        promedio
    
      * El peor caso de un algoritmo aleatorio corresponde a la
        peor distribuci{\'o}n para un algoritmo deterministico.
    
    * Otras aplicaciones importantes de los algoritmos aleatorizados
    
      * "Online Algorithms", en particular paginamiento.
    
      * Algoritmos de aproximaci{\'o}n
    
     * Hashing
    
           
               

5.2.4 *Relacion con Problemas NP-Dificiles* 
--------------------------------------------

     * Ejemplos de Problemas NP-Dificiles

         1. *Maxcut*
            - dado un grafe $G=(V,E)$
            - encontrar una partition $(L,R)$ tq $L\cup R=V$ y que
              *maximiza* la cantidad de aristas entre $L$ y $R$
            - el problema es NP dificil
            - se aproxima con un factor de dos con un algoritmo
              aleatorizado en tiempo polinomial.
            
         2. *mincut*
            - dado un grafe $G=(V,E)$
            - encontrar una partition $(L,R)$ tq $L\cup R=V$ y que
              minimiza la cantidad de aristas entre $L$ y $R$
            - el problema es NP dificil

     * Relacion con la nocion de NP:

       - El arbol representando la ejecucion de un algoritmo
         non-deterministico en tiempo polynomial (i.e. NP) se
         decomposa en dos partes, de altura polynomial $p(n)$:
         - una parte de *decisiones* non-deterministica (fan-out)
         - una parte de *verificacion* deterministica (straight)
       - Si una solamente de las $2^{p(n))$ soluciones corresponde a
         una solucion valida del problema, la aleatorizacion no
         ayuda, pero si una proporcion constante
         (e.g. 1/2,1/3,1/4,...) de las ramas corresponden a una
         solucion correcta, existe un algoritmo aleatorizado que
         resuelve el problema NP-dificil en tiempo polynomial *en
         promedio*.





5.2.5 Complejidad de un algoritmo aleatorizado 
-----------------------------------------------

       * Considera algoritmos con comparaciones
         - algoritmos deterministicos se pueden ver como arboles de
           decisi{\'o}n.
         - algoritmos aleatorios se pueden ver (de manera
           intercambiable) como
           - una distribuci{\'o}n sobre los arboles de decisi{\'o}n,
           - un arbol de decisi{\'o}n con algunos nodos "aleatorios".

         - La complejidad en una instancia de un algoritmo aleatorio
           es el promedio de la complejidad (en este instancia) de
           los algoritmos deterministicos que le compasan:

           C((A_r)_r,I) = E_r( C(A_r,I) )

         - La complejidad en el peor caso de un algoritmo aleatorio
           es el peor caso del promedio de la complejidad de los
           algoritmos deterministicos que le composan:

           C((A_r)_r) = \max_I C((A_r)_r,I) =  \max_I  E_r( C(A_r,I) )

5.2.6 Tecnicas de cotas inferiores de la complejidad aleatorizada 
------------------------------------------------------------------

 * REFERENCIAS: 

   - Capitulo 2, "Randomized Complexity" en "Concepts of Combinatorial
       Optimization", pages 21--38, 2010.
       [http://www.cs.uwaterloo.ca/~jbarbay/Recherche/Publishing/Publications/#RandomizedComplexity]

 * Notes:
  1) Problema

      - Strategia de adversario no funciona

      - En algunos casos, teora de cdigos es suficiente 
        - e.g. bsqueda en arreglo ordenado
        - eso es una cota inferior sobre el tamao del
          certificado

      - En otros caso, teora de cdigos no es suficiente
        - en particular, cuando el precio para verificar un
          certificado es mas pequeo que de encontrarlo.
        - En estos casos, utilizamos otras tcnicas:
          - teora de juegos (que vamos a ver) y equilibro de Nash
          - cotas sobre la comunicacin en un sistema de
            "Interactive Proof"

  2) Algunas Notaciones Algebraicas

     Sea:

     - A una familia de $n_a$ algoritmos deterministicos
     - $a$ un vector (0,...,0,1,0,...,0) de dimensin $n_a$
     - $\alpha$ una distribucin de probabilidad de dimensin $n_a$

     - B una familia de $n_n$ instancias
     - $b$ un vector (0,...,0,1,0,...,0) de dimensin $n_b$
     - $\beta$ una distribucin de probabilidad de dimensin $n_b$

     - M una matriz de dimensin $n_a\times n_b$ tal que
       $M_{a,b}$ es el costo del algoritmo $a$ sobre la instancia
       $b$.  Por definicin,
       - a^t M b = M_{a,b}
       - \alpha^t M b es la complejidad en promedio (sobre el
         aleatorio del algoritmo \alpha) de \alpha sobre b
       - a^t M \beta es la complejidad en promedio (sobre la
         distribucin de instancias \beta) de a sobre \beta
       - \alpha^t M \beta es la complejidad en promedio del
         algoritmo aleatorizados \alpha sobre la distribucin de
         instancia \beta.


  3) von Neuman's theorem: infsup = supinf = minmax = maxmin

     1. OPCIONAL Existencia de $\tilde{\alpha}$ et $\tilde{\beta}$ 

        Dado  $\phi$ y $\psi$ definidas sobre $\mathbb{R}^m$ y $\mathbb{R}^n$ por
        $$\phi(\alpha) = \sup_\beta \alpha ^T M \beta 
        \,\mbox{  y  }\,
        \psi(\beta)  = \inf_\alpha \alpha ^T M \beta$$
        Entonces:

        - $\phi(\alpha) = \max_\beta \alpha ^T M \beta$ 
        - $\psi(\beta)  = \min_\alpha \alpha ^T M \beta$
        - hay estrategias mixtas  
          - $\tilde{\alpha}$ por \A\
          - $\tilde{\beta}$ por \B\ 
        - tal que 
          - $\phi$ es a su mnima  en $\tilde{\alpha}$ y
          - $\psi$ es a su mxima en $\tilde{\beta}$.

     2. Resultado de von Neuman: 

        Dado un juego $\Gamma$ definido por la matrica  $M$~:
        $$
        \min_\alpha \max_\beta  \alpha ^T M \beta 
        =
        \max_\beta  \min_\alpha \alpha ^T M \beta 
        $$

     3. Interpretacin:

        + Este resultado significa que si consideramos ambos
          distribuciones sobre algoritmos y instancias, no
          importa el orden del max o min:
             - podemos elegir el mejor algoritmo (i.e. minimizar
               sobre los algoritmos aleatorizados) y despus
               elegir la peor distribucin de instancias para el
               (i.e. maximizar sobre las distribuciones de
               instancias), o al reves
             - podemos elegir la peor distribucin de instancias
               (i.e. maximizar sobre las distribuciones de
               instancias), y considerar el mejor algoritmo
               (i.e. minimizar sobre los algoritmos
               aleatorizados) para este distribucin.
        + ATENCIN!!!!  Veamos que 
          - El promedio (sobre las instancias) de las
            complejidades (de los algoritmos) en el peor caso
          - no es igual 
          - al peor caso (sobre las instancias) de la complejidad
            en promedio (sobre el aleatorio del algoritmo)
          - donde el segundo termo es realmente la complejidad de
            un algoritmo aleatorizados.

        + Todava falta la relacin con la complejidad en el
          peor caso $b$ de un algoritmo aleatorizados $\alpha$:

          $\max_b  \min_\alpha \alpha ^T M b$


  4) Lema de Loomis 

     * Dado una estrategia aleatoria $\alpha$, emite una instancia
       $b$ tal que $\alpha$ es tan mal en $b$ que en el
       peor $\beta$.

       $$
       \forall \alpha \exists b,
       \max_\beta \alpha^T M \beta = \alpha^T M b
       $$

     * Dado una distribucin de instancias $\beta$, existe un
       algoritmo deterministico $a$ tal que $a$ es tan
       bien que el mejor algoritmo aleatorizados $\alpha$ sobre
       la distribucin de instancias $\beta$:

       $$
       \forall \beta \exists a,
       \min_\alpha \alpha^T M \beta = a^T M \beta
       $$

     * Interpretacin:

       + En frente a una distribucin de instancias especifica,
         siempre existe un algoritmo deterministico ptima en
         comparacin con los algoritmos aleatorizados (que
         incluen los deterministicos).

       + En frente a un algoritmo aleatorizados, siempre existe una
         instancia tan mal que la peor distribucin de
         instancias.

  5) Prncipe de Yao

     * Del lema de Loomis podemos concluir que 

       $$
       \max_\beta \alpha^T M \beta = \max_b \alpha^T M b
       $$

       $$
       \min_\alpha \alpha^T M \beta = \min_a a^T M \beta
       $$

     * Del resultado de von Neuman sabemos que maxmin=minmax
       (sobre \alpha y \beta):

        $$
        \min_\alpha \max_\beta  \alpha ^T M \beta 
        =
        \max_\beta  \min_\alpha \alpha ^T M \beta 
        $$

     * Entonces    

       $$
       \min_alpha \max_b \alpha^T M b
       = (Loomis)
       \min_\alpha \max_\beta  \alpha ^T M \beta 
       = (von Neuman)
       \max_\beta  \min_\alpha \alpha ^T M \beta 
       = (Loomis)
       \max_\beta \min_a a^T M \beta
       $$

     * Interpretacin

        \min_\alpha   \max_b   \alpha^T M b                                     
                               \_______       La complejidad                    
            \______  _______   ________       del mejor algoritmo aleatorizado  
                      \___     ___________    en el peor caso                   

       es igual a 

        \max_\beta   \min_a    \alpha^T M b                                             
                               \_______       La complejidad                            
                     \___      ___________    del mejor algoritmo deterministico        
        \______      _______   ________       sobre la peor distribucin de instancias  


       "El peor caso del mejor algoritmo aleatorizado
       corresponde a
       la peor distribucin para el mejor algoritmo deterministico."


 * Ejemplos de cotas inferiores:

   1. Decidir si un elemento pertenece en una lista ordenadas de tamao n

      - Cual es el peor caso $b$ de un algoritmo aleatorizado $\alpha$?
      - Buscamos una distribucin $\beta_0$ que es mala para todos
        los algoritmos deterministicos $a$ (del modelo de comparaciones)
      - Consideramos la distribucin uniforma.
      - Cada algoritmo deterministico se puede representar como un
        arbol de decisin (binario) con $2n+1$ hojas.

      - Ya utilizamos para la cota inferior deterministica que la
        altura de un tal arbol es al menos $\lg(2n+1)\in\Omega(\lg
        n)$. Esta propiedad se muestra por recurrencia.
      - De manera similar, se puede mostrar por recurrencia que la
        altura en promedio de un tal arbol binario es al menos
        $\lg(2n+1)\in\Omega(\lg n)$.

      - Entonces, la complejidad promedio de cada algoritmo
        deterministico $a$ sobre $\beta_0$ es al menos
        $\lg(2n+1)\in\Omega(\lg n)$.

      - Entonces, utilizando el principie de Yao, la complejidad en
        el peor caso de un algoritmo aleatorizado en el modelo de
        comparaciones es al menos $\lg(2n+1)\in\Omega(\lg n)$.

      - El corolario interesante, es que el algoritmo
        deterministico de bsqueda binaria es *oprima* a dentro de
        la clase mas general de algoritmos aleatorizados.

   2. Decidir si un elemento pertenece en un lista desordenada de tamao k
      * Si una sola instancia de la valor buscada ($r=1$)
        * Cotas superiores
          - k en el peor caso deterministico
          - (k+1)/2 en el peor caso aleatorio
            - con una direccin al azar
            - con lg(k!) bits aleatorios
        * Cota inferior
          - Buscamos una distribucin $\beta_0$ que es mala para
            todos los algoritmos deterministicos $a$ (en el modelo de
            comparaciones).
          - Consideramos la distribucin uniforma (cada algoritmo
            reordena la instancia a su gusto, de toda manera,
            entonces solamente la distribucin uniforma tiene
            sentido): cada posicin es elegida con probabilidad $1/k$
          - Se puede considerar solamente los algoritmos que no
            consideran mas que una ves cada posicin, y que
            consideran todas las posiciones en el peor caso:
            entonces cada algoritmo puede ser representado por una
            permutacin sobre $k$.

          - Dado un algoritmo deterministico $a$, para cada
            $i\in[1,k]$, hay una instancia sobre cual el performe
            $i$ comparaciones. Entonces, su complejidad en promedio
            en este instancia es $\sum_i i/k$, que es $k(k+1)/2k =
            (k+1)/2$. Como eso es verdad para todos los algoritmos
            deterministicos, es verdad para el mejor de ellos
            tambin.

          - Entonces, utilizando el principio de Yao, la complejidad
            en el peor caso de un algoritmo aleatorizado en el
            modelo de comparaciones es al menos $(k+1)/2$.

      * Si r instancias de la valor buscada
        * Cotas superiores
          - k-r en el peor caso deterministico
          - O(k/r) en (promedio y en) el peor caso aleatorio
        * Cota inferior
          - Buscamos una distribucin $\beta_0$ que es mala para
            todos los algoritmos deterministicos $a$ (en el modelo de
            comparaciones).
          - Consideramos la distribucin uniforma (cada algoritmo
            reordena la instancia a su gusto, de toda manera,
            entonces solamente la distribucin uniforma tiene
            sentido): cada posicin es elegida con probabilidad $1/k$
          - Se puede considerar solamente los algoritmos que no
            consideran mas que una ves cada posicin. 
          - De verdad, no algoritmo tiene de considerar mas
            posiciones que $k-r+1$, entonces hay menos algoritmos
            que de permutaciones sobre $k$ elementos. Para
            simplificar la prueba, podemos exigir que los algoritmos
            especifican una permutacin entera, pero no vamos a
            contar las comparaciones despus que un de las $r$
            valores fue encontrada.



   3. Decidir si un elemento pertenece en k listas ordenadas de tamao n/k
      * Cotas superiores
         * Si una sola lista contiene la valor buscada
           - k bsquedas en el peor caso deterministico, que da
             k\lg(n/k) comparaciones
           - k/2 bsquedas en (promedio y en) el peor caso
             aleatorio, que da k\lg(n/k)/2 comparaciones
         * Si r<k listas contienen la valor buscada
           - k-r bsquedas en el peor caso deterministico, que dan
             (k-r)\lg(n/(k-r)) comparaciones
           - k/r bsquedas en (promedio y en) el peor caso
             aleatorio, que dan (k/r)\lg(n/k) comparaciones
         * Si r=k listas contienen la valor buscada
           - k bsquedas en el peor caso deterministico, en promedio y
             en el peor caso aleatorio, que dan k\lg(n/k) comparaciones

   4. Aplicacin: 

      algoritmos de interseccin de listas ordenadas.



 * Conclusin:

   * Relacin fuerte entre algoritmos aleatorizados y complejidad en
     promedio

   * El peor caso de un algoritmo aleatorio corresponde a la
     peor distribucin para un algoritmo deterministico.

 * Otras aplicaciones importantes de los algoritmos aleatorizados

   * "Online Algorithms", en particular paginamiento.

   * Algoritmos de aproximacin

   * Hashing






5.2.7 Algoritmos tipo Monte Carlo y Las Vegas 
----------------------------------------------

     * Formalizaci{\'o}n

             Algoritmos cl{\'a}sicos      Non cl{\'a}sicos   
            ------------------------+---------------
             Siempre hacen lo mismo   aleatorizados  
             Nunca se equivocan       Monte Carlo    
             Siempre terminan         Las Vegas      


     * Clasificaci{\'o}n de los algoritmos *de decisi{\'o}n* aleatorizados

         1. Probabilístico: Monte Carlo
            - P(error) < \'epsilon
            - Ejemplo:
              - detecci{\'o}n de cliquas
            - Se puede considerar tambi\'en variantes mas fines:
              - two-sided error ( => clase de complejidad BPP)
                - P(accept | negative) < \epsilon
                - P(refuse | negative) > 1-\epsilon
                - P(accept | positive) > 1-\epsilon
                - P(refuse | positive) < epsilon
              - One-sided error
                - P(accept | negative) < epsilon
                - P(refuse | negative) > 1 -\epsilon 
                - P(accept | positive) = 1
                - P(refuse | positive) = 0

         2. Probabilístico: Las Vegas
            - Tiempo es una variable aleatoria
            - Ejemplos: 
              - determinar primalidad [Miller Robin]
              - búsqueda en arreglo desordenado 
              - intersecci{\'o}n de arreglos ordenados
              - etc...

      * Relaci{\'o}n
        - Si se puede verificar el resultado en tiempo razonable,
          Monte Carlos iterado hasta correcto => Las Vegas

5.2.8 Primalidad 
-----------------
      * REFERENCIAS: 
        - Primalidad: Capitulo 14.6 en "Randomized Algorithms", de Rajeev Motwani and Prabhakar Raghavan.
        - [http://en.wikipedia.org/wiki/Primality_test#Complexity]

      * Algoritmo "Random Walks" para SAT
        1. eliga cualquieras valores $x_1,\ldots,x_n$
        2. si todas las  clausilas son  satisfechas,
           - accepta
        3. sino
           - eliga una clausula non satisfecha (deterministicamente
             o no)
           - eliga una de las variables de esta closula.
        4. Repite es $r$ veces.

      * PRIMES is in coNP

        si $x\in coNP$, eliga non-deterministicamente una
        decomposicion de $x$ y verificalo.

      * PRIMES is in NP (hence in NP\cap coNP)

        In 1975, Vaughan Pratt showed that there existed a
        certificate for primality that was checkable in polynomial
        time, and thus that PRIMES was in NP, and therefore in NP 
        coNP.


      * PRIMES in coRP

        The subsequent discovery of the Solovay-Strassen and
        Miller-Rabin algorithms put PRIMES in coRP. 

      * PRIMES in ZPP = RP \cap coRP

        In 1992, the Adleman-Huang algorithm reduced the complexity
        to ZPP = RP  coRP, which superseded Pratt's result.

      * PRIMES in QP

        The cyclotomy test of Adleman, Pomerance, and Rumely from
        1983 put PRIMES in QP (quasi-polynomial time), which is not
        known to be comparable with the classes mentioned above.

      * PRIMES in P

        Because of its tractability in practice, polynomial-time
        algorithms assuming the Riemann hypothesis, and other
        similar evidence, it was long suspected but not proven that
        primality could be solved in polynomial time. The existence
        of the AKS primality test finally settled this long-standing
        question and placed PRIMES in P. 

      * PRIMES \in NC? PRIMES \in L?

        PRIMES is not known to be P-complete, and it is not known
        whether it lies in classes lying inside P such as NC or L.

5.2.9 Clases de complejidad aleatorizada :BONUS:
------------------------------------------------

* RP 
  
  - "A *precise* polynomial-time bounded nondeterministic Turing
    Machine", aka "maquina de Turing non-deterministica acotadada
    polinomialemente *precisa*", es una maquina tal que su
    ejecucion sobre las entradas de tamao n toman tiempo p(n)
    *todas*.
  
  - "A *polynomial Monte-Carlo Turing machine*", aka una
    "*maquina de Turing de Monte-Carlo* polynomial" para el
    idioma $L$, es una tal maquina tal que
    - si $x\in L$, al menos la mitad de los $2^{p(|x|)}$ caminos
      acceptan $x$
    - si $x\not\in L$, *todas* los caminos rechazan $x$.
  
  - La definicion corresponde exactamente a la definicion de
    algoritmos de Monte-Carlo. La classe de idiomas reconocidos
    por una *maquina de Turing de Monte-Carlo* polynomial es
    $RP$.
  
  - $P \subset BP \subset NP$:
    - un algoritmo en $P$ accepta con todos sus caminos cuando
      una palabra $x$ es en $L$, que es "al menos" la mitad.
    - un algoritmo en $NP$ accepta con al menos un camino: un
      algoritmo en $RP$ accepta con al menos la mitad de sus
      caminos.
  
  
  
* ZPP 
  
  - ZPP = RP \cap coRP
  
  - Primes \in ZPP
  
  
  
* PP 
  
  - Maquina que, si $x\in L$, accepta en la mayoridad de sus
    entradas.
  
  - PP probablemente no en NP
  - PP probablemente no en RP
  
* BPP 
  
  - BPP = { L, \forall x, 
    - x\in L \implies 3/4 de los caminos acceptan x
    - x\not\in L \implies 3/4 de los caminos rechazan x
  
  - RP \subset BPP \subset PP
  
  - BPP = coBPP
  
  
  

5.3 Nociones de *aproximabilidad* (2 semanas = 4 charlas) 
==========================================================
    [2010-10-26 Tue]--[2010-11-04 Thu]
    - problemas que son o no aproximables

5.3.1 Intro: Aproximaci{\'o}n de problemas de optimizaci{\'o}n NP-dificiles 
----------------------------------------------------------------------------

    - Que problemas NP dificiles conocen?
      - colorisacion de grafos
      - ciclo hamiltonian
      - Recubrimiento de Vertices (Vertex Cover)
      - Bin Packing
      - Problema de la Muchila
      - Vendedor viajero (Traveling Salesman)

    - Que hacer cuando se necessita una solucion en tiempo
      polinomial?

      - Consideramos los problemas NP completos de decisi{\'o}n,
        generalmente de optimizaci{\'o}n.  Si se necesita una solucion{\'o}
        en tiempo polinomial, se puede considerar una aproximaci{\'o}n.

5.3.2 *$p(n)$-aproximaci{\'o}n*:  Definicin 
------------------------------------------------

     * Dado un problema de minimizaci{\'o}n, un algoritmo $A$ es un
       *$p(n)$-aproximaci{\'o}n* si
       $\forall n \max \frac{ C_A(x) }{ C_{OPT}(x) } \leq p(n)$

     * Dado un problema de maximizaci{\'o}n, un algoritmo $A$ es un
       *$p(n)$-aproximaci{\'o}n* si
       $\forall n \max \frac{ C_{OPT}(x) }{ C_A(x) } \leq p(n)$

      - Notas: 
        1) Aquí consideramos la cualidad de la soluci{\'o}n, NO la
           complejidad del algoritmo. Usualmente el problema es
           NP-difícil, y el algoritmo de aproximaci{\'o}n es de
           complejidad polinomial.
        2) Las razones estas \geq 1 (elijamos las definiciones para
           eso)
        3) A veces consideramos tambi\'en C_A(x)-C_{OPT}(x)
           (minimizaci{\'o}n) y C_{OPT}(x)-C_A(x): eso se llama un
           "esquema de aproximaci{\'o}n polinomial" y vamos a verlo mas
           tarde.

5.3.3 Ejemplo: Bin Packing (un problema que es 2-aproximable) 
--------------------------------------------------------------

    - DEFINICI{\'O}N

       Dado $n$ valores $x_1, \ldots, x_n$, $0\leq x_i\leq 1/2$,
       cual es la menor cantidad de cajas de tamaño 1 necesarias
       para empaquetarlas?

    - Algoritmo "Greedy"
      - Considerando los $x_i$ en orden,
      - llenar la caja actual todo lo posible,
      - pasar ala siguiente caja.

    - An{\'a}lisis
      - Este algoritmo tiene complejidad lineal $O(n)$.
      - Greedy da una 2-aproximaci{\'o}n.
      - (se puede mostrar facilamente en las instancias donde el
        algoritmo {\'o}ptima llene completamente todas las cajas.)

    - Adem{\'a}s, hay mejores aproximaciones, 
      1. Best-fit tiene performance ratio de 1.7 en el peor caso
      2. [Best-Fit Bin-Packing with Random Order (1997), Kenyon]

         Best-fit is the best known algorithm for on-line
         binpacking, in the sense that no algorithm is known to
         behave better both in the worst case (when Best-fit has
         performance ratio 1.7) and in the average uniform case,
         with items drawn uniformly in the interval [0; 1] (then
         Best-fit has expected wasted space O(n 1=2 (log n) 3=4
         )). In practical applications, Best-fit appears to perform
         within a few percent of optimal. In this paper, in the
         spirit of previous work in computational geometry, we study
         the expected performance ratio, taking the worst-case
         multiset of items L, and assuming that the elements of L
         are inserted in random order, with all permutations equally
         likely. We show a lower bound of 1:08 : : : and an upper
         bound of 1:5 on the random order performance ratio of
         Best-fit. The upper bound contrasts with the result that in
         the worst case, any (deterministic or randomized) on-line
         bin-packing algorithm has performance ratio at least
         1:54 : : :. 1

      3. Un otro paper donde particionan los $x_i$ en tres classes,
         placeando los x_i mas grande primero, buscando el
         placamiento optimal de los $x_i$ promedio, y usando un
         algoritmo greedy para los $x_i$ pequenos. [Karpinski?]

      4. la distribucion de los tamaños de las cajas hacen la
         instancia dificil o facil.


5.3.4 Ejemplo: Recubrimiento de Vertices (Vertex Cover) 
--------------------------------------------------------

    - DEFINICI{\'O}N:

      Dado un grafo $G=(V,E)$, cual es el menor $V'\subseteq V$ tal
      que $V'$ sea un vertex cover de $G$.
      (o sea $V'$ mas pequeño tq $\forall e=(u,v)\in E, u\in V'o v\in V')

    - Algoritmo de aproximaci{\'o}n:

      - V'\leftarrow \emptyset
      - while E\neq \emptyset
        - sea (u,v) \in E
        - V'\leftarrow V'\cup {u,v}
        - E \leftarrow E \ {(x,y), x=u o x=v o y=u o y=v }
      - return V

    - Discusi{\'o}n: es una 2-aproximaci{\'o}n o no?

    - LEMA: El algoritmo es una 2-aproximaci{\'o}n.

      - PRUEBA:
        + Cada par $u,v$ que la aproximaci{\'o}n elige esta conectada,
          entonces u o v estas en cualquier solucion{\'o} {\'o}ptima de
          Vertex Cover.
        + Como se eliminan las aristas incidentes en u y v, los
          siguientes pares que se eligen no tienen intersecci{\'o}n con
          el actual, entonces cada 2 nodos que el algoritmo elige,
          uno pertenece a la soluci{\'o}n {\'o}ptima.
        + quod erat demonstrandum, (QED).



5.3.5 Ejemplo: Vendedor viajero (Traveling Salesman) 
-----------------------------------------------------

    - DEFINICI{\'O}N:

      Dado $G=(V,E)$ dirigido y $C:E\rightarrow R^+$ una funci{\'o}n de
      costos, encontrar un recorrido que toque cada ciudad una vez, y
      minimice la suma de los costos de las aristas recorridas.

    - LEMA:     Si $c$ satisface la desigualdad triangular
      $\forall x,y,z   c(x,y)+x(y,z) \geq c(x,z)$,
      hay una 2-aproximaci{\'o}n.

      - PROOF: 
        - Algoritmo de Aproximaci{\'o}n (con desigualdad triangular)
          - construir un arbol cobertor mínimo (MST)
            - se puede hacer en tiempo polinomial, con programaci{\'o}n lineal.
            - C_{MST} \leq C_{OPT}
          - producimos un recorrido en profundidad DFS del MST:
            - C_{DFS} = 2C_{MST} \leq 2 C_{OPT}
            - (factor dos porque el camino de vuelta puede ser al
              m{\'a}ximo de tamaño igual al tamaño del camino de ida)
          - eliminamos los nodos repetidos del camino, que no crece
            el costo
            - $C_A\leq 2 C_{OPT}$
        - quod erat demonstradndum, QED.

    - LEMA: Si $c$ no satisface la desigualdad triangular, el
      problema de vendedor viajero no es aproximables en tiempo
      polinomial (a menos que P=NP$).

      - PROOF:   
        - Supongamos que existe una p(n)-aproximaci{\'o}n de tiempo
          polinomial.
        - Dado un grafo G=(V,E)
        - Construimos un grafo G'=(V,E') tal que 
          - E'=V^2 (grafo completo), y
          - c(u,v) =  1 si (u,v)\in E
                      n p(n) sino
        - Si no hay un Ciclo Hamiltonian en E,
          - todas las soluciones usan al menos una arista que no es
            en E
          - entonces todas las soluciones tienen costo mas que
            $np(n)$
        - Si hay un Ciclo Hamiltonian en E
          - tenemos una aproximaci{\'o}n de una solucion{\'o} de costo menos
            que $(n-1)p(n)$                 QED

5.3.6 Ejemplo: Vertex Cover con pesos 
--------------------------------------


    - DEFINICI{\'O}N

      Dado G=(V,E) y c:V\rightarrowR^+, se quiere un V^*\subseteq V que cubra
      E y que minimice \sum_{v\in V^*} c(v).

    - Este problema es NP Completo.

    - LEMA: Vertex Cover con pesos es 2-aproximable
    - PROOF:
      1. Sea variables x(v)\in {0,1}, \forall v\in V
          - el costo de V^* sera \sum x(v) c(v) 
          - objetivo: \min \sum_{v\in V} x(v) c(v)
            donde 0\leq x(v) \leq 1 \forall v\in V
          - x(u)+x(v)\geq 1 \forall u,v \in E
      2. x(v) \in Z ser\'e programaci{\'o}n entera, que es NP Completa
         x(v) \in R ser\'e programaci{\'o}n lineal, que es polinomial
         el valor \sum x(v) c(v) que produce el programo lineal
         es inferior a la mejor soluci{\'o}n al problema de VC.
      3. Algoritmo
         - resolver el problema de programaci{\'o}n lineal
           - nos da x(v_1),\ldots x(v_n)
         - V^* < \emptyset
         - for v\in V
           - si x(v)\geq 1/2
             - V^* \leftarrow V^* \cup {v}
         - return V^*
      4. Propiedades
         - V^* es un vertex cover:
           - si \forall(u,v)\in E, x(u)+x(v)\geq 1
           - entonces, x(u)\geq 1/2 o x(v)/geq 1/2
           - entonces, u\in V^* o v\in V^*
         - V^* es una 2-aproximaci{\'o}n:
           - c(V^*) = \sum_v y(v) c(v)
             donde y(v) = 1 si x(v) \geq 1/2
                          0 sino
           - entonces y(v) \leq 2 x(v)
           - \sum y(v) c(v) \leq \sum 2 x(v) c(v) \leq 2 OPT
           - C(V^*)         \leq 2 OPT
      5. QED


5.3.7 PTAS y FPTAS: Definiciones 
---------------------------------

    * Esquema de aproximacion poliniomial *PTAS*
      Un *esquema de aproximaci{\'o}n polinomial* para un problema es un
      algoritmo $A$ que recibe como input una instancia del problema
      y un para-metro $\varepsilon>0$ y produce una $(1+\varepsilon)$
      aproximaci{\'o}n. Para todo $\varepsilon$ fijo, el tiempo de $A$
      debe ser polinomial en $n$, el tamaño de la instancia.

    * Ejemplos de complejidades: Cuales tienen sentidos?
      - [ ] $O(n^{2/3})$
      - [ ] $O(\frac{1}{\varepsilon^2} n^2)$
      - [ ] $O(2^\varepsilon n)$
      - [ ] $O(2^{1/\varepsilon} n)$
            
    * Esquema de aproximaci{\'o}n completamente polinomial *FPTAS*

      Un *esquema de aproximaci{\'o}n completamente polinomial* es un
      PTAS donde el tiempo del algoritmo es polinomial en $n$ *y en
      $1/\varepsilon$*.

5.3.8 Ejemplo: Problema de la mochila 
--------------------------------------


    * Definici{\'o}n:
      
      Dado 
      - los elementos $S={1,\ldots,n}$ con pesos $X_1,\ldots,X_N\geq 0$,
      - un tamaño m{\'a}ximo $t$
      Quiero encontrar $S'\subset S$ 
      - tal que $\sum(S')\leq t y$
      - que maximice $\sum(S')=\sum_{i\in S'} x_i$

    * Solucion exacta, exponencial
      - Dado $L=\{y_1,,\ldots y_m\}$, definimos $L+x=\{y_1+x,\ldots,y_m+x\}$
      - Algoritmo:
        - $L \leftarrow \{\emptyset\}$
        - for $i\leftarrow 1$ to $n$
          - $L \leftarrow$ merge $(L,L+x_i)$
          - prune$(L,t)$      (remudando las valores $> t$)
        - return $\max(L)$

    * Solucion aproximada (inspirada del algoritmo exacto)

      - Definimos la operaci{\'o}n de *recorte* de una lista L con
        par{\'a}metro $\delta$:
        - Dado $y,z \in L$, $z$ *represente* a $y$ si
          - $y /(1+\delta)   \leq   z   \leq y$ 
      - vamos a eliminar de $L$ todos los $y$ que sean representados
        por alguno $z$ no eliminado de $L$.

      - Recortar$(L,\delta)$
        - Sea $L=\{y_1,\ldots,y_m\}$
        - $L'\leftarrow \{y_1\}$
        - $\mathit{Last} \leftarrow y_1$
        - for $i\leftarrow 2$ to $m$
          - si $y_i > \mathit{Last}(1+\delta)$
            - $L \leftarrow L'.\{y_i\}$
            - $\mathit{Last}\leftarrow y_i$
        - return $L'$

      - Algoritmo de Aproximaci{\'o}n:
        - $L \leftarrow \{\emptyset\}$
        - for $i\leftarrow 1$ to $n$
          - $L \leftarrow \mathit{merge} (L,L+x_i)$
          - $\mathit{prune}(L,t)$      (remudando las valores $> t$)
          - *$L \leftarrow \mathit{recortar}(L,\epsilon/2n)$*
        - return max(L)

      - El resultado es una $(1+\epsilon)$-aproximaci{\'o}n:
        1. retorne una soluci{\'o}n valida, tal que 
           - $\sum(S')\leq t$ para algún $S'\subset S$
        2. en el paso $i$, para todo $z\in L_{OPT}$,
           existe un $y\in L_A$ tal que $z$ representa a $y$.
           - Luego de los $n$ pasos, el $z^*$ {\'o}ptimo en $L_{OPT}$
             tiene un representante $y^*\in L_A$ tal que 
             $z^*/(1+\epsilon/2n)^n \leq y^* \leq z^*
        3. Para mostrar que el algoritmo es una $(1+\epsilon)$
           aproximaci{\'o}n, 
           - hay que mostrar que
             - $z^*/(1+\epsilon) \leq y^*$
           - entonces, debemos mostrar que 
             - $(1+\epsilon/2n)^n \leq 1+\epsilon$
           - Eso se muestra con puro calculo:
             - $(1+\epsilon/2n)^n \leq? 1+\epsilon$
             - $e^{n\lg(1+\epsilon/2n) }$
             - $\leq e^{ n \epsilon /2n }$
             - $= e^{ \epsilon/2 }$
             - $\leq? e^{\ln(1+\epsilon)}$
             - eso es equivalente a elegir \epsilon tal
               que $\epsilon/2 \leq \ln(1+\epsilon)$
             - i.e. cualquier tal que $0<\epsilon\leq 1$
        4. El algoritmo es polinomial (en todos los par{\'a}metros)
           - despues de recortar dedos $y_i,y_{i+1}\in L$
             se cumple $y_{i+1}>y_i(1+\delta)$
             y el ultimo elemento es $\leq t$
           - entonces, la lista contiene $0,1$
             y luego a lo mas $\lfloor \log_{(1+\delta)} t \rfloor$
           - entonces el largo de L en cada iteracion no supera
             $2+ \frac{ \log t }{ \log( 1+\varepsilon/2n) }$
           - Nota que $\ln(1+x) $
             - $= - \ln (1/(1+x))$
             - $= - \ln ( (1+x-x)/(1+x) )$
             - $= - \ln ( 1 - x/(1+x) )$
             - $= - \ln (1+y) \geq -y$
             - $\geq - (-x/(1+x)) = x/(1+x)$
           - Entonces
             - $2+ \frac{ \ln t }{ \ln 1 + \epsilon/2n }$
             - $\leq 2 + ((1+\epsilon/2n) 2n \ln t )/\epsilon$
             - $= ( 2n\ln t )/ \epsilon + \ln t + 2$
             - $= O(n \lg t /\epsilon)$
           - Entonces cada iteracion toma $O(n \lg t /\epsilon)$ operaciones
           - Las $n$ iteraciones en total toman 
             - $O(n^2 \lg t /\epsilon)$ operaciones

5.4 Algoritmos *paralelos* y distribuidos (2 semanas = 4 charlas) 
==================================================================
    - Medidas de complejidad
    - T\'ecnicas de diseño

 REFERENCIA: Chap 12 of "Introduction to Algorithms, A Creative Approach",
 Udi Manber, p. 375

 REFERENCIA: [http://www.catonmat.net/blog/mit-introduction-to-algorithms-part-thirteen/]

5.4.1 Modelos de paralelismo 
-----------------------------

    * Instrucciones
      - SIMD: Single Instrucci{\'o}n, Múltiple Data
      - MIMD:  Múltiple Instrucci{\'o}n, Múltiple Data
    * Memoria
      - compartida
      - distribuida

    * 2*2 combinaciones posibles:

                 Memoria compartida   Memoria distribuida                                  
         ------+--------------------+-----------------------------------------------------
          SIMD   PRAM                 redes de interconexi{\'o}n (weak computer units)  
                                      (hipercubos, meshes, etc...)                         
         ------+--------------------+-----------------------------------------------------
          MIMD   Threads              procesamiento distribuido (strong computer units),   
                                      Bulk Synchronous Process, etc...                     

    * En este curso consideramos en particular el modelo PRAM

5.4.2 Modelo PRAM 
------------------

   * Mucha unidad de CPU, una sola memoria RAM

     cada procesador tiene un identificador único, y puede utilizarlo
     en el programa

   * Ejemplo:
     
     + if p mod 2 = 0 then
       + A[p] += A[p-1]
     + else
       + A[p] += A[p+1]
     + b \leftarrow A[p];
     + A[p]\leftarrow b;

   * Problema: el resultado no es bien definido, puede tener
     *conflictos* si los procesadores est{\'a}n asinchronos. Las soluciones a
     este problemas dan varios submodelos del modelo PRAM:

     1. EREW Exclusive Read. Exclusive Write

     2. CREW Concurrent Read, Exclusive Write

     3. CRCW Concurrent Read, Concurent Write
        En este caso hay variantes tambi\'en:
        - todos deben escribir lo mismo
        - arbitrario resultado
        - priorizado
        - alguna f() de lo que se escribe


5.4.3 Como medir el "trade-off" entre recursos (cantidad de procesadores) y tiempo? 
------------------------------------------------------------------------------------

    * DEFINICI{\'O}N:

      - $T^*(n)$ es el *Tiempo secuencial* del mejor algoritmo no
        paralelo en una entrada de tamaño $n$ (i.e. usando $1$
        procesador).

      - $T_A(n,p)$ es el *Tiempo paralelo* del algoritmo paralelo
        $A$ en una entrada de tamaño $n$ usando $p$ procesadores.

      - El *Speedup* del algoritmo $A$ es definido por

        $S_A(n,p) = \frac{ T^*(n) }{ T_A(n,p) } \leq p$ 

        Un algoritmo es mas efectivo cuando $S(p)=p$, que se llama
        *speedup perfecto*.

      - La *Eficiencia* del algoritmo $A$ es definida por

        $E_A(n,p) = \frac{ S_A(n,p) }{ p }=\frac{T^*(n)}{pT_A(n,p)}$ 

        El caso {\'o}ptima es cuando $E_A(n,p)=1$, cuando el algoritmo
        paralelo hace la misma cantidad de trabajo que el algoritmo
        secuencial. El objetivo es de *maximizar la eficiencia*.

        (Nota estas definiciones en la pisara, vamos a usarlas despu\'es.)

5.4.4 PROBLEMA: Calcular Max(A[1,...,N]) 
-----------------------------------------

    1. Solucion Secuencial

       * Algoritmo:
         - $m \leftarrow 1$
         - for $i\leftarrow 2$ to $n$
           - if $A[i]>A[m]$ then $m\leftarrow i$
         - return $A[m]$

       * Se puede ver como un arbol de evaluaci{\'o}n con una sola rama
         de largo $n$ y $n$ hojas.

       * Complejidad: 
         - tiempo $O(n)$, con $1$ procesador, entonces:
         - $T^*(n)=n$.

    2. Solucion Parallela con $n$ procesadores

       * Algoritmo:
         - $M[p] \leftarrow A[p]$
         - for $l\leftarrow 0$ to $\lceil \lg p \rceil -1$
           - if $p \mod 2^{l+1}=0$ y $ p+2^l<n$
             - $M[p]\leftarrow \max( M[p],M[p+2^l])$
         - if $p=0$
           - $max \leftarrow M[2]$

       * Se puede ver como un arbol balanceado de altura $\lg n$ con
         $n$ hojas.

       * Complejidad: 

         - tiempo $O(\lg n)$ con $n$ procesador, i.e. en nuestra notaciones:
         - $T(n,n) = \lg n$
         - $S(n,n) = \frac{n}{\lg n} $
         - $E(n,n) = \frac{n}{n\lg n} = {1\over\lg n} $

       * Nota: no se puede hacer mas r{\'a}pido, pero hay mucho
         procesadores poco usados: quiz{\'a}s se puede calcular el max
         en el mismo tiempo, pero usando menos procesadores?

    3. Solucion general con $p$ procesadores

       * Idea:

         - reduce la cantidad de procesadores, y hace "load
           balancing" sobre $n/\lg n$ procesadores.
         - Divida el input en $n/\lg n$ grupos, 
         - asigna cada grupo de $\lg n$ elementos a un procesador.
         - En la primera fase, cada procesador encontra el max de su grupo
         - En la segunda fase, utiliza el algoritmo precedente.

       * Complejidad: 

         - tiempo $O(\lg n)$ con $n$ procesador, i.e. en nuestra notaciones:
           - $T(n, {n\over\lg n} ) = 2 \lg n \in O(\lg n)$
             - $T(n,p)= {n\over p} + \lg p$
           - $S(n,p) = \frac{n}{{n\over p} + \lg p} 
             = p ( 1 - \frac {p\lg p}{n+p\lg p})
             \rightarrow p$ si $n\rightarrow \infty$ y p
           - $E(n,p) = \frac{n}{{n\over\lg n}\lg n} = 1/2 $

       * Discusi{\'o}n:
         
         - El par{\'a}metro de $\lg n$ procesadores es {\'o}ptima?

           - Para que? Que significa ser {\'o}ptima? 
             - en energía
             - en el contexto donde los procesadores libres pueden
               ser usados para otras tareas.
           - Si, es {\'o}ptimo para la eficiencia, se puede ver
             estudiando el grafo en funci{\'o}n de $p$.

         - Eso es un algoritmo EREW, CREW, o CRCW?

           - EREW (Exclusive Read. Exclusive Write): no dos
             procesadores lean o escriben en la misma c\'edula al
             mismo tiempo.

         - Nota: 

           - Hay un algoritmo CRCW que puede calcular el max en $O(1)$
             tiempo en paralelo, ilustrando el poder del modelo
             CRCW (y el costo de las restricciones del modelo EREW)
             [ REFERENCIA: Section 12.3.2 of "Introduction to Algorithms, A
             Creative Approach", Udi Manber, p. 382]]

           




5.4.5 LEMMA de Brent, Trabajo y Consecuencias 
----------------------------------------------
* LEMA de Brent 
  
  El algoritmo previo illustra un principo mas general, llamado el
  "Lemma de Brent":
  
  Si un algoritmo 
  - consigue un tiempo T(n,p)=C, entonces 
  - consigue tiempo T(n,p/s)= sC \forall s>1 
  - (bajo algunas condiciones, tal que hay suficientamente memoria
    para cada procesador)
  
* DEFINICI{\'O}N "Trabajo" 
  
  - Usando el Lema de Brent, podemos exprimir el rendimiento de
    los algoritmos paralelos con solamente dos medidas:
   
    - $T(n)$, el tiempo del mejor algoritmo paralelo usando
      cualquier cantidad de procesadores que quiere.
  
      Nota las diferencias con
      + $T^*(n)$, el tiempo del mejor algoritmo secuencial, y 
      + $T_A(n,n)$, el tiempo del algoritmo $A$ con $n$ procesadores.
  
    - $W(n)$, la suma del total trabajo ejecutado por todo los
      procesadores (i.e. superficia del arbol de calculo, a
      contras de su altura (tiempo) o hancho (cantidad de
      procesadores).
  
  - INTERACCION: Cual son estas valores para el algoritmo de Max?
    - $T(n)=$?
    - $W(n)=$?
  
  - INTERACCION: Puedes ver como desde $T(n)$, $W(n)$ se puede deducir
    las valores de
    - $T(n,p)$? (solucion en el corolario)
    - $S(n,p)$? (trivial desde $T(n,p)$) 
    - $E(n,p)$? (solucion en el corolario)
      - 
  
* COROLARIO 
  
  - Con el lema de Brent podemos obtener:
  
    - $$T(n,p) = T(n) + \frac{ W(n) }{ p }$$
  
    - $$E(n,p) = \frac{ T^*(n) }{ pT(n) + W(n) }$$
  
* EJEMPLO 
  
  * Para el calculo del m{\'a}ximo:
    - $T(n) = \lg n$
    - $W(n) = n$
  
  * Entonces
    - se puede obtener 
      - $T_B(n,p) = \lg n + {n \over p}$
      - $$E(n,p) = \frac{ n }{ p\lg n + n }$$
  
  * (Nota que eso es solamente una cota superior, nuestro
    algoritmo da un mejor tiempo.)
  
  
  
  

5.4.6 PROBLEMA: Ranking en listas 
----------------------------------

     1. DEFINICI{\'O}N
        
        - dado una lista, calcula el rango para cada elemento.

        - En el caso de una lista tradicional, no se puede hacer
          mucho mejor que lineal.

        - Consideramos una lista en un arreglo $A$, 
          - donde cada elemento $A[i]$ tiene un puntero al siguiente
            elemento, $N[i]$, y
          - calculamos su rango $R[i]$ en un arreglo $R$.

     2. DoublingRank()
        - $R[p] \leftarrow 0$
        - if $N[p] =  null$
          - $R[p] \leftarrow 1$
        - for $d\leftarrow 1$ to $\lceil\lg n\rceil$
          - if $N[p]\neq NULL$
            - if $R[N[p]]>0$ 
              - $R[p] \leftarrow R[N[p]]+2^d$
            - $N[p] \leftarrow N[N[p]]$

     3. An{\'a}lisis

        - $T(n) = \lg n$
        - $W(n) = n + W(n/2) \in O(n)$
        - $T(n,p) = T(n) + W(n)/p = \lg n + n/p$
        - $p^*$
          $T(n) = W(n) / p^*$
          $p n/\lg n$
        - $E(n,p^*) = \frac{T^*(n)}{ p^* T(n) + W(n) }
                   = \frac{ n }{ n/\lg n \lg n +n} 
                   \in \Theta(1)$

     4. El algoritmo es EREW o CREW?

        - es EREW si los procesadores est{\'a}n sincronizados, com en
          RAM aqu{\'a}.


5.4.7 PROBLEMA: Prefijos en paralelo ("Parallel Prefix") 
---------------------------------------------------------

    * DEFINICI{\'O}N: Problema "Prefijo en Paralelo"

      Dado $x_1,\ldots, x_n$ y un operador asociativo $\times$,
      calcular 
      - $y_1 = x_1$
      - $y_2 = x_1\times x_2$
      - $y_2 = x_1\times x_2 \times x_3$
      - ...
      - $y_n = x_1\times \ldots \times x_n$

    * Solucion Secuencial

      Hay una solucion obvio en tiempo $O(n)$.

* Solucion paralela 1 
  
  * Concepto:
  
    - Hip{\'o}tesis: sabemos solucionarlo con $n/2$ elementos
    - Caso de base: $n=1$ es simple.
    - Inducci{\'o}n:
      1. recursivamente calculamos en paralelo:
         - todos los prefijos de $\{x_1,\ldots,x_{n/2}\}$ con
           $n/2$ procesadores.
         - todos los prefijos de $\{x_{n/2},\ldots,x_n\}$ con
           $n/2$ procesadores.
      2. en paralelo agregamos $x_{n/2}$ a los prefijos de
         $\{x_{n/2},\ldots,x_n\}$
  
  * Observacion: en cual modelo de parallelismo es el ultimo paso?
  
  * ParallelPrefix1(i,j)
    - if $i_p=j_p$
      - return x_{i_p}
    - $m_p \leftarrow \lfloor \frac{i_p + j_p}{2} \rfloor$;
    - if $p\leq m$ then
      - algo( i_p, m_p )
    - else
      - algo(m+1, j_p)
      - y_p \leftarrow y_m . y_p
  
  * Otra forma de escribir el algoritmo (de p. 384 de
    "Introduction to Algorithms, A Creative Approach", Udi
    Manber):
  
     + ParallelPrefix1(left,right)
       - if $(right-left) = 1$
         - $x[right] \leftarrow x[left] . x[right]$
       - else
         - $middle \leftarrow (left+right-1)/2$
         - do in paralel
           - ParallelPrefix1(left,middle) \{assigned to $\{P_1 to P_{n/2}\}$\}
           - ParallelPrefix1(middle+1,right) \{assigned to $\{P_{n/2+1} to P_n\}$\}
         - for $i \leftarrow middle+1$ to $right$ do in paralel
           - $x[i] \leftarrow x[middle] . x[i]$
  
  
  * Notas:
  
    - este solucion *no* es EREW (Exclusive Read&Write), porque
      los procesadores pueden leer $y_m$ al mismo tiempo.
    - este solucion{\'o} es CREW (Concurrent Read, Exclusive Write).
  
   - Complejidad: 
  
     - $T_{A_1}(n,n) = 1+ T(n/2,n/2) = \lg n$
  
       (El mejor tiempo en paralelo con cualquier cantidad de
       procesadores.)
  
     - $W_{A_1}(n) = n + 2 W_{A_1}(n/2) - n\lg n$
  
     - $T_{A_1}(n,p) = T(n) + W_{A_1}(n)/p = \lg n + (n\lg n)/p$
  
     - Calculamos $p^*$, la cantidad {\'o}ptima de procesadores
       para minimizar el tiempo: 
       - $T(n) = W_{A_1}(n) /p^*$
       - $p^* = \frac{ W(n) }{ T(n) } = n$
  
     - Calculamos la eficiencia
  
       - $E_{A_1}(n,p^*) 
         = \frac{ T^*(n) }{ p^* T(n)+W(n) }
         = \frac{ n }{ n\lg n } 
         = {1 \over \lg n}$
  
       - es poco eficiente =(
  
       - Podríamos tener un algoritmo con 
         - la eficiencia del algoritmo secuencial 
         - el tiempo del algoritmo paralelo?
  
  
* Solucion paralela 2: mismo tiempo, mejor eficiencia 
  
  - Idea:
    
    El concepto es de dividir de manera diferente: par y impar
    (en vez de largo o pequeño).
  
  - Concepto:
    1. Calcular en paralelo $x_{2i-1}.x_{2i}$ en $x_{2i}$
       para $\forall i, 1\leq i \leq n/2$.
    2. Recursivamente, calcular todos los prefijos de 
       $E=\{ x_2,x_4,\ldots, x_{2i},\ldots, x_n \}$
    3. Calcular en paralelo los prefijos en posiciones impares,
       multiplicando los prefijos de $E$ por una sola valor. 
  
  - algo2(i,j)
  
    - for $d\leftarrow 1$ to $(\lg n)-1$
      - if $p=0 \mod 2^{d+1}$
        - if $p+2^d<n$ 
          - $x_{p+2^d} \leftarrow x_p . x_{p+2^d}$
    - for $d\leftarrow 1$ to $(\lg n)-1$
      - if $p=0 \mod 2^{d+1}$
        - if $p-2^d>0$ 
          - $x_{p-2^d} \leftarrow x_{p-2^d}.x_p$
  
  - visualizaci{\'o}n 
  
    0. 
    1. [0,1]
    2. 
    3. [2,3] [0,3]
    4. 
    5. [4,5]
    6. 
    7. [6,7] [4,7] [0,7]
    8. 
    9.  [8,9]
    10.
    11. [10,11] [8,11]
    12. 
    13. [12,13]
    14. 
    15. [14,15] [12,15] [8,15] [0,15]
  
  - Notas:
    - Este algoritmo es EREW
  
  - An{\'a}lisis
    - $T_2(n) = 2\lg n$
    - $W(n) = n + W(n.2) = n$
    - $T_2(n,p) = T(n) + W(n)/p = 2\lg n + \frac{n}{p}$
  
    - Calculamos la cantidad {\'o}ptima de procesadores para obtener
      el tiempo {\'o}ptima:
      - $T_2(n) = W(n) / p^*$ entonces
      - $p^* = {W(n) \over T(n)} = {n\over\lg n}$
  
    - $E_2(n,p^*) = { T^*(n) \over p^* T(n)+ W(n)}  \in O(1)$
       
     

5.4.8 Conclusion del Parallelismo: 
-----------------------------------

     1. Cual es la consecuencia del Lemma de Brent?

        - Concentrarse en $T(n)$ y $E(n)$
        - Pero saber aplicar el Lemma de Brent para programmar $T(n,p)$

     2. Cual (otra) tecnica veamos?
        
        - Mejorar la efficiencia con una parte secuencial (en
          parallelo) del algoritmo.

5.5 Conclusion Unidad 
======================
    * Vimos
      1. Aleatorizacion
      2. Aproximabilidad
      3. Paralelizacion / Distribucio
    * Contexto
      + son *extenciones* del contenido del curso
      + hay muchas otras
        - cryptografia
        - quantum computing
        - parameterized complexity
        - ...
      + La metodologia entre todas tiene una parte en comun:
        - Formalismo
          - Cotas superiores
          - Cotas inferiores
        - Adecuacion a la practica.

6 CONCLUSION del curso 
~~~~~~~~~~~~~~~~~~~~~~~
    SCHEDULED: <2010-11-18 Thu 12:00-13:30>

    * Unidades:

      1. Conceptos basicos
      2. Memoria Secundaria
      3. Tecnicas Avanzadas
      4. Extensiones

    * Temas

      - Implementacion y Experimentacion.

      - cotas inferiores 
        - lemma del ave
        - mínimo y m{\'a}ximo de un arreglo
        - búsqueda en un arreglo con distintas probabilidades de acceso
        - lemma del minimax (para aleatorizacion)
        - theorema de Yao-von Neuman

      - analisis 
        - en promedio 
          - de algoritmos deterministicos
          - de algoritmos aleatorizados
        - "adaptativa" para
          - torre de Hanoi y "Disk Pile" problema
          - busqueda ordenada (y codificacion de enteros)
          - problemas en linea
        - en Memoria Externa
          - Diccionarios
          - Colas de Prioridades
          - Ordenamiento
        - en dominio discreto y finito (afuera del modelo de comparacion)
          - inter/extra polacion
          - skiplists
          - hash
          - radix sort
        - de algoritmos en linea ("online")
          - "competitive analysis"
        - de esquemas de aproximacion
          - "bin packing"
          - "Vertex Cover"
          - "Traveling Salesman"
          - "Backpack"
        - amortizada
          - enumeracion de enteros en binario
          - min max
        - en el modelo PRAM
          - max
          - ranking en listas
          - prefijos


            

[1] FOOTNOTE DEFINITION NOT FOUND: 1

[2] FOOTNOTE DEFINITION NOT FOUND: 0

