miércoles, 17 de agosto de 2016

¡Qué importa, mi código ya funciona!

Notación BigO 



Me he topado con entrevistas de trabajo sobre todo en Oracle, en las que hacen hincapié en el tema de la O grande o comúnmente conocida como BigO.



"La Notación BigO es la representación relativa de la complejidad de un algoritmo"


¿Cuál es el tiempo de complejidad de tu algoritmo?
¿Puedes mejorar el tiempo de complejidad de tu algoritmo?

Dos preguntas cruciales en las entrevistas de trabajo, las cuales podrás resolver a continuación.

Representación: Simplificar la comparación de algoritmos en una sola variable.
Relativa:
Comparación entre algoritmos similares.

Complejidad: Comportamiento del algoritmo cuando la entrada de datos aumenta. ¿Más memoria? ¿Más tiempo?



Existen varios tipos de complejidades, pero enlisto sólo las más comunes.

  • Complejidad Constante O(1)
  • Complejidad Logarítmica O(log n)
  • Complejidad Lineal O(n)
  • Complejidad Lineal-Logaritmica O(n log n)
  • Complejidad Cuadrática O(n2)

Donde n significa el número de datos a procesar.

Complejidad Constante O(1): Cantidad de datos es irrelevante, es decir, tardará el mismo tiempo en ejecutarse el algoritmo.

Ejemplos complejidad O(1) "Declaraciones simples"
Solo es una linea y para todos ellos la complejidad es constante.

int a=0;
a=5;
a++;

Ejemplos:
  1. Acceder al elemento de un arreglo
  2. Insertar un elemento en una lista ligada
  3. Añadir o sacar un elemento de una pila


Complejidad Logarítmica O(log n): El tiempo incrementa conforme aumenta el número de elementos, pero logarítmicamente, es decir, es muy corto tiempo.

Recordemos que el log es la inversa de la exponencial
Para esto: 

26=64  es decir: log2(64)=6


Ejemplo complejidad O(log n) "Divide y vencerás"
Buscar el mayor número de un arreglo [3,5,6,4,10], podemos ver que tenemos la opción mas sencilla a simple vista: recorrer todo el arreglo N=5.
Por lo tanto la complejidad seria O(N) o bien O(5)

¿Pero si en lugar de 5 fueran 130 elementos? Sería mayor el número de operaciones.

Realizar un algoritmo con complejidad O(log(n)) sería la mejor opción, es decir log130 sería un poco más de 7 (siete operaciones que se realizarían). 

La búsqueda binaria es el ejemplo más sencillo para entender esta complejidad.

1.- Ordenar arreglo
2.- Dividir en dos partes el arreglo e ir buscando sólo en la parte que contenga más próximo al número buscado, esto reducirá a 7 operaciones únicamente.



Ejemplos: 
  1. Búsqueda binaria.
  2. Encontrar el may-men elemento en un árbol de búsqueda binaria
  3. Algoritmo "Divide y vencerás"

Complejidad Lineal O(n): Cuán más grande sea la cantidad de datos, el tiempo de respuesta aumentará proporcionalmente.

Ejemplos complejidad O(n) "Ciclos sencillos"
El ciclo se iterará n veces

for(int i=0;i<n;i++)
{
           //declaraciones simples
}
Complejidad: O(n)
Ejemplos:
  1. Recorrer un arreglo o lista ligada
  2. Búsqueda lineal
  3. Comparar dos cadenas


Complejidad Lineal-Logarítmica O(n log n): Combinación de la lineal y la logarítmica, es común encontrarnos algoritmos de ordenamiento para esta categoría.

 Ejemplos: 

  1. Merge Sort
  2. Heap Sort
  3. Quick Sort
Ejemplo: Bucles donde la evolución de la variable de control no es lineal, junto a bucles con variable lineal. 

int c, x;  //O(1) 
for (int i=0;i<n;i++) {    //O(n)  variable de control lineal
    c=i;// O(1)
    while(c > 0) //O(log n)  variable de control no lineal
    {
         x = x % c;    //O(1)
         c = c / 2;      //O(1)
    }
    x+=2;  //O(1)
}

Complejidad: O(1) * O(n) * O(log n) = O(n log n)

Complejidad Cuadrática O(n2): El tiempo se dispara rápidamente, no es muy eficiente al tratarse de una gran cantidad de datos.

Ejemplos complejidad O(n2) "Ciclos anidados"
Se multiplica la complejidad exterior con la interior; n es el número de veces que se ejecutará el ciclo.

for(int i=0;i<n;i++)   O(n)
{
          for(int j=0;j<n;j++)     O(n)
         {
                 //declaraciones simples
         }
}

=O(n*n) = O(n2)

Ejemplos:

  1. Bubble Sort
  2. Selection Sort
  3. Iterar un arreglo de dos dimensiones


Sin Embargo...

¿Qué pasa si nuestro algoritmo no presenta ninguna de las categorías anteriores?

Ejemplo: O(n+3)
Sólo nos interesaría O(n) ya que conforme aumente n, la constante 3 sería insignificante.

Ejemplo: O(n2 +2n +3)
Sólo se toma O(n2) siendo la potencia más grande.

Cuando se analiza un algoritmo existen 3 diferentes casos:

  1. Best Case
  2. Average Case
  3. Worst Case

Wors Case, es el más representativo ya que nos indica la categoría de complejidad más alta. Por ejemplo un algoritmo de búsqueda lineal tiene complejidad O(n):


  1. Worst Case: Recorrer todo el arreglo O(n)
  2. Average Case: Recorrer la mitad de los elementos O(n/2)
  3. Best Case: Primer elemento es el buscado O(1)



