






















Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Asignatura: ESTRUCTURA DE DATOS, Profesor: UEMC UEMC, Carrera: Ingeniero Técnico de Telecomunicación, especialidad en Sistemas Electrónicos, Universidad: UVA
Tipo: Apuntes
1 / 30
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!























Un algoritmo es una secuencia finita de instrucciones precisas y no ambiguas, que colaboran todas ellas juntas para realizar una tarea que resuelva un problema.
Un algoritmo debe ser finito.
A la hora de evaluar un algoritmo, seguiremos unos criterios de eficiencia. A la hora de elegir entre varios algoritmos, utilizaremos 2 criterios básicos, veces contradictorios entre ellos:
La importancia de los criterios depende de:
Este tiempo dependerá de:
Tamaño de la entrada nº de datos En ocasiones suele decirse “Magnitud de la entrada”
Cada paso es independiente del sgteLa forma de resolverlo se va a basar en seguir una serie de decisiones
Cada paso influye en el sgte
Lo que más influye
Se expresa en función del tiempo que necesita para ejecutarse y del espacio que ocupa en memoria. En general, se realiza en función del tamaño de entrada (entendiéndose como entrada al nº de elementos de entrada).
En ocasiones se entiende por tamaño de entrada algo distinto, es decir, la magnitud de la entrada. Ejemplo: calcular si 37 es primo frente a 1654827. El tamaño de la entrada es el mismo, pero no la magnitud
T(n) ≡ tiempo que tarda en ejecutarse un algoritmo para una entrada de tamaño “n” E(n) ≡ espacio de memoria que necesita un algoritmo para ejecutarse, considerando un tamaño de entrada “n”
Estas dos medidas siempre van a estar referidas al peor de los casos : el que proporciona el peor tiempo de ejecución.
Ejemplo: ordenar un vector de 10 elementos
Para un tamaño fijo de “n”
Algoritmo de ordenación de burbuja de un vector v=[1,…n] de enteros
v: vector[1,…n] de enteros Para i←1 hasta n-1, i+ Para j←n hasta i+1, j-
Si v[j-1] > v[j] entonces 1
temp←v[j] 1 v[j-1]←v[j] 1 v[j]←temp 1 fin_si fin_para fin_para
Si n→∞ ⇒ T(n) ≈ n 2
Notación matemática utilizada para representar los tiempos que tardan los algoritmos, esto es, el tiempo que tarda en ejecutase un algoritmo en función del tamaño de entrada.
Se definen tres tipos de notación:
4*(n-i)
f(n) nunca se va a comportar peor que g(n), porque g(n) es su cota superior. Cuando el tiempo de ejecución de un algoritmo es O(g(n)) se dice que tiene una velocidad de crecimiento, o un orden de complejidad temporal, de g(n). La acotación superior se usa para representar el peor de los casos.
Cota superior de f (n)
REGLA DE LA SUMA Los términos g(n) y h(n) han de ser positivos
Comprobar que f(n)=3n^2 +2n-5 es del orden de O(n 2 )
Para ello debemos probar que: 3n 2 +2n-5 ≤cn 2
Despejando c, obtenemos que c=5 por lo que: 3n 2 +2n-5 ≤5n 2 Diremos entonces que: f(n) Є O(n 2 )
Comprobar si f(n)=(n+1) 2 Є O(n 2 )
Según la notación vista anteriormente, se debe probar que: (n+1) 2 ≤ cn^2
Otra forma de resolverlo es: f(n)=f1(n)+f2(n)+f3(n)= n 2 +2n+
f1(n) Є O(n 2 ) f2(n) Є O(2n) f3(n) Є O(1)
Toda función está acotada superiormente por ella misma
Comprobar si f(n)=3n^3 + 2n^2 Є O(n 3 )
Primera forma de resolverlo, según la definición: 3n 3 + 2n^2 ≤ cn^3
n=1 c≥ 5 n=2 c≥ 4
La otra forma de resolverlo: f(n)=f1(n)+f2(n)= 3n^3 + 2n 2
f1(n) Є O(3n 3 )
Regla de la suma: n^2 +2n+1 Є O(máx{n^2 ,2n,1}) n^2 +2n+1 Є O(n^2 ) ⇒ f(n) Є O(n 2 )
Regla de la suma: 3n^3 +2n 2 Є O(máx{3n^3 , 2n^2 }) 3n^3 +2n 2 Є O(n^3 ) ⇒ f(n) Є O
daríamos
daríamos
Ejemplo: supongamos un algoritmo tal que su T (^) promedio(n) Є Θ (f(n)) ¿ T (^) peor
Tpromedio (n) Є Θ (f(n))
Vamos a ver las principales técnicas de diseño de algoritmos: ♥ Recursividad ♥ Divide y vencerás ♥ Fuerza bruta ♥ Backtracking o vuelta atrás ♥ Algoritmo voraces ♥ (^) Programación dinámica
Definición
Un módulo es recursivo cuando dentro de su ejecución existen una o varias llamadas a sí mismo.
Por composición:
Ejemplo: el factorial de un número n! =n*(n-1)!
Propiedades
a. Deben existir uno o varios caso base donde no se haga uso de la recursividad Es decir, deberá haber un caso en el que se pare la recursividad porque si no será un bucle infinito. El tamaño de la entrada E es cada vez menor hasta llegar al caso base (cada vez son problemas más sencillos)
Ejemplo: en el caso anterior, (n-1)! es más sencillo que n!
IF n = 1 THEN FACT := 1 ELSE FACT := n ***** FACT(n-1) END;
Operación de comparación
Operación de asignación
Operación de asignación + producto
Para averiguar cuál es la complejidad del algoritmo, hacemos uso del análisis teórico, puesto que dispongo de las líneas de código:
Ecuaciones de recurrencia
Hay dos formas para resolver una ecuación de complejidad, dependiendo de la estructura que posea:
Ejemplo: en el caso del factorial c = 4
Nº de llamadas recursivas
Tiempo de las ops recursivas
Ops no recursivasa ≡ nº llamadas recursivas n-b ≡ tamaño de la entrada en la llamada recursiva c*nK^ ≡nº operaciones no recursivas
Prueba de corrección
Para demostrar que un algoritmo recursivo funciona: a. Tiene que existir un salida no recursiva en el algoritmo b. Cada llamada recursiva se refiere siempre a un problema más sencillo c. Supuesto que las llamadas recursivas funcionan, el algoritmo debe funcionar
Ejemplo: en el caso del factorial
Ejemplo: Secuencia de Fibonacci
La sucesión de Fibonacci es la sucesión infinita de nº naturales tales que 0 1 1 2 3 5 8 13
Versión recursiva del método:
Algoritmo fibonacci Entrada entero n
Operación comparación Salida entero n
Operación asignación Si n≤2 entonces Devolver n
Operación lógica + asignación Si_no Devolver fibonacci (n-1)+fibonacci (n-2)
Al igual que antes, calculamos la complejidad del algoritmo como:
Puesto que (n-1)>(n-2), lo que estoy dando es una cota superior a mi problema:
Según esta fórmula:
Fib(2) + Fib(1) = Fib (3)
Fib(0) + Fib(1) = Fib (2)
Fib(1)Fib(0)
Es irresoluble no es acotable, es infinito Para n=
Hemos calculado 8 veces los casos base Se dice que es un problema superpuesto (calculo muchas veces lo mismo, el mismo subproblema) esto provoca el orden exponencial. A medida que aumenta n, este problema aumenta de escala y por lo tanto, estamos calculando muchas veces los mismos subproblemas.
Los problemas que presentan estas características se llaman ALGORITMOS SE PROBLEMAS SUPERPUESTOS.
Versión iterativa del método:
Algoritmo fibonacci entrada entero n salida entero n local entero anterior, actual, x, i si n≤2 entonces Devolver n anterior:=0, actual:= para i=2 hasta n x:=anterior anterior:=actual actual:=actual+x fin_para devolver actual
Los problemas recursivos y superpuestos no pueden ir juntos, se repelen.
Resumen: un problema se divide en subproblemas. Estos subproblemas son más sencillos porque la entrada es menor. Este subproblema se dividirá a su vez en un subproblema trivial.
Definición
Orden exponencial Fib(5)Fib(4)Fib(3)Fib(3)Fib(2)Fib(2)Fib(1) Fib(1)Fib(0)Fib(1)Fib(0)Fib(1)Fib(2)Fib(1)Fib(0)Conseguimos reducir la complejidad. Ésta pasa a ser O(n) Lineal resoluble
La complejidad del algoritmo es:
Realmente no es un divide y vencerás porque el tamaño de entrada NO SE REDUCE NOTABLEMENTE, ya que sólo se reduce en 1 unidad. En un buen “Divide y vencerás”, cada subproblema debería ser de tamaño: n, n/2, n/4,… hasta llegar a una entrada de tamaño 1. En este ejemplo, esto supondría llegar a un vector de 1 elemento.
Ejemplo: Búsqueda de un elemento en un vector (II)
Una forma alternativa de buscar un elemento de un vector es:
FUNCTION BUSQUEDA (VAR V: TVECTOR; I,J,X: INTEGER): BOOLEAN VAR MED: INTEGER BEGIN IF I>J THEN BUSQUEDA := FALSE ELSE_IF J-I=
BUSQUEDA := TRUE ELSE BEGIN MED : = (I+J) DIV 2 BUSQUEDA := BUSQUEDA (V,I,MED,X) OR BUSQUEDA (V,MED+ 1 , J,X) END; END;
n
El tamaño de la entrada se ha decrementado en una unidad
XSegunda mitad del Є (I,J) vector
Primera mitad del vectorJIMED
n/2 n/
n/
Análisis de la complejidad:
A pesar de utilizar el divide y vencerás, no hemos conseguido nada porque sigue siendo lineal e incluso ha empeorado ligeramente (porque a=2).
Ejemplo: Búsqueda de un elemento en un vector (III)
Supongamos que el vector está ordenado ascendentemente. MED : = (I+J) DIV 2
FUNCTION BUSQUEDA (VAR V: TVECTOR; I,J,X: INTEGER): BOOLEAN VAR MED: INTEGER BEGIN MED : = (I+J) DIV 2 IF V[MED]=X THEN
BUSQUEDA := TRUE ELSE_IF V[MED] > X THEN
BUSQUEDA (V,I,MED- 1 ,X) ELSE BUSQUEDA (V,MED+ 1 ,J,X) END;
Análisis de la complejidad:
Ejemplo: Potencia entera (an^ )
a Є R+^ , n Є Z +
MEDIMEDMEDIMEDMEDJMED +1JI………Desecho la parte derecha del vector X Є (I,MED)
Desecho la parte izq del vectorSi se hace una búsqueda no se hace la otra, por eso X Є (MED,J) a=1 y no a=
Log(n) es mejor comportamiento que “n”
Las características de ésta y las demás estrategias:
Cumplen todas un esquema general:
Ejemplo: Problema de las N-Reinas
Se basa en que dispongo de un tablero de ajedrez de N*N de tal forma que se basa en hallar la disposición de las N Reinas de forma que ninguna de ellas esté en peligro (la reina avanza hacia adelante, atrás o en diagonales).
La estrategia de fuerza bruta explora todas las posibilidades.
Hay que tomar N decisiones: ¿Dónde coloco a cada una de las reinas? Árbol de decisiones:
Hay un total de N*N tableros