Está en la página 1de 9

Guía de estudio.

Transformación de
algoritmos
Profesor Adrián Rivero Jiménez.

Bloque VIII. Transformación de algoritmos. 2


Diferentes algoritmos de ordenación 2
Evaluación en tiempo y/o espacio de los diferentes algoritmos 2
Problemas tratables e intratables 4
Clasificación de problemas 6
Consulta de fuentes 8
2
Bloque VIII. Transformación de algoritmos.

Diferentes algoritmos de ordenación


El ordenamiento por burbuja es el algoritmo más sencillo probablemente. Ideal para
empezar. Consiste en ciclar repetidamente a través de la lista, comparando elementos
adyacentes de dos en dos. Si un elemento es mayor que el que está en la siguiente
posición se intercambian. Es un algoritmo estable. El inconveniente es que es muy
lento.

El ordenamiento por inserción técnicamente es la forma más lógica de ordenar


cualquier cosa para un humano, por ejemplo, una baraja de cartas. Requiere O (n²).

Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado.


Después, cuando hay k elementos ordenados de menor a mayor, se toma el elemento
k+1 y se compara con todos los elementos ya ordenados, deteniéndose cuando se
encuentra un elemento menor (todos los elementos mayores han sido desplazados
una posición a la derecha). En este punto se inserta el elemento k+1 debiendo
desplazarse los demás elementos.

Por último, el ordenamiento por selección: Al igual que el algoritmo de inserción es


muy trivial, puesto que recorre el vector o la lista, buscando el elemento más pequeño
y colocándolo en la posición 0 del vector, y así sucesivamente n-1 veces, tanto de
grande como sea el vector. Al igual que los algoritmos anteriores, requiere O (n²).

Evaluación en tiempo y/o espacio de los diferentes algoritmos


La característica básica que debe tener un algoritmo es que sea correcto, es decir, que
produzca el resultado deseado en tiempo finito. Adicionalmente puede interesarnos
que sea claro, que esté bien estructurado, que sea fácil de usar, que sea fácil de
implementar y que sea eficiente.
3

Entendemos por eficiencia de un algoritmo la cantidad de recursos de cómputo que


requiere; es decir, cuál es su tiempo de ejecución y qué cantidad de memoria utiliza.
A la cantidad de tiempo que requiere la ejecución de un cierto algoritmo se le suele
llamar coste en tiempo mientras que a la cantidad de memoria que requiere se le suele
llamar coste en espacio.
Es evidente que conviene buscar algoritmos correctos que mantengan tan bajo como
sea posible el consumo de recursos que hacen del sistema, es decir, que sean lo más
eficientes posible. Cabe hacer notar que el concepto de eficiencia de un algoritmo es
un concepto relativo, esto quiere decir que ante dos algoritmos correctos que resuelven
el mismo problema, uno es más eficiente que otro si consume menos recursos. Por
tanto, podemos observar que el concepto de eficiencia y en consecuencia el concepto
de coste nos permitirá comparar distintos algoritmos entre ellos. Si consideramos los
algoritmos elementales de ordenación por selección y por inserción ¿cómo podríamos
elegir cuál de ellos utilizar en una aplicación dada?

Veremos más adelante que para efectos prácticos ambos algoritmos son similares y
que son eficientes sólo para ordenar secuencias con un número pequeño de
elementos. Sin embargo hay varias comparaciones que se pueden hacer entre ellos.

De la tabla anterior podemos inferir que para ordenar secuencias cuyos elementos
sean difíciles de comparar (las comparaciones son caras) es más conveniente utilizar
el método de ordenación por inserción, y que este método es más eficiente mientras
más ordenada esté la secuencia de entrada. Si por el contrario queremos ordenar
secuencias de elementos que son fáciles de comparar (o que tienen claves asociadas
4
fáciles de comparar) y en cambio los intercambios son caros sería más conveniente
utilizar el algoritmo de ordenación por selección.
En general, ¿cómo podemos elegir entre un algoritmo y otro si ambos resuelven el
mismo problema? Una posibilidad es hacerlo mediante pruebas empíricas. En este
caso habría que traducir ambos algoritmos a un lenguaje de programación, realizar
medidas del tiempo de ejecución de los programas cuando se aplican a un conjunto
de muestras de entrada y a partir de estas medidas intentar inferir el rendimiento de
los programas. Pero este método tiene varios inconvenientes ya que los resultados
dependen:
● del subconjunto de pruebas escogidas
● del ordenador en el que se realicen las pruebas
● del lenguaje de programación utilizado o
● del compilador, entre otros factores.
Además, no siempre es fácil implementar un algoritmo (algunos pueden ser muy largos
o complicados), por tanto, en muchas ocasiones puede ser muy útil poder predecir
cómo va a comportarse un algoritmo sin tenerlo que implementar. Para ello es
conveniente analizar un algoritmo matemáticamente.
Ejemplo. Análisis de la función pos min, que encuentra la posición del elemento mínimo
en un vector de enteros.

