Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
algoritmos Clase 2
Contenido
Eficiencia algortmica
Notacin Big Oh
Ejercicios del curso
Tips & tricks
Qu es un algoritmo?
Un algoritmo es un conjunto ordenado de instrucciones
bien definidas, inambiguas y finitas que permite resolver
un determinado problema computacional.
Un corolario de esta definicin es que un determinado
problema computacional puede ser resuelto por diversos
(infinitos) algoritmos.
Veamos una demostracin de esto
Nota
Para este y todos los ejercicios que veremos en clase:
paciencia para los que ya saben y mucha concentracin
para los que se sientan perdidos.
Qu es un algoritmo?
Esta caracterstica (mltiples alternativas para resolver
un mismo problema) es la motivacin de este curso:
disear buenos (si no los mejores) algoritmos para
solucionar determinados problemas.
Quiz el principio ms importante para el buen diseador de
algoritmos es negarse a estar satisfecho
Aho et al. (1974) The design and analysis of computer algorithms
Notacin Big Oh
Definicin formal:
T(n) = O(f(n)), si y solo si existen dos constantes c, n0 > 0
de forma que T(n) c*f(n) para todo n>n0
En trminos prcticos:
Considerar el peor escenario
Realizar un anlisis asinttico (enfocarse en
valores grandes de n)
No prestar atencin a trminos constantes o de
orden menor
En el ejemplo del selectSort podemos decir entonces que
T(n) = 2 , o lo que es lo mismo, que es O(2 )
Comparacin de eficiencias
Habiendo comprendido el concepto de la notacin Big O,
cul es el orden de complejidad o eficiencia del
bubbleSort?, por qu?
function bubbleSort(X[], n){
for i=n-1:1 {
ordenado = true;
for j=0:i-1 {
if (X[j] > X[j+1]){
switch(X[j], X[j+1])
ordenado = false;
}
}
if ordenado = true: break
}
}
Comparacin de eficiencias
Volviendo al ejercicio de street numbers, determinemos
cul de los siguientes algoritmos es mejor.
function sn1(n){
if n<3: return -1
for i=2:n-1{
s1 = 0
for j=1:i-1{
s1 += j
}
s2 = 0
for k=i+1:n{
s2 += k
}
if s1=s2: return i
}
return -1
}
O(2 ) cuadrtica
function sn2(n){
if n<3: return -1
for i=2:n-1{
s1 = i*(i-1)/2
s2 = (n*(n+1)-i*(i+1))/2
if s1=s2: return i
}
return -1
}
function sn3(n){
if n<3: return -1
i = sqrt((n^2+n)/2)
if i = INT(i): return i
return -1
}
O(1) constante
O(n) lineal
Considerando que
(+1)
=
=1
2
Cambiando el condicional
por una igualdad y luego
despejando
Comparacin de eficiencias
Ejercicio: Considerando la notacin Big O, determinemos
cul de los dos siguientes algoritmos es mejor.
function fib1(n){
if n <= 1: return n
else return fib1(n-1) + fib1(n-2)
}
function fib2(n){
f[0] = 0, f[1] = 1
for i = 2:n{
f[i] = f[i-1] + f[i-2]
}
return f[n]
}
O(2 )
O(n)
en realidad
O( )
siendo =
1+ 5
2
Comparacin de eficiencias
Supongamos que estamos trabajando en un computador con procesador de un solo
ncleo a 3,2Ghz lo que nos da un aproximado de 1,000,000,000 operaciones por
segundo. En la siguiente tabla vamos a relacionar el tamao de un problema
determinado con lo que demoraran en resolverlo una serie de algoritmos con
eficiencias diferentes.
log(n)
10
100
1000
10.000
100.000
1'000.000
1E+9 (mil millones)
1E+12 (un billn)
1E+15 (mil billones)
1E+18 (un trilln)
1E+21 (mil trillones)
1E+24 (un cuatrilln)
1E+27 (mil cuatrillones)
n.log(n)
n^2
n^3
2^n
3 nanosegs
10 nanosegs
33 nanosegs
100 nanosegs
1 microseg
1 microseg
7 nanosegs
100 nanosegs
664 nanosegs
10 microsegs
1 miliseg
4E+10 milenios
10 nanosegs
1 microseg
10 microsegs
1 miliseg
1 seg
13 nanosegs
10 microsegs
133 microsegs
100 milisegs
17 minutos
17 nanosegs
100 microsegs
2 milisegs
10 segs
12 dias
20 nanosegs
1 miliseg
20 milisegs
17 minutos
32 aos
30 nanosegs
1 seg
30 segs
32 aos
40 nanosegs
17 minutos
11 horas
50 nanosegs
12 dias
1 ao y medio
60 nanosegs
31 aos
19 siglos
70 nanosegs
317 siglos
80 nanosegs
90 nanosegs
Entrada de datos
Scanner vs. InputStreamReader
Scanner sirve para leer dato por dato especificndole el tipo de
cada uno
Scanner entrada = new Scanner(System.in);
int a = entrada.nextInt();
float b = entrada.nextFloat();
Entrada de datos
StringTokenizer vs. Split
StringTokenizer sirve para partir un string en tokens, es decir,
elementos individuales separados entre s por un delimitador.
Los delimitadores por defecto son: " \t\n\r\f, es decir, espacio en
blanco, caracter de tabulacin, caracter de nueva lnea, caracter
de retorno, y caracter de salto de pgina
StringTokenizer st = new StringTokenizer(linea);
while( st.hasMoreTokens() ){
String dato = st.nextToken();
//procesar dato, por ejemplo convertirlo a algn tipo
}
Entrada de datos
StringTokenizer vs. Split
Split hace lo mismo que StringTokenizer solo que adems
de permitir definir delimitadores especficos, tambin
permite usar expresiones regulares lo cual puede ser til si
se desea remover datos intiles de la entrada
String arr1[] = linea.split("-");
String arr2[] = linea.split("\\s+|,\\s*|.\\s+");
123.46
Java
Insercin
Indexacin
Bsqueda
Borrado
Arreglo
dinmico
ArrayList
O(n)
O(1)
O(log(n)) si
est
ordenado,
O(n) si no
O(1)
ListaEnlazada
LinkedList
O(1) si es al
inicio o al
final, O(n) si
no
O(1) para el
inicio o el
final, O(n) si
no
O(n)
O(1) para el
inicio o el
final, O(n) si
no
Pila
Queue
O(1) para el
push
O(1) para el
peek
O(n)
O(1) para el
pop
Cola
Deque
O(1) para el
push
O(1) para el
peek
O(n)
O(1) para el
pop
rbol binario
de bsqueda
balanceado
TreeSet
O(log(n))
No aplica
O(log(n))
O(log(n))
Montculo
binario
PriorityQueue
O(log(n))
No aplica
O(1) si es
para la cima,
O(n) si no
O(log(n)) si
es la cima,
O(n) si no
Tabla hash
HashMap
O(1)*
No aplica
O(1)*
O(1)*
Tareas
1. Para calentar motores en lo que a programar se
refiere, codificar los tres algoritmos de ordenamiento
mencionados (selectSort, insertSort, bubbleSort) en el
lenguaje que deseen. Luego probarlos con diferentes
tamaos de arreglos (100, 1.000, 10.000, 100.000,
1000.000). Hacer un grfico tamao vs tiempo de
ejecucin. Comprobar si tienen la forma n^2.
2. Hacer lo mismo con las funciones fib1 y fib2 pero para
los valores de n entre 5 y 20.
3. Realizar todos los ejercicios de calentamiento en la
plataforma.