Es muy importante analizar la complejidad de un algoritmo, ya que normalmente lo hacemos sólo con poca o mediana cantidad de datos que puede culminar en un tiempo aceptable, pero no estamos seguros si funcionará con una enorme cantidad de datos (millones).

Ejemplos: 

1.- Cuál es el tiempo y complejidad de espacio del siguiente código:
        int a = 0, b = 0;    //O(1)
        for (i = 0; i < N; i++) {  //O(N)
            a = a + rand();  //O(1)
        }
        for (j = 0; j < M; j++) { //O(M)
            b = b + rand(); //O(1)
        }
Se suman las 3. pero como en O(1)  1 es una constante. 
Asume que rand() es O(1).
  •  
  •  
  •  
  •  
  •  

2.- Cuál es el tiempo y complejidad de espacio del siguiente código:

int a = 0, b = 0;    //O(1)
    for (i = 0; i < N; i++) { //O(N)
        for (j = 0; j < N; j++) { //O(N)
            a = a + j;
        }
    }
    for (k = 0; k < N; k++) {  //O(N)
        b = b + k;
    } 
Los ciclos anidados representan O(N*N) más el segundo ciclo O(N), el espacio de complejidad sería O(1). Así bien, como O(N*N) + O(N), pero como O(N) sería insignificante comparándolo con O(N*N), sólo se deja este ultimo termino.


  •  
  •  
  •  
  •  
  •  
3.- ¿Cuál es la complejidad del siguiente código?
 int a = 0, i = N;
        while (i > 0) {
            a += i;
            i /= 2;
        }
En cada iteración podemos ver que i se convierte en i/2, en cada iteración i sería la mitad del valor de N. 
  •  
  •  
  •  
  •  
  •  

4.- ¿Cuál es la complejidad del siguiente código?

 int a = 0;
    for (i = 0; i < N; i++) {  //O(N)
        for (j = N; j > i; j--) { //O(N)
            a = a + i + j;
        }
    }
Como son ciclos anidados: O(N*N)
  •  
  •  
  •  
  •  

Conclusión: 



Un MUST de todo ingeniero de software respetable es tener conocimientos y aplicar el análisis de complejidad de algoritmos, de tal forma que pueda escribir programas eficientes y escalables a largo plazo.Es importante practicarlo, checando programas escritos previamente, analizarlos y tratar de encontrar su complejidad para ver de qué forma podemos mejorarlos; la próxima vez que escribamos código, detengámonos unos momentos a analizar la complejidad.







lunes, 4 de julio de 2016

Crear proyecto Oracle JET en NetBeans

Una vez instalado el JET, procedemos a crear un proyecto.

Seleccionamos la categoría y tipo de proyecto siguiente:

Damos un nombre y ubicación al proyecto y listo. Esta es la estructura que se genera.


Tenemos un proyecto vacío, vamos a descargar el Quick Start que esta en la página de internet para facilitarnos aun más el diseño. http://www.oracle.com/technetwork/developer-tools/jet/downloads/index.html en esa página, únicamente aceptamos los términos y condiciones y seleccionamos el Quickstart. Reemplazamos los archivos en nuestro proyecto. Ejecutamos y tenemos ahora una plantilla.



Instalar Plugin JET Oracle

JET (JavaScript Extention Toolkit)

He decidido prepararme en el nuevo plugin de Oracle, estuve en un taller introductorio realizado en el Campus Party 2016 en Guadalajara, es por eso que comienzo con el aprendizaje de este plugin para desarrollo web. Utiliza HTML5, CSS3, JavaScript, JQuery, JQueryUI, Knockout.

En este post realizaremos la instalación correcta y creacion del proyecto con JET.

REQUERIMIENTOS: (en mi caso usare netbeans para facilitarme la vida, aunque únicamente descargando e importando librerías con un editor cualquiera seria suficiente).
  • NetBeans
  • Conexión a Internet para descargar el Plugin

INSTALACIÓN:

1.- En el menu Tools de netbeans ubicar la opcion Plugins, posicionarnos en la pestaña "Available Plugins" dar clic en el botón "Check for newest", y buscamos mediante el campo de busqueda JET. 

Aparecera Oracle JET support, lo seleccionamos y lo instalamos. Reiniciamos el entorno de desarrollo (Netbeans) para que se apliquen los cambios y poder usar proyectos con JET.

jueves, 9 de junio de 2016

INSTALAR IREPORT (CORREGIR ERROR JDK 8 )



A continuación muestro cómo corregir el error que tiene iReport al no iniciar una vez instalado normalmente.

1.- Descargar el .exe de la pagina oficial: http://community.jaspersoft.com/project/ireport-designer/releases (Version 5.6.0) a la fecha.
2.- Ejeutar instalador y seguir los pasos normalmente como cualquier programa.
3.- No se ejecuta el iReport, no abre.

SOLUCION

iReport no es compatible con JDK8 (actual a la fecha), si tenemos ese instalado hay que desinstalarlo junto con el Java Update 8.

Instalar JDK 7 (se instala automaticamente Java Update 7). Instalar ambas versiones 32 y 64. ¿Porqué? no sé pero así me funcionó.

Buscamos la ruta del JDK 7 (normalmente es: C:\Program Files\Java\jdk1.7.0_79 ) la copiamos y nos dirigimos a la carpeta del Jaspersoft ( C:\Program Files (x86)\Jaspersoft\iReport-5.6.0\etc ). Ahí encontraremos el archivo "ireport.conf" el cual abriremos con el editor de texto y modificamos la siguiente linea: #jdkhome="/path/to/jdk" 
por la siguiente: jdkhome="C:\Program Files\Java\jdk1.7.0_79"
Quitando el # que significa comentario y poniendo la ruta de nuestro jdk 7.

Una vez modificado, nuestro iReport funcionará correctamente.