El coste en tiempo de un algoritmo depende del tipo de operaciones que realiza y del
coste específico de estas operaciones. Este coste suele calcularse únicamente en
función del tamaño de las entradas para que sea independiente del tipo de máquina,
lenguaje de programación, compilador, etc. en que se implementa el algoritmo.

Problemas tratables e intratables


El concepto de correctitud de un algoritmo debe no sólo incluir el hecho de que el
algoritmo realice lo especificado, sino también que lo realice con los recursos
disponibles, los recursos más limitados en la producción de software son: el tiempo de
ejecución (medido en cantidad instrucciones elementales), la memoria para el
5
almacenamiento de los datos (medida en general en cantidad de variables
elementales). Se denomina a estas funciones medidas de complejidad, las medidas
de complejidad interesantes no pueden ser estáticas (constantes para todas las
instancias), sino dinámicas (dependen de la instancia a la cual se aplica el algoritmo).
Entonces no será factible estudiarlas para cada instancia en particular; se definen para
todas las instancias de un determinado tamaño, en el peor caso el estudio de la
eficiencia de los algoritmos no puede ser atacado por el argumento “las computadoras
del futuro serán increíblemente rápidas y por lo tanto no interesará que el algoritmo
sea eficiente”.

El ejemplo de los números de Fibonacci; o el hecho de que sin una mejora algorítmica
se pueda resolver el problema del viajante para cien ciudades toma cien millones de
años; o la factorización de un número de 300 dígitos que tarda un millón de años,
refutan esta hipótesis para resolver estos problemas se necesita una mejora en los
algoritmos; pero no una pequeña mejora sino una mejora en órdenes de magnitud por
ejemplo, una búsqueda secuencial en un arreglo ordenado es de Θ(n) en el peor caso;
una búsqueda binaria es de Θ(log n). Para instancias pequeñas la diferencia puede no
ser notable, pero para n = 109 la diferencia está entre esperar un año o un minuto por
el resultado dado, un algoritmo que resuelve un problema, es razonable (y
aconsejable) preguntarse si no existirá un algoritmo más eficiente para el mismo
problema.

El objetivo fundamental de la Complejidad Computacional es clasificar los problemas


de acuerdo a su tratabilidad, tomando el o los algoritmos más eficientes para
resolverlos, esto es, poder determinar las respuestas a las siguientes preguntas:
¿Cuán tratable es el problema?, Si el problema es tratable, ¿es el algoritmo
suficientemente eficiente?, si se demuestra que el problema no admite soluciones
mejores, entonces se puede afirmar que el algoritmo es eficiente (salvo constantes
ocultas!!)
6
Clasificación de problemas

De acuerdo a los recursos indispensables para su solución hay tratables e intratables.


En general, los distintos grados de tratabilidad son muy subjetivos (varían mucho de
acuerdo al modelo computacional, los recursos disponibles, las variantes de las
estructuras de datos, etc.), por lo tanto un objetivo primario del estudio de la
complejidad es definir cuáles problemas son tratables, y cuáles no. Recién después
de esto se pueden considerar distintos grados de tratabilidad o intratabilidad, por
ejemplo, se puede afirmar que la mayoría de los problemas vistos en la materia son
tratables: o sea tienen solución para instancias grandes, y una mejora algorítmica o
una mejora en el HW produce una gran ampliación en el conjunto de instancias que
se pueden resolver, en cambio, hay problemas que no son tratables: el problema de
las torres de Hanoi, o el problema del viajante, en la práctica sólo se resuelven para
instancias pequeñas. No solo problemas con respuestas difíciles son intratables. Otro
problema intratable es el denominado MONKEY PUZZLE, una especie particular de
rompecabezas, en el que si se tiene un tablero de n×n, no se conoce algoritmo mejor
que probar todas las permutaciones posibles para resolverlo, esto es Ω(n!), para n =
5, generando un millón de configuraciones por segundo, se tardaría 490.000 millones
de años en resolverlo esta evidencia empírica ha permitido acordar (una especie de
tesis de Turing-Church para la complejidad) que si un problema admite una solución
polinomial entonces se trata de un problema tratable; en caso contrario se lo considera
intratable.

El límite de tratabilidad entre algoritmos polinomiales y super-polinomiales es arbitrario,


pero mayoritariamente aceptado. Por ejemplo, 1,00001n o n log2 n serían intratables,
mientras que n 10000 o 100000000000n sería tratables, el punto es que estas
funciones extremas raramente aparecen en casos reales como tiempo de ejecución
de algoritmos además, problemas como PROGRAMACIÓN LINEAL, con soluciones
eficientes en general pero no polinomiales en el peor caso (Algoritmo Simplex), se
demostraron tener solución polinomial.
7
Los algoritmos de O(nk) son considerados de tiempo razonable a pesar del k y de las
posibles constantes ocultas para el espacio de memoria se tiene que tener más
cuidado,
porque ya un espacio polinomial muchas veces es intratable, las funciones
exponenciales y factoriales siempre son intratables además, dentro de esta tratabilidad
y de esta intratabilidad es posible distinguir varios grados, otro tema de investigación
actual es la extensión del concepto de tratabilidad a algoritmos probabilísticos y
paralelos. En estos casos se han propuesto otras formalizaciones para tener una mejor
idea de la diferencia entre tratable e intratable: para comparación: el número de
protones en el universo es de 79 dígitos, y el número de microsegundos transcurridos
desde el Big Bang es de 24 dígitos. Esto significa que si suponemos que se ejecutan
k instrucciones por microsegundo, los algoritmos tardan para comparación: se
considera que el Big Bang ocurrió hace aproximadamente 15.000 millones de años
esto demuestra que los problemas intratables no se resuelven comprando hardware;
es una característica intrínsica del problema el hecho de que solo se resuelvan
instancias pequeñas.
8
Consulta de fuentes

Ashish Prasad (18/12/2018), How to write a pseudo code?. Recuperado el 10 de


septiembre de 2020 de https://www.geeksforgeeks.org/how-to-write-a-pseudo-code/

Lucidchart , What is a flowchart?. Recuperado el 10 de septiembre de 2020 de


https://www.lucidchart.com/pages/what-is-a-flowchart-tutorial

Zamoszczyk Claudio, De Luca Sebastián, Ruiz Martínez Sebastián, Iturbide Lucas


(2012), Human Query Language. Recuperado el 11 de septiembre de 2020 de
https://www.palermo.edu/ingenieria/pdf2013/12/12CyT_03humanquerylanguage.pdf

Moreno Antonio, (17/10/2017). Procesamiento del lenguaje natural, ¿qué es?.


Recuperado el 11 de septiembre de 2020. https://www.iic.uam.es/inteligencia/que-es-
procesamiento-del-lenguaje-natural/

García Cano Edgar E., Solano Galvez Jorge A.. Guía práctica de estudio 05:
Diagramas de Flujo. Recuperado el 13 de septiembre de 2020. http://odin.fi-
b.unam.mx/salac/practicasFP/fp_p5.pdf

Ramírez Felipe, (2007). Introducción a la programación. Algoritmos y su


implementación en Visual Basic .Net, C#, Java y C++. (2a ed.). México. Alfaomega.

Recursion. Recuperado el 10 de octubre de 2020.


https://www.cs.utah.edu/~germain/PPS/Topics/recursion.html

Harvey M. Deitel & Paul J. Deitel, (2007). Como programar en C#. (2a ed.). México.
Pearson Educacion.
9
Sara Álvarez, (07/02/2006). Tipos de lenguajes de programación. Recuperado el 11
de octubre de 2020. https://desarrolloweb.com/articulos/2358.php

Domingo Gallardo y Cristina Pomares, (2013). Lenguajes y Paradigmas de


Programación. Recuperado el 11 de octubre de 2020.
http://www.dccia.ua.es/dccia/inf/asignaturas/LPP/2013-14/teoria/Tema01-
HistoriaLenguajesProgramacion.html#paradigmas-de-programaci%C3%B3n

Alejandro Alcalde, (22/09/2017). Algoritmos de ordenación. Recuperado el 11 de


octubre de 2020. https://elbauldelprogramador.com/algoritmos-de-ordenacion/

Amaia Duch, (Marzo 2007). Análisis de Algoritmos. Recuperado el 11 de octubre de


2020. https://www.cs.upc.edu/~duch/home/duch/analisis.pdf

También podría gustarte