├── 04_Simulacion ├── test └── Utils │ └── gutils.py ├── 05_BasesDeDatos ├── test ├── 04_HojasDeCalculo.ipynb └── .ipynb_checkpoints │ └── 04_HojasDeCalculo-checkpoint.ipynb ├── README.md ├── 00_Introduccion └── Interactivos │ ├── test │ ├── zinteractivo3.ipynb │ └── FD.py ├── 02_AlgoritmosOrdenamiento ├── 02_MergeQuick │ ├── test │ ├── utils │ │ └── figs │ │ │ ├── merge.PNG │ │ │ ├── merge.gif │ │ │ └── quicksort.jpg │ ├── 01_MergeQuick.ipynb │ └── .ipynb_checkpoints │ │ └── 01_MergeQuick-checkpoint.ipynb ├── 03_RadixBucket │ ├── test │ ├── utils │ │ └── figs │ │ │ ├── RadixSort.png │ │ │ └── BucketSort.jpg │ ├── .ipynb_checkpoints │ │ └── 01_RadixBucket-checkpoint.ipynb │ └── 01_RadixBucket.ipynb └── 01_Ordenamientos │ ├── utils │ └── figs │ │ ├── bubble.gif │ │ ├── RadixSort.png │ │ ├── insertion.gif │ │ ├── ordenjedi.png │ │ ├── selection.gif │ │ ├── BucketSort.jpg │ │ ├── pseudoselec.png │ │ └── pseudoinsertion.png │ ├── 04_pos_Ordenamientos.ipynb │ └── .ipynb_checkpoints │ └── 04_pos_Ordenamientos-checkpoint.ipynb └── 03_AlgoritmosBusqueda ├── 02_BusquedaBinaria └── utils │ └── figs │ ├── busBR.png │ └── esqbis.PNG ├── 05_TablasDeDispersion ├── utils │ └── figs │ │ └── poli.png ├── ManejodeDatos9180.txt └── inteligencia.txt ├── 04_ArbolesBinariosBusqueda ├── utils │ ├── figs │ │ ├── abb.gif │ │ ├── abb.png │ │ ├── avl.png │ │ ├── rid.gif │ │ ├── aavl.png │ │ ├── abb1.png │ │ ├── arbolb.png │ │ ├── minimo.gif │ │ ├── nodo.png │ │ ├── prueba.gif │ │ ├── rdi1.gif │ │ ├── busqueda.png │ │ ├── eliminar.png │ │ ├── insertar.gif │ │ ├── sderecha.gif │ │ ├── busqueda1.gif │ │ ├── busqueda2.gif │ │ ├── insertar2.gif │ │ └── simpleizq.gif │ └── src │ │ ├── __pycache__ │ │ ├── ArbolesBinarios.cpython-311.pyc │ │ ├── ArbolesBinarios.cpython-39.pyc │ │ ├── ArbolesBinariosBusqueda.cpython-311.pyc │ │ └── ArbolesBinariosBusqueda.cpython-39.pyc │ │ ├── ArbolesBinarios.py │ │ ├── .ipynb_checkpoints │ │ ├── ArbolesBinarios-checkpoint.py │ │ └── ArbolesBinariosBusqueda-checkpoint.py │ │ └── ArbolesBinariosBusqueda.py └── 00_ArbolAdivinador │ ├── utils │ └── figs │ │ ├── ad1.png │ │ ├── ad2.png │ │ ├── ad3.png │ │ └── nodo.png │ ├── 04_02_ArbolAdivinador.ipynb │ └── .ipynb_checkpoints │ └── 04_02_ArbolAdivinador-checkpoint.ipynb ├── 03_BusquedaDePatrones ├── 01_ManejoDeArchivos │ ├── ManejodeDatos9180.txt │ ├── ManejodeDatos9180.txt.1 │ └── .ipynb_checkpoints │ │ └── ManejodeDatos9180-checkpoint.txt └── 02_BusquedaDePatrones │ ├── ManejodeDatos9180.txt │ └── .ipynb_checkpoints │ └── ManejodeDatos9180-checkpoint.txt └── .ipynb_checkpoints └── 04_02_ArbolAdivinador-checkpoint.ipynb /04_Simulacion/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /05_BasesDeDatos/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MACTI-manejodatos -------------------------------------------------------------------------------- /00_Introduccion/Interactivos/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/03_RadixBucket/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/merge.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/merge.PNG -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/merge.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/02_BusquedaBinaria/utils/figs/busBR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/02_BusquedaBinaria/utils/figs/busBR.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/02_BusquedaBinaria/utils/figs/esqbis.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/02_BusquedaBinaria/utils/figs/esqbis.PNG -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/bubble.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/bubble.gif -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/quicksort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/02_MergeQuick/utils/figs/quicksort.jpg -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/03_RadixBucket/utils/figs/RadixSort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/03_RadixBucket/utils/figs/RadixSort.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/05_TablasDeDispersion/utils/figs/poli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/05_TablasDeDispersion/utils/figs/poli.png -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/RadixSort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/RadixSort.png -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/insertion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/insertion.gif -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/ordenjedi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/ordenjedi.png -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/selection.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/selection.gif -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/03_RadixBucket/utils/figs/BucketSort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/03_RadixBucket/utils/figs/BucketSort.jpg -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/avl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/avl.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/rid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/rid.gif -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/BucketSort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/BucketSort.jpg -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/pseudoselec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/pseudoselec.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/aavl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/aavl.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/abb1.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/arbolb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/arbolb.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/minimo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/minimo.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/nodo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/nodo.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/prueba.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/prueba.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/rdi1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/rdi1.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/eliminar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/eliminar.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/insertar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/insertar.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/sderecha.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/sderecha.gif -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/pseudoinsertion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/02_AlgoritmosOrdenamiento/01_Ordenamientos/utils/figs/pseudoinsertion.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda1.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/busqueda2.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/insertar2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/insertar2.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/simpleizq.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/figs/simpleizq.gif -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad1.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad2.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/ad3.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/nodo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/utils/figs/nodo.png -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinarios.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinarios.cpython-311.pyc -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinarios.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinarios.cpython-39.pyc -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinariosBusqueda.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinariosBusqueda.cpython-311.pyc -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinariosBusqueda.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugernaut/MACTI-manejodatos/principal/03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/__pycache__/ArbolesBinariosBusqueda.cpython-39.pyc -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/04_pos_Ordenamientos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [] 15 | } 16 | ], 17 | "metadata": { 18 | "kernelspec": { 19 | "display_name": "Python 3 (ipykernel)", 20 | "language": "python", 21 | "name": "python3" 22 | }, 23 | "language_info": { 24 | "codemirror_mode": { 25 | "name": "ipython", 26 | "version": 3 27 | }, 28 | "file_extension": ".py", 29 | "mimetype": "text/x-python", 30 | "name": "python", 31 | "nbconvert_exporter": "python", 32 | "pygments_lexer": "ipython3", 33 | "version": "3.11.6" 34 | }, 35 | "vscode": { 36 | "interpreter": { 37 | "hash": "0a68ab044c6ea367198d7b58f0f8352272d5267d2d2c131306c104f6e9ede3d6" 38 | } 39 | } 40 | }, 41 | "nbformat": 4, 42 | "nbformat_minor": 4 43 | } 44 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/01_Ordenamientos/.ipynb_checkpoints/04_pos_Ordenamientos-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [] 15 | } 16 | ], 17 | "metadata": { 18 | "kernelspec": { 19 | "display_name": "Python 3 (ipykernel)", 20 | "language": "python", 21 | "name": "python3" 22 | }, 23 | "language_info": { 24 | "codemirror_mode": { 25 | "name": "ipython", 26 | "version": 3 27 | }, 28 | "file_extension": ".py", 29 | "mimetype": "text/x-python", 30 | "name": "python", 31 | "nbconvert_exporter": "python", 32 | "pygments_lexer": "ipython3", 33 | "version": "3.11.6" 34 | }, 35 | "vscode": { 36 | "interpreter": { 37 | "hash": "0a68ab044c6ea367198d7b58f0f8352272d5267d2d2c131306c104f6e9ede3d6" 38 | } 39 | } 40 | }, 41 | "nbformat": 4, 42 | "nbformat_minor": 4 43 | } 44 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/05_TablasDeDispersion/ManejodeDatos9180.txt: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/03_BusquedaDePatrones/01_ManejoDeArchivos/ManejodeDatos9180.txt: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/03_BusquedaDePatrones/01_ManejoDeArchivos/ManejodeDatos9180.txt.1: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/03_BusquedaDePatrones/02_BusquedaDePatrones/ManejodeDatos9180.txt: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/03_BusquedaDePatrones/01_ManejoDeArchivos/.ipynb_checkpoints/ManejodeDatos9180-checkpoint.txt: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/03_BusquedaDePatrones/02_BusquedaDePatrones/.ipynb_checkpoints/ManejodeDatos9180-checkpoint.txt: -------------------------------------------------------------------------------- 1 | No Apellido Apellido 2 Nombre Carrera Correo Telefono 2 | 1 Alemán Galicia Diego Leónardo C. Computación alemanlex_plus_cool@hotmail.com 44-635-28-288 3 | 2 Amador Gónzalez Noé Eusebio Aplicadas noe.amadorg@ciencias.unam.mx 55-640-83-871 4 | 3 Amaro Islas Yamile Amalia Zulema Actuaría aminahelue@ciencias.unam.mx 55-4977-6159 5 | 4 Cabrera Pérez Rodrígo Actuaría rodri030100@gmail.com 55-477-61-948 6 | 5 Cazares Solis Andrea Nicole Actuaría nicolecazares141@gmail.com 55-539-42-382 7 | 6 Contreras Chávez Citlali Actuaría citlali.contreras.1999@gmail.com 55-399-75-350 8 | 7 Dorantes Bravo Alicia Aplicadas adorantes@ciencias.unam.mx 55-128-98-209 9 | 8 Durán Santiago Rafael Aplicadas rsanti955@gmail.com 333-72-554-55 10 | 9 Enríquez Ríos Michelle Guadalupe Actuaría michelle.0198.me@gmail.com 55-782-67-957 11 | 10 Flores Delgado Omar Alejandro Actuaría omaralejandro00g@gmail.com 55-665-72-227 12 | 11 Garcés Garduño Rodrígo Tonatihu Actuaría rodrigotonatihu@ciencias.unam.mx 55-244-10-361 13 | 12 García Azamar Cristopher Alejandro Actuaría crisazami_123@ciencias.unam.mx 46-928-422-65 14 | 13 García Mejía Randy Jesús Actuaría randy.jesus.garcia@gmail.com 55-580-24-293 15 | 14 Gómez Arteaga Beu Ribe Actuaría beu.ribega@gmail.com 55-789-33-403 16 | 15 Gónzalez García Maricela Actuaría marigonzalez_240100@hotmail.com 55-907-91-129 17 | 16 Guevara Legaspe Leslye Joseline Actuaría leslye_joseline@ciencias.unam.mx 55-121-67-977 18 | 17 Gúzman López Eduardo Gabriel Aplicadas eggl@ciencias.unam.mx 55-970-28-624 19 | 18 Hérnandez López Alejandro Actuaría trigranalex@ciencias.unam.mx 55-161-68-809 20 | 19 Juárez Diosdado Ulises Aplicadas ulisesu13@ciencias.unam.mx 55-497-22-370 21 | 20 Lerdo de Tejada Flores Miguel Actuaría miguel_lerdodetejada@yahoo.com.mx 55-7190-3848 22 | 21 Nuñez Vega Adive Alejandra Actuaría anv.ale558@gmail.com 5554-72-20-63 23 | 22 Núñez Sánchez Ruben Actuaría rubennu00@ciencias.unam.mx 55-660-99-872 24 | 23 Pérez Escartin Maya Aranzazu Actuaría aranzazu-08@hotmail.com 55-376-26-789 25 | 24 Ramírez Carmona Axel Gabriel Actuaría axel.ramirez@ciencias.unam.mx 55-812-56-695 26 | 25 Reséndiz Guerrero Mariella Vanesa Actuaría mariella_resendiz@yahoo.com 55-583-43-525 27 | 26 Rivera Ramírez María Fernanda Actuaría fer.loveswim.0408@gmail.com 55-489-59-362 28 | 27 Rodríguez Hérnandez Ricardo Aplicadas rimucaser@gmail.com 888-314-46-780 29 | 28 Rodríguez Rojas Aarón Israel Actuaría aaronrojas@ciencias.unam.mx 55-931-23-412 30 | 29 Rodríguez Vega Octavio Matemáticas octavius@ciencias.unam.mx 55-366-59-591 31 | 30 Salas Reyes Sac-Nicte Damayanti Aplicadas nictesalas@ciencias.unam.com 55-276-13-206 32 | 31 Salinas Avelino Elizabeth Actuaría eliza160900@ciencias.unam.mx 55-626-14-760 33 | 32 Sánchez Martínez Fabiola Sofía Actuaría sofysm99@gmail.com 55-461-15-303 34 | 33 Sánchez Valle Daniela Itzel Actuaría danielavalle@ciencias.unam.mx 77-174-67-488 35 | 34 Téllez Soto José Emanuel Aplicadas joseemanueltellezsoto@gmail.com 55-93680-510 36 | 35 Vásquez Martínez Andrea Lizbeth Actuaría andreavasquez115@gmail.com 55-687-34366 37 | 36 Zamarripa Ornelas Diego Mauricio Actuaría diego.zamarripa18@gmail.com 55-458-69-357 -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/05_TablasDeDispersion/inteligencia.txt: -------------------------------------------------------------------------------- 1 | Ahora que ya conoce la definición de la IA y más de su historia, la mejor forma de profundizar en el tema es conocer las principales técnicas de la IA, específicamente, los casos en los que la Inteligencia artificial se utiliza para los negocios. 2 | 3 | Aprendizaje automático 4 | Generalmente, el concepto de Aprendizaje automático se confunde con el de “IA débil”. Es en este campo en donde los avances más importantes de la IA se están llevando a cabo. En términos prácticos, “el Aprendizaje automático es la ciencia que se encarga de hacer que las computadoras realicen acciones sin necesidad de programación explícita”. La idea principal aquí es que se les puede proporcionar datos a los algoritmos de Aprendizaje automático y luego usarlos para saber cómo hacer predicciones o guiar decisiones. 5 | 6 | Algunos ejemplos de algoritmos de Aprendizaje automático incluyen los siguientes: diagramas de decisiones, algoritmos de agrupamiento, algoritmos genéticos, redes Bayesianas y Aprendizaje profundo. 7 | 8 | Aprendizaje profundo 9 | ¿Recuerda cuando Google anunció un algoritmo que encontraba videos de gatos en Youtube? (Si desea refrescar su memoria haga clic aquí). Pues bien, esto es Aprendizaje profundo, una técnica de Aprendizaje automático que utiliza redes neuronales (el concepto de que las neuronas se pueden simular mediante unidades computacionales) para realizar tareas de clasificación (piense en clasificar una imagen de un gato, de un perro o personas, por ejemplo). 10 | 11 | Algunos ejemplos de aplicaciones prácticas del Aprendizaje profundo son las siguientes: identificación de vehículos, peatones y placas de matrícula de vehículos autónomos, reconocimiento de imagen, traducción y procesamiento de lenguaje natural. 12 | 13 | Descubrimiento de datos inteligentes 14 | Es el próximo paso en soluciones de IE (Inteligencia empresarial). La idea consiste en permitir la automatización total del ciclo de la IE: la incorporación y preparación de datos, el análisis predictivo y los patrones y la identificación de hipótesis. Este es un ejemplo interesante de la recuperación de datos inteligentes en acción. La información que ninguna herramienta de IE había descubierto. 15 | 16 | Análisis predictivo 17 | Piense en ese momento en el que está contratando un seguro para auto y el agente le hace una serie de preguntas Estas preguntas están relacionadas a las variables que influyen en su riesgo. Detrás de estas preguntas se encuentra un modelo predictivo que informa sobre la probabilidad de que ocurra un accidente con base en su edad, código postal, género, marca de auto, etc. Es el mismo principio que se emplea en los modelos predictivos de crédito para identificar a los buenos y malos pagadores. Por lo tanto, el concepto principal de análisis predictivo (o modelado) significa que se puede utilizar un número de variables (ingresos, código postal, edad, etc.) combinadas con resultados (por ejemplo, buen o mal pagador) para generar un modelo que proporcione una puntuación (un número entre 0 y 1) que representa la probabilidad de un evento (por ejemplo, pago, migración de clientes, accidente, etc.). 18 | 19 | Los casos de uso en los negocios son amplios: modelos de crédito, modelos de segmentación de clientes (agrupamiento), modelos de probabilidad de compra y modelos de migración de clientes, entre otros. 20 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/ArbolesBinarios.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | # Clase Nodo necesaria para generar arboles binarios 4 | class Nodo(object): 5 | ''' 6 | Constructor de nodos 7 | dato: es el contenido del nodo 8 | ''' 9 | def __init__(self, dato): 10 | self.izq = None 11 | self.dato = dato 12 | self.der = None 13 | self.padre = None 14 | 15 | # Nos dice si el nodo tiene al menos un hijo 16 | def tieneHijos(self): 17 | return self.izq is not None and self.der is not None 18 | 19 | # Nos dide si el nodo es un hijo izquierdo 20 | def esIzq(self): 21 | return self.padre.izq == self 22 | 23 | # Nos dice si el nodo es un hijo derecho 24 | def esDer(self): 25 | return self.padre.der == self 26 | 27 | # Imprime el contenido del nodo 28 | def __str__(self): 29 | if self.dato is None: 30 | pass 31 | else: 32 | return '{}'.format(self.dato) 33 | 34 | ''' Clase AB (ArbolBinario), genera la estructura de un arbol binario, asi como sus funciones.''' 35 | class AB(object): 36 | 37 | ''' Consructor de arboles binarios''' 38 | def __init__(self, dato): 39 | self.raiz = Nodo(dato) 40 | 41 | ''' Elimina todo el arbol''' 42 | def elimina(self): 43 | self.raiz = None 44 | 45 | ''' Devuelve el nivel del nodo que se le pasa como parametro. 46 | La raiz se ubica en el nivel cero''' 47 | def nivel(self, nodo): 48 | if nodo is None: 49 | return -1 50 | else: 51 | return 1 + self.nivel(nodo.padre) 52 | 53 | ''' Devuelve la altura a partir del nodo que se le pasa como parametro, 54 | si el arbol es vacio la altura es cero, si no se le suma 1 al maximo 55 | de las alturas de sus hijos''' 56 | def altura(self, nodo): 57 | if nodo is None: 58 | return 0 59 | else: 60 | return 1 + max(self.altura(nodo.izq), self.altura(nodo.der)) 61 | 62 | ''' Inserta recursivamente un dato en el arbol de manera recursiva 63 | nodo: es el nodo a partir del cual se quiere insertar 64 | dato: es el dato que se quiere insertar 65 | ''' 66 | def insertar_nodo(self, nodo, dato): 67 | # si el nodo es vacio ahi se crea el nuevo nodo 68 | if nodo is None: 69 | nuevo_nodo = Nodo(dato) 70 | return nuevo_nodo 71 | # dado que en los AB no hay un orden el nuevo nodo se inserta donde sea 72 | if bool(random.getrandbits(1)): 73 | nuevo_nodo = self.insertar_nodo(nodo.izq, dato) 74 | nodo.izq = nuevo_nodo 75 | nuevo_nodo.padre = nodo 76 | else: 77 | nuevo_nodo = self.insertar_nodo(nodo.der, dato) 78 | nodo.der = nuevo_nodo 79 | nuevo_nodo.padre = nodo 80 | #nodo guarda toda la ruta de donde sera insertado el dato 81 | #hasta caer en el caso base, es por eso que se devuelve 82 | return nodo 83 | 84 | ''' Inserta un nodo en el arbol, a partir de la raiz''' 85 | def insertar(self, dato): 86 | #Se inserta el dato desde la raiz 87 | self.insertar_nodo(self.raiz, dato) 88 | 89 | ''' Recorre el arbol enorden e imprime cada uno de sus nodos''' 90 | def recorrido_enorden(self, nodo): 91 | if nodo is not None: 92 | self.recorrido_enorden(nodo.izq) 93 | print(nodo.dato) 94 | self.recorrido_enorden(nodo.der) 95 | 96 | ''' Recorre el arbol preorden e imprime cada uno de sus nodos''' 97 | def recorrido_preorden(self, nodo): 98 | if nodo is not None: 99 | print(nodo.dato) 100 | self.recorrido_preorden(nodo.izq) 101 | self.recorrido_preorden(nodo.der) 102 | 103 | ''' Recorre el arbol postorden e imprime cada uno de sus nodos''' 104 | def recorrido_postorden(self, nodo): 105 | if nodo is not None: 106 | self.recorrido_postorden(nodo.izq) 107 | self.recorrido_postorden(nodo.der) 108 | print(nodo.dato) -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/.ipynb_checkpoints/ArbolesBinarios-checkpoint.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | # Clase Nodo necesaria para generar arboles binarios 4 | class Nodo(object): 5 | ''' 6 | Constructor de nodos 7 | dato: es el contenido del nodo 8 | ''' 9 | def __init__(self, dato): 10 | self.izq = None 11 | self.dato = dato 12 | self.der = None 13 | self.padre = None 14 | 15 | # Nos dice si el nodo tiene al menos un hijo 16 | def tieneHijos(self): 17 | return self.izq is not None and self.der is not None 18 | 19 | # Nos dide si el nodo es un hijo izquierdo 20 | def esIzq(self): 21 | return self.padre.izq == self 22 | 23 | # Nos dice si el nodo es un hijo derecho 24 | def esDer(self): 25 | return self.padre.der == self 26 | 27 | # Imprime el contenido del nodo 28 | def __str__(self): 29 | if self.dato is None: 30 | pass 31 | else: 32 | return '{}'.format(self.dato) 33 | 34 | ''' Clase AB (ArbolBinario), genera la estructura de un arbol binario, asi como sus funciones.''' 35 | class AB(object): 36 | 37 | ''' Consructor de arboles binarios''' 38 | def __init__(self, dato): 39 | self.raiz = Nodo(dato) 40 | 41 | ''' Elimina todo el arbol''' 42 | def elimina(self): 43 | self.raiz = None 44 | 45 | ''' Devuelve el nivel del nodo que se le pasa como parametro. 46 | La raiz se ubica en el nivel cero''' 47 | def nivel(self, nodo): 48 | if nodo is None: 49 | return -1 50 | else: 51 | return 1 + self.nivel(nodo.padre) 52 | 53 | ''' Devuelve la altura a partir del nodo que se le pasa como parametro, 54 | si el arbol es vacio la altura es cero, si no se le suma 1 al maximo 55 | de las alturas de sus hijos''' 56 | def altura(self, nodo): 57 | if nodo is None: 58 | return 0 59 | else: 60 | return 1 + max(self.altura(nodo.izq), self.altura(nodo.der)) 61 | 62 | ''' Inserta recursivamente un dato en el arbol de manera recursiva 63 | nodo: es el nodo a partir del cual se quiere insertar 64 | dato: es el dato que se quiere insertar 65 | ''' 66 | def insertar_nodo(self, nodo, dato): 67 | # si el nodo es vacio ahi se crea el nuevo nodo 68 | if nodo is None: 69 | nuevo_nodo = Nodo(dato) 70 | return nuevo_nodo 71 | # dado que en los AB no hay un orden el nuevo nodo se inserta donde sea 72 | if bool(random.getrandbits(1)): 73 | nuevo_nodo = self.insertar_nodo(nodo.izq, dato) 74 | nodo.izq = nuevo_nodo 75 | nuevo_nodo.padre = nodo 76 | else: 77 | nuevo_nodo = self.insertar_nodo(nodo.der, dato) 78 | nodo.der = nuevo_nodo 79 | nuevo_nodo.padre = nodo 80 | #nodo guarda toda la ruta de donde sera insertado el dato 81 | #hasta caer en el caso base, es por eso que se devuelve 82 | return nodo 83 | 84 | ''' Inserta un nodo en el arbol, a partir de la raiz''' 85 | def insertar(self, dato): 86 | #Se inserta el dato desde la raiz 87 | self.insertar_nodo(self.raiz, dato) 88 | 89 | ''' Recorre el arbol enorden e imprime cada uno de sus nodos''' 90 | def recorrido_enorden(self, nodo): 91 | if nodo is not None: 92 | self.recorrido_enorden(nodo.izq) 93 | print(nodo.dato) 94 | self.recorrido_enorden(nodo.der) 95 | 96 | ''' Recorre el arbol preorden e imprime cada uno de sus nodos''' 97 | def recorrido_preorden(self, nodo): 98 | if nodo is not None: 99 | print(nodo.dato) 100 | self.recorrido_preorden(nodo.izq) 101 | self.recorrido_preorden(nodo.der) 102 | 103 | ''' Recorre el arbol postorden e imprime cada uno de sus nodos''' 104 | def recorrido_postorden(self, nodo): 105 | if nodo is not None: 106 | self.recorrido_postorden(nodo.izq) 107 | self.recorrido_postorden(nodo.der) 108 | print(nodo.dato) -------------------------------------------------------------------------------- /00_Introduccion/Interactivos/zinteractivo3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "7tk9OKenCXiO" 17 | }, 18 | "source": [ 19 | "# Cálculo de derivadas numéricas y errores\n", 20 | "## Proyecto PAPIME PE101019\n", 21 | "- Autor: Luis M. de la Cruz Salas\n", 22 | "- Rev: lun jul 6 19:29:17 CDT 2020" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": { 29 | "id": "iDUqff21CXiQ" 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "import numpy as np\n", 34 | "import pandas as pd\n", 35 | "from sympy import Symbol, cos, sin, exp, tan\n", 36 | "import FD\n", 37 | "import matplotlib.pyplot as plt\n", 38 | "import macti.vis as mvis" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": { 45 | "id": "TaNNDUwjCXiR" 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "from ipywidgets import interact, interactive, fixed\n", 50 | "import ipywidgets as wd" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "colab": { 58 | "referenced_widgets": [ 59 | "7f8dce8dcb5a4310a935476334e05afa", 60 | "4d0ba29d8fcc49248ca6bbef60baec61" 61 | ] 62 | }, 63 | "id": "KSyFYVbqCXiR", 64 | "outputId": "ac9f2b2f-04d3-4548-a3d8-8b654966591e" 65 | }, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "application/vnd.jupyter.widget-view+json": { 70 | "model_id": "7f8dce8dcb5a4310a935476334e05afa", 71 | "version_major": 2, 72 | "version_minor": 0 73 | }, 74 | "text/plain": [ 75 | "VBox(children=(HBox(children=(Dropdown(description='Función', layout=Layout(width='250px'), options=(cos(x), s…" 76 | ] 77 | }, 78 | "metadata": {}, 79 | "output_type": "display_data" 80 | }, 81 | { 82 | "data": { 83 | "application/vnd.jupyter.widget-view+json": { 84 | "model_id": "4d0ba29d8fcc49248ca6bbef60baec61", 85 | "version_major": 2, 86 | "version_minor": 0 87 | }, 88 | "text/plain": [ 89 | "Output()" 90 | ] 91 | }, 92 | "metadata": {}, 93 | "output_type": "display_data" 94 | } 95 | ], 96 | "source": [ 97 | "t = Symbol('x')\n", 98 | "lista_funciones = [cos(t), sin(t), exp(t), exp(t)*cos(t), tan(t), sin(t)*t**2]\n", 99 | "opciones_aprox = ['Forward', 'Backward', 'Centered', 'All']\n", 100 | "\n", 101 | "w_f = wd.Dropdown(\n", 102 | " options=lista_funciones,\n", 103 | " value=cos(t),\n", 104 | " description='Función',\n", 105 | " layout=wd.Layout(width='250px')\n", 106 | ")\n", 107 | "\n", 108 | "w_a = wd.Dropdown(\n", 109 | " options=opciones_aprox,\n", 110 | " value='Forward',\n", 111 | " description='Aproximación',\n", 112 | " layout=wd.Layout(width='250px')\n", 113 | ")\n", 114 | "\n", 115 | "w_x0 = wd.FloatSlider(\n", 116 | " min=-2.0, max=2.0, step=0.5, value=0.0,\n", 117 | " description='x0',\n", 118 | " layout=wd.Layout(width='250px')\n", 119 | ")\n", 120 | "\n", 121 | "w_h = wd.FloatSlider(\n", 122 | " min=0.01, max=1.0, step=0.1, value=1.0,\n", 123 | " description='h',\n", 124 | " layout=wd.Layout(width='250px')\n", 125 | ")\n", 126 | "\n", 127 | "button = wd.Button(\n", 128 | " description=\"\", icon='play',\n", 129 | " layout=wd.Layout(width='50px')\n", 130 | ")\n", 131 | "\n", 132 | "ui = wd.VBox([wd.HBox([w_f, w_a],\n", 133 | " layout=wd.Layout(padding='0px',\n", 134 | " border='1px solid gray',\n", 135 | " width='510px')),\n", 136 | " wd.HBox([w_x0, w_h],\n", 137 | " layout=wd.Layout(padding='0px',\n", 138 | " border='1px solid gray',\n", 139 | " width='510px')),\n", 140 | " wd.HBox([button])])\n", 141 | "\n", 142 | "ui.layout = wd.Layout(border='solid 0px black')\n", 143 | "\n", 144 | "output = wd.Output()\n", 145 | "\n", 146 | "display(ui, output)\n", 147 | "\n", 148 | "def on_button_clicked(b):\n", 149 | " output.clear_output(wait=True)\n", 150 | " with output:\n", 151 | " FD.numericalDer(w_f.value, w_x0.value, w_h.value, w_a.value)\n", 152 | "\n", 153 | "button.on_click(on_button_clicked)\n" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": { 160 | "id": "Au9YYMnxCXiS" 161 | }, 162 | "outputs": [], 163 | "source": [] 164 | } 165 | ], 166 | "metadata": { 167 | "kernelspec": { 168 | "display_name": "Python 3 (ipykernel)", 169 | "language": "python", 170 | "name": "python3" 171 | }, 172 | "language_info": { 173 | "codemirror_mode": { 174 | "name": "ipython", 175 | "version": 3 176 | }, 177 | "file_extension": ".py", 178 | "mimetype": "text/x-python", 179 | "name": "python", 180 | "nbconvert_exporter": "python", 181 | "pygments_lexer": "ipython3", 182 | "version": "3.11.6" 183 | }, 184 | "colab": { 185 | "provenance": [], 186 | "include_colab_link": true 187 | } 188 | }, 189 | "nbformat": 4, 190 | "nbformat_minor": 0 191 | } -------------------------------------------------------------------------------- /00_Introduccion/Interactivos/FD.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # Cálculo de derivadas numéricas 5 | # Autor: Luis M. de la Cruz Salas 6 | # Rev: mar jul 7 11:12:13 CDT 2020 7 | 8 | 9 | import numpy as np 10 | from pandas import DataFrame 11 | from sympy import Symbol, diff, sin, cos, exp 12 | from sympy.utilities.lambdify import lambdify 13 | import matplotlib.pyplot as plt 14 | 15 | def forwardFD(u,x,h): 16 | """ 17 | Esquema de diferencias finitas hacia adelante. 18 | 19 | Parameters 20 | ---------- 21 | u : función. 22 | Función a evaluar. 23 | 24 | x : array 25 | Lugar(es) donde se evalúa la función 26 | 27 | h : array 28 | Tamaño(s) de la diferencia entre u(x+h) y u(x). 29 | 30 | Returns 31 | ------- 32 | Cálculo de la derivada numérica hacia adelante. 33 | """ 34 | return (u(x+h)-u(x))/h 35 | 36 | def backwardFD(u,x,h): 37 | """ 38 | Esquema de diferencias finitas hacia atrás. 39 | 40 | Parameters 41 | ---------- 42 | u : función. 43 | Función a evaluar. 44 | 45 | x : array 46 | Lugar(es) donde se evalúa la función 47 | 48 | h : array 49 | Tamaño(s) de la diferencia entre u(x+h) y u(x). 50 | 51 | Returns 52 | ------- 53 | Cálculo de la derivada numérica hacia atrás. 54 | """ 55 | return (u(x)-u(x-h))/h 56 | 57 | 58 | def centeredFD(u,x,h): 59 | """ 60 | Esquema de diferencias finitas centradas. 61 | 62 | Parameters 63 | ---------- 64 | u : función. 65 | Función a evaluar. 66 | 67 | x : array 68 | Lugar(es) donde se evalúa la función 69 | 70 | h : array 71 | Tamaño(s) de la diferencia entre u(x+h) y u(x). 72 | 73 | Returns 74 | ------- 75 | Cálculo de la derivada numérica centrada. 76 | """ 77 | return (u(x+h)-u(x-h))/(2*h) 78 | 79 | def line(x,x0,x1,y0,y1): 80 | """ 81 | Dados dos puntos en el plano, cálcula la pendiente de 82 | la recta que pasa por esos puntos y regresa los puntos 83 | que pasan por esa recta. 84 | """ 85 | return ((y1-y0)/(x1-x0))*(x-x0) + y0 86 | 87 | def numericalDer(f, x0, h, aprox = 'All'): 88 | t = Symbol('x') # defino la variable dependiente 89 | fp = diff(f,t) # calcula la derivada de la función f (simbólica) 90 | 91 | # Genero funciones lambda para evaluar la función y su derivada 92 | evalfp = lambdify(t, fp, modules=['numpy']) # la derivada 93 | evalf = lambdify(t, f, modules=['numpy']) # la función 94 | 95 | fp_value = evalfp(x0) # evalúo la derivada en x0 96 | 97 | # Calculo el error de las aproximacions y el valor exacto 98 | ef = np.fabs(fp_value - forwardFD(evalf, x0, h)) 99 | eb = np.fabs(fp_value - backwardFD(evalf, x0, h)) 100 | ec = np.fabs(fp_value - centeredFD(evalf, x0, h)) 101 | 102 | # Arreglos para las gráficas de la línea y la función. 103 | xl = np.linspace(x0 - 0.5 * np.pi, x0 + 0.5 * np.pi, 50) 104 | xv = np.linspace(x0 - np.pi, x0 + np.pi, 50) 105 | 106 | # Coordenaas verticales de las líneas de cada aproximación 107 | lf = line(xl, x0, x0 + h, evalf(x0), evalf(x0 + h)) 108 | lb = line(xl, x0, x0 - h, evalf(x0), evalf(x0 - h)) 109 | lc = line(xl, x0-h, x0+h, evalf(x0-h), evalf(x0+h)) 110 | 111 | # Punto donde se aproxima y el punto vecino. 112 | yv = evalf(xv) 113 | yp = evalfp(xv) 114 | 115 | ancho_linea = 2.0 116 | 117 | fig = plt.figure(figsize=(10,4)) 118 | fig.suptitle('EF = {:10.4e}, EB = {:10.4e}, EC = {:10.4e}'.format(ef,eb,ec)) 119 | 120 | ax1 = plt.subplot(1,2,1) 121 | plt.plot(xv, yv, '--', lw = 3, color='b', label = 'f = {}'.format(f)) 122 | plt.scatter(x0, evalf(x0), facecolor ='b', edgecolor='k', zorder=10) 123 | 124 | if aprox == 'All': 125 | plt.scatter(x0+h, evalf(x0+h), facecolor ='w', edgecolor='k', zorder=10) 126 | plt.scatter(x0-h, evalf(x0-h), facecolor ='w', edgecolor='k', zorder=10) 127 | plt.scatter(x0-2*h, evalf(x0-2*h), facecolor ='w', edgecolor='k', zorder=10) 128 | plt.plot(xl, lf, lw = ancho_linea, label="f' = Forward") 129 | plt.plot(xl, lb, lw = ancho_linea, label="f' = Backward") 130 | plt.plot(xl, lc, lw = ancho_linea, label="f' = Centered") 131 | 132 | elif aprox == 'Forward': 133 | plt.scatter(x0+h, evalf(x0+h), facecolor ='w', edgecolor='k', zorder=10) 134 | plt.plot(xl, lf, lw = ancho_linea, label="f' = Forward") 135 | 136 | elif aprox == 'Backward': 137 | plt.scatter(x0-h, evalf(x0-h), facecolor ='w', edgecolor='k', zorder=10) 138 | plt.plot(xl, lb, lw = ancho_linea, label="f' = Backward") 139 | 140 | elif aprox == 'Centered': 141 | plt.scatter(x0+h, evalf(x0+h), facecolor ='w', edgecolor='k', zorder=10) 142 | plt.scatter(x0-h, evalf(x0-h), facecolor ='w', edgecolor='k', zorder=10) 143 | plt.plot(xl, lc, lw = ancho_linea, label="f' = Centered") 144 | 145 | plt.legend(ncol=2, loc=(0.0,-0.30)) 146 | 147 | 148 | ax2 = plt.subplot(1,2,2) 149 | plt.plot(xv, yp, '--', lw = 3, color='k', label = "f'= {}".format(fp)) 150 | 151 | if aprox == 'All': 152 | plt.plot(xv, forwardFD(evalf, xv, h), lw = ancho_linea) 153 | plt.plot(xv, backwardFD(evalf, xv, h), lw = ancho_linea) 154 | plt.plot(xv, centeredFD(evalf, xv, h), lw = ancho_linea) 155 | elif aprox == 'Forward': 156 | plt.plot(xv, forwardFD(evalf, xv, h), lw = ancho_linea) 157 | elif aprox == 'Backward': 158 | plt.plot(xv, backwardFD(evalf, xv, h), lw = ancho_linea) 159 | elif aprox == 'Centered': 160 | plt.plot(xv, centeredFD(evalf, xv, h), lw = ancho_linea) 161 | 162 | plt.legend() 163 | 164 | plt.show() 165 | return [ef, eb, ec] 166 | 167 | #----------------------- TEST OF THE MODULE ---------------------------------- 168 | if __name__ == '__main__': 169 | 170 | # Definimos un arreglo con diferentes tamaños de h: 171 | N = 5 172 | h = np.zeros(N) 173 | 174 | h[0] = 1.0 175 | for i in range(1,N): 176 | h[i] = h[i-1] * 0.5 177 | 178 | # Definimos un arreglo con valores de 1.0 (donde evaluaremos el cos(x)): 179 | x = np.ones(N) 180 | 181 | aprox = np.array([h, 182 | np.cos(x), 183 | forwardFD(np.sin,x,h), 184 | backwardFD(np.sin,x,h), 185 | centeredFD(np.sin,x,h)]) 186 | 187 | 188 | daprox = DataFrame(aprox.transpose(), 189 | columns = ['h', 'original', 'forward', 'backward', 'centered']) 190 | print(daprox) 191 | 192 | t = Symbol('x') 193 | print(numericalDer(sin(t) * t*t, x[0], h[0], 'Forward')) -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/ArbolesBinariosBusqueda.py: -------------------------------------------------------------------------------- 1 | from utils.src.ArbolesBinarios import AB, Nodo 2 | 3 | ''' Clase arbol binario de busqueda, genera la estructura de un arbol binario 4 | de busqueda asi como sus funciones.''' 5 | class ABB(AB): 6 | ''' Consructor de arboles''' 7 | def __init__(self, dato): 8 | # llamamos al constructor de la clase padre con la palabra super 9 | super(ABB, self).__init__(dato) 10 | # y se agrega la variable ultimo agregado que sirve para clases posteriores 11 | self.ultimo_agregado = self.raiz 12 | 13 | ''' Busca un dato en el arbol y devuelve el nodo''' 14 | def busqueda(self, nodo, dato): 15 | # si la raiz es None o el dato esta contenido en el nodo, 16 | # se devuelve el nodo. 17 | if nodo is None or nodo.dato == dato: 18 | return nodo 19 | # si el dato es mayo entonces se busca del lado derecho 20 | if nodo.dato < dato: 21 | return self.busqueda(nodo.der, dato) 22 | # si no, se busca en el lado izquierdo 23 | else: 24 | return self.busqueda(nodo.izq, dato) 25 | 26 | ''' Inserta un elemento en el arbol a partir de un nodo''' 27 | def insertar_nodo(self, nodo, dato): 28 | # si el nodo es vacio ahi se crea el nuevo nodo 29 | if nodo is None: 30 | nuevo_nodo = Nodo(dato) 31 | self.ultimo_agregado = nuevo_nodo 32 | return nuevo_nodo 33 | # si el dato es menor que su padre, se inserta en el lado izquierdo 34 | if dato < nodo.dato: 35 | nuevo_nodo = self.insertar_nodo(nodo.izq, dato) 36 | nodo.izq = nuevo_nodo 37 | nuevo_nodo.padre = nodo 38 | # de no ser asi se inserta del lado derecho 39 | else: 40 | nuevo_nodo = self.insertar_nodo(nodo.der, dato) 41 | nodo.der = nuevo_nodo 42 | nuevo_nodo.padre = nodo 43 | # nodo guarda toda la ruta de donde sera insertado el dato 44 | # hasta caer en el caso base, es por eso que se devuelve 45 | return nodo 46 | 47 | ''' Inserta un nodo en el arbol, a partir de la raiz''' 48 | def insertar(self, dato): 49 | # si el dato a insertar no se encuentra en el ABB se inserta 50 | if self.busqueda(self.raiz, dato) is None: 51 | # Se inserta el dato desde la raiz 52 | self.insertar_nodo(self.raiz, dato) 53 | 54 | ''' Busca el minimo en el subarbol a partir de nodo, este metodo sirve 55 | para poder eliminar nodos del arbol y mantener el orden''' 56 | def minimo_en_subarbol(self, nodo): 57 | # caso base en el que no hay minimo 58 | if nodo is None: 59 | return nodo 60 | # caso base en el que el nodo es el minimo ya que no tiene hijo izq 61 | if nodo.izq is None: 62 | return nodo 63 | # llamada recursiva para movernos al siguiente minimo 64 | return self.minimo_en_subarbol(nodo.izq) 65 | 66 | ''' Borra un nodo en el arbol, busca al nodo que contiene a dato 67 | y en caso de existir lo borra, se pueden dar multiples casos''' 68 | def borra_nodo(self, nodo, dato): 69 | # Caso 0) revisamos si el arbol es vacio. 70 | if self.raiz is None: 71 | return None 72 | # buscamos el nodo a borrar 73 | nodo_a_borrar = self.busqueda(nodo, dato) 74 | aux = nodo_a_borrar 75 | 76 | # Caso 0.1) si el dato no se encontro en el arbol no se puede borrar 77 | if nodo_a_borrar is None: 78 | return None 79 | 80 | # Caso 1) si el nodo a borrar es la RAIZ 81 | if nodo_a_borrar is self.raiz: 82 | # caso1.1) no tiene hijos, solo se borra la raiz 83 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is None: 84 | self.raiz = None 85 | self.ultimo_agregado = None 86 | return None 87 | 88 | # Caso1.2) solo se tiene hijo derecho, entonces se sube al hijo derecho 89 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is not None: 90 | self.raiz = nodo_a_borrar.der 91 | self.raiz.padre = None 92 | return self.raiz 93 | 94 | # Caso1.3) solo se tiene hijo izquierdo, entonces se sube al hijo izquierdo 95 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is None: 96 | self.raiz = nodo_a_borrar.izq 97 | self.raiz.padre = None 98 | return self.raiz 99 | 100 | # Caso1.4) tiene ambos hijos 101 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is not None: 102 | # buscamos el minimo en el subarbol derecho (minimo de los mayores) 103 | minimo = self.minimo_en_subarbol(nodo_a_borrar.der) 104 | aux = minimo.padre 105 | self.raiz.dato = minimo.dato 106 | self.borra_nodo(minimo, minimo.dato) 107 | return aux 108 | 109 | else: #Caso 2) 110 | # a partir de aqui se tienen 3 casos: 111 | # si no tiene hijos simplemente se borra el nodo 112 | # si tiene un solo hijo (ya sea izquierdo o derecho) se sube al unico hijo 113 | # tiene ambos hijos 114 | 115 | # es necesario identificar si el nodo a borrar es hijo izquierdo o derecho 116 | es_izquierdo = False 117 | if nodo_a_borrar.padre.izq == nodo_a_borrar: 118 | es_izquierdo = True 119 | 120 | # Caso2.1) no tiene hijos, solo se borra el nodo 121 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is None: 122 | aux = nodo_a_borrar.padre 123 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 124 | if es_izquierdo: # Caso2.1.1) 125 | aux.izq = None 126 | else: # Caso2.1.2) 127 | aux.der = None 128 | nodo_a_borrar = None 129 | return aux 130 | 131 | # Caso2.2) solo se tiene hijo izquierdo, entonces se sube al hijo izquierdo 132 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is None: 133 | nodo_a_borrar.izq.padre = nodo_a_borrar.padre 134 | aux = nodo_a_borrar.padre 135 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 136 | if es_izquierdo: # Caso2.2.1) 137 | nodo_a_borrar.padre.izq = nodo_a_borrar.izq 138 | else: # Caso2.2.2) 139 | nodo_a_borrar.padre.der = nodo_a_borrar.izq 140 | return aux 141 | 142 | # Caso2.3) solo se tiene hijo derecho, entonces se sube al hijo derecho 143 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is not None: 144 | nodo_a_borrar.der.padre = nodo_a_borrar.padre 145 | aux = nodo_a_borrar.padre 146 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 147 | if es_izquierdo: # Caso2.3.1) 148 | nodo_a_borrar.padre.izq = nodo_a_borrar.der 149 | else: # Caso2.3.2) 150 | nodo_a_borrar.padre.der = nodo_a_borrar.der 151 | return aux 152 | 153 | # Caso2.4) tiene ambos hijos 154 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is not None: 155 | # buscamos el minimo en el subarbol derecho 156 | minimo = self.minimo_en_subarbol(nodo_a_borrar.der) 157 | aux = minimo.padre 158 | nodo_a_borrar.dato = minimo.dato 159 | self.borra_nodo(minimo, minimo.dato) 160 | return aux 161 | 162 | ''' Borra un nodo que contiene a dato a partir de la raiz''' 163 | def borrar(self, dato): 164 | self.borra_nodo(self.raiz, dato) 165 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/utils/src/.ipynb_checkpoints/ArbolesBinariosBusqueda-checkpoint.py: -------------------------------------------------------------------------------- 1 | from ArbolesBinarios import AB, Nodo 2 | 3 | ''' Clase arbol binario de busqueda, genera la estructura de un arbol binario 4 | de busqueda asi como sus funciones.''' 5 | class ABB(AB): 6 | ''' Consructor de arboles''' 7 | def __init__(self, dato): 8 | # llamamos al constructor de la clase padre con la palabra super 9 | super(ABB, self).__init__(dato) 10 | # y se agrega la variable ultimo agregado que sirve para clases posteriores 11 | self.ultimo_agregado = self.raiz 12 | 13 | ''' Busca un dato en el arbol y devuelve el nodo''' 14 | def busqueda(self, nodo, dato): 15 | # si la raiz es None o el dato esta contenido en el nodo, 16 | # se devuelve el nodo. 17 | if nodo is None or nodo.dato == dato: 18 | return nodo 19 | # si el dato es mayo entonces se busca del lado derecho 20 | if nodo.dato < dato: 21 | return self.busqueda(nodo.der, dato) 22 | # si no, se busca en el lado izquierdo 23 | else: 24 | return self.busqueda(nodo.izq, dato) 25 | 26 | ''' Inserta un elemento en el arbol a partir de un nodo''' 27 | def insertar_nodo(self, nodo, dato): 28 | # si el nodo es vacio ahi se crea el nuevo nodo 29 | if nodo is None: 30 | nuevo_nodo = Nodo(dato) 31 | self.ultimo_agregado = nuevo_nodo 32 | return nuevo_nodo 33 | # si el dato es menor que su padre, se inserta en el lado izquierdo 34 | if dato < nodo.dato: 35 | nuevo_nodo = self.insertar_nodo(nodo.izq, dato) 36 | nodo.izq = nuevo_nodo 37 | nuevo_nodo.padre = nodo 38 | # de no ser asi se inserta del lado derecho 39 | else: 40 | nuevo_nodo = self.insertar_nodo(nodo.der, dato) 41 | nodo.der = nuevo_nodo 42 | nuevo_nodo.padre = nodo 43 | # nodo guarda toda la ruta de donde sera insertado el dato 44 | # hasta caer en el caso base, es por eso que se devuelve 45 | return nodo 46 | 47 | ''' Inserta un nodo en el arbol, a partir de la raiz''' 48 | def insertar(self, dato): 49 | # si el dato a insertar no se encuentra en el ABB se inserta 50 | if self.busqueda(self.raiz, dato) is None: 51 | # Se inserta el dato desde la raiz 52 | self.insertar_nodo(self.raiz, dato) 53 | 54 | ''' Busca el minimo en el subarbol a partir de nodo, este metodo sirve 55 | para poder eliminar nodos del arbol y mantener el orden''' 56 | def minimo_en_subarbol(self, nodo): 57 | # caso base en el que no hay minimo 58 | if nodo is None: 59 | return nodo 60 | # caso base en el que el nodo es el minimo ya que no tiene hijo izq 61 | if nodo.izq is None: 62 | return nodo 63 | # llamada recursiva para movernos al siguiente minimo 64 | return self.minimo_en_subarbol(nodo.izq) 65 | 66 | ''' Borra un nodo en el arbol, busca al nodo que contiene a dato 67 | y en caso de existir lo borra, se pueden dar multiples casos''' 68 | def borra_nodo(self, nodo, dato): 69 | # Caso 0) revisamos si el arbol es vacio. 70 | if self.raiz is None: 71 | return None 72 | # buscamos el nodo a borrar 73 | nodo_a_borrar = self.busqueda(nodo, dato) 74 | aux = nodo_a_borrar 75 | 76 | # Caso 0.1) si el dato no se encontro en el arbol no se puede borrar 77 | if nodo_a_borrar is None: 78 | return None 79 | 80 | # Caso 1) si el nodo a borrar es la RAIZ 81 | if nodo_a_borrar is self.raiz: 82 | # caso1.1) no tiene hijos, solo se borra la raiz 83 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is None: 84 | self.raiz = None 85 | self.ultimo_agregado = None 86 | return None 87 | 88 | # Caso1.2) solo se tiene hijo derecho, entonces se sube al hijo derecho 89 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is not None: 90 | self.raiz = nodo_a_borrar.der 91 | self.raiz.padre = None 92 | return self.raiz 93 | 94 | # Caso1.3) solo se tiene hijo izquierdo, entonces se sube al hijo izquierdo 95 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is None: 96 | self.raiz = nodo_a_borrar.izq 97 | self.raiz.padre = None 98 | return self.raiz 99 | 100 | # Caso1.4) tiene ambos hijos 101 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is not None: 102 | # buscamos el minimo en el subarbol derecho (minimo de los mayores) 103 | minimo = self.minimo_en_subarbol(nodo_a_borrar.der) 104 | aux = minimo.padre 105 | self.raiz.dato = minimo.dato 106 | self.borra_nodo(minimo, minimo.dato) 107 | return aux 108 | 109 | else: #Caso 2) 110 | # a partir de aqui se tienen 3 casos: 111 | # si no tiene hijos simplemente se borra el nodo 112 | # si tiene un solo hijo (ya sea izquierdo o derecho) se sube al unico hijo 113 | # tiene ambos hijos 114 | 115 | # es necesario identificar si el nodo a borrar es hijo izquierdo o derecho 116 | es_izquierdo = False 117 | if nodo_a_borrar.padre.izq == nodo_a_borrar: 118 | es_izquierdo = True 119 | 120 | # Caso2.1) no tiene hijos, solo se borra el nodo 121 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is None: 122 | aux = nodo_a_borrar.padre 123 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 124 | if es_izquierdo: # Caso2.1.1) 125 | aux.izq = None 126 | else: # Caso2.1.2) 127 | aux.der = None 128 | nodo_a_borrar = None 129 | return aux 130 | 131 | # Caso2.2) solo se tiene hijo izquierdo, entonces se sube al hijo izquierdo 132 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is None: 133 | nodo_a_borrar.izq.padre = nodo_a_borrar.padre 134 | aux = nodo_a_borrar.padre 135 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 136 | if es_izquierdo: # Caso2.2.1) 137 | nodo_a_borrar.padre.izq = nodo_a_borrar.izq 138 | else: # Caso2.2.2) 139 | nodo_a_borrar.padre.der = nodo_a_borrar.izq 140 | return aux 141 | 142 | # Caso2.3) solo se tiene hijo derecho, entonces se sube al hijo derecho 143 | if nodo_a_borrar.izq is None and nodo_a_borrar.der is not None: 144 | nodo_a_borrar.der.padre = nodo_a_borrar.padre 145 | aux = nodo_a_borrar.padre 146 | # revisamos si el nodo a borrar es un hijo izquiero o derecho 147 | if es_izquierdo: # Caso2.3.1) 148 | nodo_a_borrar.padre.izq = nodo_a_borrar.der 149 | else: # Caso2.3.2) 150 | nodo_a_borrar.padre.der = nodo_a_borrar.der 151 | return aux 152 | 153 | # Caso2.4) tiene ambos hijos 154 | if nodo_a_borrar.izq is not None and nodo_a_borrar.der is not None: 155 | # buscamos el minimo en el subarbol derecho 156 | minimo = self.minimo_en_subarbol(nodo_a_borrar.der) 157 | aux = minimo.padre 158 | nodo_a_borrar.dato = minimo.dato 159 | self.borra_nodo(minimo, minimo.dato) 160 | return aux 161 | 162 | ''' Borra un nodo que contiene a dato a partir de la raiz''' 163 | def borrar(self, dato): 164 | self.borra_nodo(self.raiz, dato) -------------------------------------------------------------------------------- /05_BasesDeDatos/04_HojasDeCalculo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "Y7eEouik1z4K" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

Análisis de datos con Excel: Introducción a distintas funciones de excel

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 24 | "
Ayudante: Diana Laura Rojas Cristino
\n", 25 | "
Ayudante: Rodrigo Alejandro Sánchez Morales
\n", 26 | "
Materia: Manejo de Datos
\n", 27 | "
" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "M8AFH5zC30RZ" 34 | }, 35 | "source": [ 36 | "\n", 37 | "## Contenido\n", 38 | "\n", 39 | "- [Objetivos Generales](#OG)\n", 40 | "\n", 41 | "- [Objetivos Particulares](#OP)\n", 42 | "\n", 43 | "- [Introducción](#Int)\n", 44 | "\n", 45 | "- [Operadores básicos de Excel](#1)\n", 46 | "\n", 47 | "- [Funciones importantes a conocer en Excel](#2)\n" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": { 53 | "id": "tXGNXr1y4H7Q" 54 | }, 55 | "source": [ 56 | "\n", 57 | "## Objetivos Generales\n", 58 | "\n", 59 | "- Que el alumno tenga noción de algunas de las principales funciones de Excel para el análisis de datos." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "id": "hnhTcYPl51Qp" 66 | }, 67 | "source": [ 68 | "\n", 69 | "## Objetivos Particulares\n", 70 | "- Conocer los operadores básicos de Excel\n", 71 | "- Conocer algunas de las funciones básicas de Excel para el análisis de datos, tales como aquellas que funcionan en números, fechas, texto y búsqueda.\n" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": { 77 | "id": "VIogRBst9g6q" 78 | }, 79 | "source": [ 80 | "\n", 81 | "# Introducción\n", 82 | "\n", 83 | "Excel es una herramienta poderosa y versátil que puede utilizarse tanto en el ámbito escolar como en el entorno laboral. Es una aplicación de hojas de cálculo que permite organizar, analizar y presentar datos de manera efectiva.\n", 84 | "\n", 85 | "Esencialmente, Excel es una herramienta que ayuda a simplificar procesos y a aumentar la eficiencia y precisión en el manejo de datos. En el ámbito escolar, Excel es una herramienta valiosa para la gestión de notas, seguimiento del progreso académico y la realización de proyectos y trabajos de investigación. Permite a los estudiantes organizar y analizar datos de manera efectiva, lo que les ayuda a comprender mejor la información y tomar decisiones basadas en datos. \n", 86 | "\n", 87 | "En el entorno laboral, Excel es una herramienta esencial para la gestión de datos financieros, la creación de informes y el análisis de datos. Permite a las empresas automatizar procesos, reducir errores y tomar decisiones informadas basadas en datos precisos y actualizados. \n", 88 | "\n", 89 | "Simultáneamente a la necesidad de Excel en la vida cotidiana, escolar y laboral, desde hace años el ímpetu del análisis de datos ha tomado más importancia en muchas empresas sin importar el ramo. Por lo anterior, los presentes notebooks tienen como fin ayudar en la comprensión y utilización de Excel para el análisis de datos.\n" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "id": "Wt_mF3jUAorA" 96 | }, 97 | "source": [ 98 | "\n", 99 | "# Operadores básicos de Excel.\n", 100 | "\n", 101 | "## Numéricos:\n", 102 | "\n", 103 | "1. $+$, realiza la suma de las celdas que se indiquen entre cada signo.\n", 104 | "2. $-$, realiza la resta de las celdas que se indiquen entre cada signo.\n", 105 | "3. $*$, realiza la multiplicación de las celdas que se indiquen entre cada signo.\n", 106 | "4. $/$, realiza la división de las cledas que se indiquen entre cada signo\n", 107 | "5. $^$, eleva a cierta potencia un número\n", 108 | "\n", 109 | "## Lógicos:\n", 110 | "1. $=$: Igual\n", 111 | "2. $>$: Mayor que\n", 112 | "3. $<$: Menor que\n", 113 | "4. $>=$: Mayor o igual que\n", 114 | "5. $<=$: Menor o igual que\n", 115 | "6. $<>$: Distinto que\n", 116 | "\n", 117 | "## Concatenación de texto:\n", 118 | "1. $&$, concatena el texto de varias celdas\n", 119 | "\n", 120 | "\n", 121 | "[Ir al índice](#Contenido)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": { 127 | "id": "mCV2T_4Bikoi" 128 | }, 129 | "source": [ 130 | "\n", 131 | "# 2. Funciones importantes a conocer de Excel\n", 132 | "\n", 133 | "A continuación se mencionan algunas de las primeras funciones de Excel que utilizaremos en esta sesión, así como sus parámetros y las indicaciones que hay que tener para su buen funcionamiento:\n", 134 | "\n", 135 | "## Numéricas: \n", 136 | "\n", 137 | "\n", 138 | "* $SUMA\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 139 | "\n", 140 | " Realiza la suma de las celdas que contengan números e indiquemos. Este proceso es muy usado para no indicar repetidamente el símbolo \"+\" entre cada celda\n", 141 | "\n", 142 | "* $MIN\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 143 | "\n", 144 | " Calcula el mínimo de una selección de celdas que contienen números\n", 145 | "\n", 146 | "* $MAX\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 147 | "\n", 148 | " Calcula el máximo de una selección de celdas que contienen números\n", 149 | "\n", 150 | "* $RAIZ\\backsim(número)$\n", 151 | "\n", 152 | " Calcula la raíz cuadrada de un número contenido en una celda\n", 153 | "\n", 154 | "* $REDONDEAR\\backsim(número, número de decimales)$\n", 155 | "\n", 156 | " Redondea un número contenido en una celda según las posiciones de decimales que indiquemos.\n", 157 | "\n", 158 | "* $ENTERO\\backsim(número)$\n", 159 | "\n", 160 | " Devuelve el número entero de una celda\n", 161 | "\n", 162 | "* $PROMEDIO\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 163 | "\n", 164 | " Realiza el promedio de las celdas que contengan números e indiquemos. \n", 165 | "\n", 166 | "* $CONTAR\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 167 | "\n", 168 | " Cuenta el número de celdas que tienen contenido\n", 169 | "\n", 170 | "* $ALEATORIO\\backsim()$\n", 171 | "\n", 172 | " Devuelve un número aleatorio entre 0 y 1\n", 173 | "\n", 174 | "* $RESIDUO\\backsim(número, númerodivisor)$\n", 175 | "\n", 176 | " Devuelve el residuo entre dos números, indicando cuál es el dividendo y el divisor\n", 177 | "\n", 178 | "* $DESVEST\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 179 | " Calcula la desviación estandar de una muestra\n", 180 | "\n", 181 | "## FECHAS\n", 182 | "\n", 183 | "* $AÑO\\backsim(fecha)$\n", 184 | "* $MES\\backsim(fecha)$\n", 185 | "* $DIA\\backsim(fecha)$\n", 186 | "\n", 187 | " Devuelve el año, mes o día (según corresponda) de la celda indicada, la cual debe ser una fecha\n", 188 | "\n", 189 | "* $DIAS\\backsim(fecha_inicial, fecha_final)$\n", 190 | "\n", 191 | " Calcula el número de días entre dos fechas\n", 192 | "\n", 193 | "* $NUM.DE.SEMANA\\backsim(fecha)$\n", 194 | "\n", 195 | " Regresa el número de semana en la que se encuentra la fecha indicada\n", 196 | "\n", 197 | "* $DIAS.LAB\\backsim(fecha-inicial, fecha-final, (vacaciones))$\n", 198 | "\n", 199 | " Regresa el número de días entre dos fechas, pero sólo considera días laborales (no considera fines de semana), además puedes añadir un parámetro adicional con los días de vacaciones.\n", 200 | "\n", 201 | "## TEXTO:\n", 202 | "\n", 203 | "* $REEMPLAZAR\\backsim(texto-original, núm-inicial, núm-caracteres, texto-nuevo)$\n", 204 | " \n", 205 | " Esta función, como su nombre lo indica, permite reemplazar ciertos carácteres de un texto por otros, indicando en primer parámetro el texto original, luego el número del caracter donde se empezará el reemplazo, luego el número de carácteres que se reemplazarán después del caracter inicial, y el texto nuevo, que es con lo que se reemplazará dicho caracter.\n", 206 | "\n", 207 | "* $SUSTITUIR\\backsim(texto, texto-original, texto-nuevo)$\n", 208 | "\n", 209 | " Esta función reemplaza ciertas partes del texto por los carácteres indicados. Es muy usada ya que permite repetir algunos cambios. Los parámetros son fáciles de comprender: en texto irá el texto que queremos cambiar, en texto-original pondremos los carácteres que queremos cambiar y en texto-nuevo los carácteres que sustituirán dicho texto.\n", 210 | "\n", 211 | "* $ESPACIOS\\backsim(texto)$\n", 212 | "\n", 213 | " Elimina los espacios al inicio y final de la cadena.\n", 214 | "\n", 215 | "* $IZQUIERDA\\backsim(texto, (núm-caracteres))$\n", 216 | "* $DERECHA\\backsim(texto, (núm-caracteres))$\n", 217 | "\n", 218 | " Devuelve el número de carácteres de la izquierda o derecha de un texto. Por default si no indicamos el número de carácteres sólo nos devolverá el del extremo indicado. \n", 219 | "\n", 220 | "* $LARGO\\backsim(texto)$\n", 221 | "\n", 222 | " Devuelve el número de carácteres de una cadena, contabilizando espacios. \n", 223 | "\n", 224 | "* $MAYUSC\\backsim(texto)$\n", 225 | "* $MINUSC\\backsim(texto)$\n", 226 | "\n", 227 | " Convierte el texto en mayúscula o minúscula según sea el caso\n", 228 | "\n", 229 | "* $NOMPROPIO\\backsim((texto)$\n", 230 | "\n", 231 | " Convierte la primer letra de un texto en mayúscula\n", 232 | "\n", 233 | "\n", 234 | "## LOGICAS\n", 235 | "\n", 236 | "* $SI\\backsim(prueba_logica, (valor-si-verdadero), (valor-si-falso))$\n", 237 | "\n", 238 | " Evalua una condición y regresa respectivos valores si se cumplen o no.\n", 239 | "\n", 240 | "* $SI.ERROR\\backsim(valor, valor-si-error))$\n", 241 | "\n", 242 | " Evalua un valor, si este resulta en un error se reemplaza con el valor indicado en valor-si-error.\n", 243 | "\n", 244 | "* $Y\\backsim(valor-logico1, valor-logico2, valor-logico3, ... , valor-logico-enesimo)$\n", 245 | "* $O\\backsim(valor-logico1, valor-logico2, valor-logico3, ... , valor-logico-enesimo)$\n", 246 | "\n", 247 | " Comprueban si las condiciones planteadas son verdaderas o falsas, y según su valor en la tabla de verdad determinan si es un valor verdadero o falso en general para todas las condiciones.\n", 248 | "\n", 249 | "## BÚSQUEDA\n", 250 | "\n", 251 | "A continuación solamente enunciaremos una de las más importantes, sin embargo hay algunas otras que se irán descubriendo en el proceso.\n", 252 | "\n", 253 | "* $BUSCARV\\backsim(valor-buscado, matriz-tabla, indicador-columnas, (rango))$\n", 254 | "\n", 255 | " Valor buscado es el parámetro que indica lo que estamos buscando, matriz-tabla indica dónde buscaremos, indicador-columnas indica en qué columna estaremos buscando y rango puede ser 0 o 1, donde 0 es una búsqueda exacta y 1 es un sólo encontrar coincidencias.\n", 256 | "\n", 257 | "\n", 258 | "\n", 259 | "\n", 260 | "\n", 261 | "\n", 262 | "\n" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": { 268 | "id": "_yMmhJhJgSEu" 269 | }, 270 | "source": [ 271 | "\n", 272 | "# 3. Ejercicios:\n", 273 | "\n", 274 | "Dentro del siguiente link encontraremos material a considerar para la demostración de ejercicios:\n", 275 | "\n", 276 | "https://drive.google.com/drive/folders/1uZdq0ynsdChVLDDD5IZlCU2mY3eA6z3i?usp=sharing\n", 277 | "\n" 278 | ] 279 | } 280 | ], 281 | "metadata": { 282 | "colab": { 283 | "include_colab_link": true, 284 | "provenance": [], 285 | "toc_visible": true 286 | }, 287 | "kernelspec": { 288 | "display_name": "Python 3 (ipykernel)", 289 | "language": "python", 290 | "name": "python3" 291 | }, 292 | "language_info": { 293 | "codemirror_mode": { 294 | "name": "ipython", 295 | "version": 3 296 | }, 297 | "file_extension": ".py", 298 | "mimetype": "text/x-python", 299 | "name": "python", 300 | "nbconvert_exporter": "python", 301 | "pygments_lexer": "ipython3", 302 | "version": "3.11.6" 303 | } 304 | }, 305 | "nbformat": 4, 306 | "nbformat_minor": 4 307 | } 308 | -------------------------------------------------------------------------------- /05_BasesDeDatos/.ipynb_checkpoints/04_HojasDeCalculo-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "Y7eEouik1z4K" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

Análisis de datos con Excel: Introducción a distintas funciones de excel

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 24 | "
Ayudante: Diana Laura Rojas Cristino
\n", 25 | "
Ayudante: Rodrigo Alejandro Sánchez Morales
\n", 26 | "
Materia: Manejo de Datos
\n", 27 | "
" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "M8AFH5zC30RZ" 34 | }, 35 | "source": [ 36 | "\n", 37 | "## Contenido\n", 38 | "\n", 39 | "- [Objetivos Generales](#OG)\n", 40 | "\n", 41 | "- [Objetivos Particulares](#OP)\n", 42 | "\n", 43 | "- [Introducción](#Int)\n", 44 | "\n", 45 | "- [Operadores básicos de Excel](#1)\n", 46 | "\n", 47 | "- [Funciones importantes a conocer en Excel](#2)\n" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": { 53 | "id": "tXGNXr1y4H7Q" 54 | }, 55 | "source": [ 56 | "\n", 57 | "## Objetivos Generales\n", 58 | "\n", 59 | "- Que el alumno tenga noción de algunas de las principales funciones de Excel para el análisis de datos." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "id": "hnhTcYPl51Qp" 66 | }, 67 | "source": [ 68 | "\n", 69 | "## Objetivos Particulares\n", 70 | "- Conocer los operadores básicos de Excel\n", 71 | "- Conocer algunas de las funciones básicas de Excel para el análisis de datos, tales como aquellas que funcionan en números, fechas, texto y búsqueda.\n" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": { 77 | "id": "VIogRBst9g6q" 78 | }, 79 | "source": [ 80 | "\n", 81 | "# Introducción\n", 82 | "\n", 83 | "Excel es una herramienta poderosa y versátil que puede utilizarse tanto en el ámbito escolar como en el entorno laboral. Es una aplicación de hojas de cálculo que permite organizar, analizar y presentar datos de manera efectiva.\n", 84 | "\n", 85 | "Esencialmente, Excel es una herramienta que ayuda a simplificar procesos y a aumentar la eficiencia y precisión en el manejo de datos. En el ámbito escolar, Excel es una herramienta valiosa para la gestión de notas, seguimiento del progreso académico y la realización de proyectos y trabajos de investigación. Permite a los estudiantes organizar y analizar datos de manera efectiva, lo que les ayuda a comprender mejor la información y tomar decisiones basadas en datos. \n", 86 | "\n", 87 | "En el entorno laboral, Excel es una herramienta esencial para la gestión de datos financieros, la creación de informes y el análisis de datos. Permite a las empresas automatizar procesos, reducir errores y tomar decisiones informadas basadas en datos precisos y actualizados. \n", 88 | "\n", 89 | "Simultáneamente a la necesidad de Excel en la vida cotidiana, escolar y laboral, desde hace años el ímpetu del análisis de datos ha tomado más importancia en muchas empresas sin importar el ramo. Por lo anterior, los presentes notebooks tienen como fin ayudar en la comprensión y utilización de Excel para el análisis de datos.\n" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "id": "Wt_mF3jUAorA" 96 | }, 97 | "source": [ 98 | "\n", 99 | "# Operadores básicos de Excel.\n", 100 | "\n", 101 | "## Numéricos:\n", 102 | "\n", 103 | "1. $+$, realiza la suma de las celdas que se indiquen entre cada signo.\n", 104 | "2. $-$, realiza la resta de las celdas que se indiquen entre cada signo.\n", 105 | "3. $*$, realiza la multiplicación de las celdas que se indiquen entre cada signo.\n", 106 | "4. $/$, realiza la división de las cledas que se indiquen entre cada signo\n", 107 | "5. $^$, eleva a cierta potencia un número\n", 108 | "\n", 109 | "## Lógicos:\n", 110 | "1. $=$: Igual\n", 111 | "2. $>$: Mayor que\n", 112 | "3. $<$: Menor que\n", 113 | "4. $>=$: Mayor o igual que\n", 114 | "5. $<=$: Menor o igual que\n", 115 | "6. $<>$: Distinto que\n", 116 | "\n", 117 | "## Concatenación de texto:\n", 118 | "1. $&$, concatena el texto de varias celdas\n", 119 | "\n", 120 | "\n", 121 | "[Ir al índice](#Contenido)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": { 127 | "id": "mCV2T_4Bikoi" 128 | }, 129 | "source": [ 130 | "\n", 131 | "# 2. Funciones importantes a conocer de Excel\n", 132 | "\n", 133 | "A continuación se mencionan algunas de las primeras funciones de Excel que utilizaremos en esta sesión, así como sus parámetros y las indicaciones que hay que tener para su buen funcionamiento:\n", 134 | "\n", 135 | "## Numéricas: \n", 136 | "\n", 137 | "\n", 138 | "* $SUMA\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 139 | "\n", 140 | " Realiza la suma de las celdas que contengan números e indiquemos. Este proceso es muy usado para no indicar repetidamente el símbolo \"+\" entre cada celda\n", 141 | "\n", 142 | "* $MIN\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 143 | "\n", 144 | " Calcula el mínimo de una selección de celdas que contienen números\n", 145 | "\n", 146 | "* $MAX\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 147 | "\n", 148 | " Calcula el máximo de una selección de celdas que contienen números\n", 149 | "\n", 150 | "* $RAIZ\\backsim(número)$\n", 151 | "\n", 152 | " Calcula la raíz cuadrada de un número contenido en una celda\n", 153 | "\n", 154 | "* $REDONDEAR\\backsim(número, número de decimales)$\n", 155 | "\n", 156 | " Redondea un número contenido en una celda según las posiciones de decimales que indiquemos.\n", 157 | "\n", 158 | "* $ENTERO\\backsim(número)$\n", 159 | "\n", 160 | " Devuelve el número entero de una celda\n", 161 | "\n", 162 | "* $PROMEDIO\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 163 | "\n", 164 | " Realiza el promedio de las celdas que contengan números e indiquemos. \n", 165 | "\n", 166 | "* $CONTAR\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 167 | "\n", 168 | " Cuenta el número de celdas que tienen contenido\n", 169 | "\n", 170 | "* $ALEATORIO\\backsim()$\n", 171 | "\n", 172 | " Devuelve un número aleatorio entre 0 y 1\n", 173 | "\n", 174 | "* $RESIDUO\\backsim(número, númerodivisor)$\n", 175 | "\n", 176 | " Devuelve el residuo entre dos números, indicando cuál es el dividendo y el divisor\n", 177 | "\n", 178 | "* $DESVEST\\backsim(número 1, número 2, número 3, ..., n-número)$\n", 179 | " Calcula la desviación estandar de una muestra\n", 180 | "\n", 181 | "## FECHAS\n", 182 | "\n", 183 | "* $AÑO\\backsim(fecha)$\n", 184 | "* $MES\\backsim(fecha)$\n", 185 | "* $DIA\\backsim(fecha)$\n", 186 | "\n", 187 | " Devuelve el año, mes o día (según corresponda) de la celda indicada, la cual debe ser una fecha\n", 188 | "\n", 189 | "* $DIAS\\backsim(fecha_inicial, fecha_final)$\n", 190 | "\n", 191 | " Calcula el número de días entre dos fechas\n", 192 | "\n", 193 | "* $NUM.DE.SEMANA\\backsim(fecha)$\n", 194 | "\n", 195 | " Regresa el número de semana en la que se encuentra la fecha indicada\n", 196 | "\n", 197 | "* $DIAS.LAB\\backsim(fecha-inicial, fecha-final, (vacaciones))$\n", 198 | "\n", 199 | " Regresa el número de días entre dos fechas, pero sólo considera días laborales (no considera fines de semana), además puedes añadir un parámetro adicional con los días de vacaciones.\n", 200 | "\n", 201 | "## TEXTO:\n", 202 | "\n", 203 | "* $REEMPLAZAR\\backsim(texto-original, núm-inicial, núm-caracteres, texto-nuevo)$\n", 204 | " \n", 205 | " Esta función, como su nombre lo indica, permite reemplazar ciertos carácteres de un texto por otros, indicando en primer parámetro el texto original, luego el número del caracter donde se empezará el reemplazo, luego el número de carácteres que se reemplazarán después del caracter inicial, y el texto nuevo, que es con lo que se reemplazará dicho caracter.\n", 206 | "\n", 207 | "* $SUSTITUIR\\backsim(texto, texto-original, texto-nuevo)$\n", 208 | "\n", 209 | " Esta función reemplaza ciertas partes del texto por los carácteres indicados. Es muy usada ya que permite repetir algunos cambios. Los parámetros son fáciles de comprender: en texto irá el texto que queremos cambiar, en texto-original pondremos los carácteres que queremos cambiar y en texto-nuevo los carácteres que sustituirán dicho texto.\n", 210 | "\n", 211 | "* $ESPACIOS\\backsim(texto)$\n", 212 | "\n", 213 | " Elimina los espacios al inicio y final de la cadena.\n", 214 | "\n", 215 | "* $IZQUIERDA\\backsim(texto, (núm-caracteres))$\n", 216 | "* $DERECHA\\backsim(texto, (núm-caracteres))$\n", 217 | "\n", 218 | " Devuelve el número de carácteres de la izquierda o derecha de un texto. Por default si no indicamos el número de carácteres sólo nos devolverá el del extremo indicado. \n", 219 | "\n", 220 | "* $LARGO\\backsim(texto)$\n", 221 | "\n", 222 | " Devuelve el número de carácteres de una cadena, contabilizando espacios. \n", 223 | "\n", 224 | "* $MAYUSC\\backsim(texto)$\n", 225 | "* $MINUSC\\backsim(texto)$\n", 226 | "\n", 227 | " Convierte el texto en mayúscula o minúscula según sea el caso\n", 228 | "\n", 229 | "* $NOMPROPIO\\backsim((texto)$\n", 230 | "\n", 231 | " Convierte la primer letra de un texto en mayúscula\n", 232 | "\n", 233 | "\n", 234 | "## LOGICAS\n", 235 | "\n", 236 | "* $SI\\backsim(prueba_logica, (valor-si-verdadero), (valor-si-falso))$\n", 237 | "\n", 238 | " Evalua una condición y regresa respectivos valores si se cumplen o no.\n", 239 | "\n", 240 | "* $SI.ERROR\\backsim(valor, valor-si-error))$\n", 241 | "\n", 242 | " Evalua un valor, si este resulta en un error se reemplaza con el valor indicado en valor-si-error.\n", 243 | "\n", 244 | "* $Y\\backsim(valor-logico1, valor-logico2, valor-logico3, ... , valor-logico-enesimo)$\n", 245 | "* $O\\backsim(valor-logico1, valor-logico2, valor-logico3, ... , valor-logico-enesimo)$\n", 246 | "\n", 247 | " Comprueban si las condiciones planteadas son verdaderas o falsas, y según su valor en la tabla de verdad determinan si es un valor verdadero o falso en general para todas las condiciones.\n", 248 | "\n", 249 | "## BÚSQUEDA\n", 250 | "\n", 251 | "A continuación solamente enunciaremos una de las más importantes, sin embargo hay algunas otras que se irán descubriendo en el proceso.\n", 252 | "\n", 253 | "* $BUSCARV\\backsim(valor-buscado, matriz-tabla, indicador-columnas, (rango))$\n", 254 | "\n", 255 | " Valor buscado es el parámetro que indica lo que estamos buscando, matriz-tabla indica dónde buscaremos, indicador-columnas indica en qué columna estaremos buscando y rango puede ser 0 o 1, donde 0 es una búsqueda exacta y 1 es un sólo encontrar coincidencias.\n", 256 | "\n", 257 | "\n", 258 | "\n", 259 | "\n", 260 | "\n", 261 | "\n", 262 | "\n" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": { 268 | "id": "_yMmhJhJgSEu" 269 | }, 270 | "source": [ 271 | "\n", 272 | "# 3. Ejercicios:\n", 273 | "\n", 274 | "Dentro del siguiente link encontraremos material a considerar para la demostración de ejercicios:\n", 275 | "\n", 276 | "https://drive.google.com/drive/folders/1uZdq0ynsdChVLDDD5IZlCU2mY3eA6z3i?usp=sharing\n", 277 | "\n" 278 | ] 279 | } 280 | ], 281 | "metadata": { 282 | "colab": { 283 | "include_colab_link": true, 284 | "provenance": [], 285 | "toc_visible": true 286 | }, 287 | "kernelspec": { 288 | "display_name": "Python 3 (ipykernel)", 289 | "language": "python", 290 | "name": "python3" 291 | }, 292 | "language_info": { 293 | "codemirror_mode": { 294 | "name": "ipython", 295 | "version": 3 296 | }, 297 | "file_extension": ".py", 298 | "mimetype": "text/x-python", 299 | "name": "python", 300 | "nbconvert_exporter": "python", 301 | "pygments_lexer": "ipython3", 302 | "version": "3.11.6" 303 | } 304 | }, 305 | "nbformat": 4, 306 | "nbformat_minor": 4 307 | } 308 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/.ipynb_checkpoints/04_02_ArbolAdivinador-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ff0f0ccb", 6 | "metadata": {}, 7 | "source": [ 8 | "\n", 9 | "

Arbol Adivinador

\n", 10 | "
\n", 11 | " \n", 12 | "
Profesor: M.en.C. Miguel Angel Pérez León
\n", 13 | "
Ayudante: Jesús Iván Coss Calderón
\n", 14 | "
Ayudante: Jonathan Ramírez Montes
\n", 15 | "
Materia: Manejo de Datos
\n", 16 | "
" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "id": "4da85cca", 22 | "metadata": {}, 23 | "source": [ 24 | "**Objetivo general**\n", 25 | "\n", 26 | "* Conocer el funcionamiento de una estructura de datos de tipo árbol\n", 27 | "\n", 28 | "**Objetivos particulares**\n", 29 | "\n", 30 | "* Conocer el funcionamiento del árbol adivinador\n", 31 | "\n", 32 | "## Contenido\n", 33 | "\n", 34 | "- [Introducción](#1)\n", 35 | "- [Arbol Adivinador](#2)\n", 36 | " - [Descripción del algoritmo ](#2-1)\n", 37 | " - [Implementación del algoritmo](#2-2)\n", 38 | "- [Clase Nodo](#3)\n", 39 | "- [Clase ArbolAdivinador](#4)\n", 40 | "- [Referencias](#5)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "0b6ce2a8", 46 | "metadata": {}, 47 | "source": [ 48 | "\n", 49 | "\n", 50 | "# Introducción \n", 51 | "\n", 52 | "Los árboles binarios no solo sirven para realizar búsquedas, de hecho los árboles se ocupan de manera muy frecuente en áreas como bases de datos, inteligencia artificial o sistemas operativos.\n", 53 | "\n", 54 | "En esta presentación vamos a ver el ejemplo de algoritmo empleado desde hace mucho tiempo para simular aprendizaje y con base en este aprendizaje (base de conocimiento) lograr predecir lo que piensa el usuario." 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "id": "ca9ccf1a", 60 | "metadata": {}, 61 | "source": [ 62 | "\n", 63 | "\n", 64 | "# Arbol Adivinador\n", 65 | "\n", 66 | "Este árbol (igual que los que veremos más adelante) esta conformado por nodos, la única diferencia es que en este árbol binario de búsqueda, cada nodo interno (nodo que no sea una hoja) contiene una pregunta y cada hoja del árbol es un animal.\n", 67 | "\n", 68 | "Haciendo uso de la estructura de datos conocida como árbol binario, vamos a tratar de adivinar el animal en el que esta pensando el usuario, en caso de adivinar el objetivo se logro, pero en caso contrario se le pide al usuario que indique en que animal estaba pensando y en como diferenciarlo del animal que le mostró el algoritmo.\n", 69 | "\n", 70 | "La idea detrás de este algoritmo es muy sencilla y muy parecida a la **búsqueda binaria**, cada pregunta que se le realiza al usuario descarta una gran cantidad de posibles animales, ya que la respuesta es booleana y eso acota el posible espacio de búsqueda.\n", 71 | "\n", 72 | "De igual manera que con los árboles binarios, cada nodo del árbol adivinador se ve de la siguiente forma.\n", 73 | "\n", 74 | "
\n", 75 | " \n", 76 | "
\n", 77 | "\n", 78 | "Aunque una sutil diferencia es que el dato contenido dentro de cada nodo intermedio será una pregunta, las hojas serán animales, las respuestas afirmativas a cada pregunta son los hijos izquierdos de todo nodo interno y las respuestas negativas son los hijos derechos de cada nodo intermedio." 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "id": "79a88043", 84 | "metadata": {}, 85 | "source": [ 86 | "\n", 87 | "\n", 88 | "## Descripción del algoritmo \n", 89 | "\n", 90 | "El árbol comienza con un solo nodo (la raíz) y esa es la base de conocimiento, así que el programa le pregunta al usuario si el animal que esta pensando es ese que contiene la raíz, digamos un pájaro.\n", 91 | "\n", 92 | "
\n", 93 | " \n", 94 | "
\n", 95 | "\n", 96 | "Si la respuesta es afirmativa, el algoritmo cumple con su objetivo ya que adivino el animal que estaba pensando el usuario. Sin embargo en caso de que la respuesta sea negativa, es decir que no se adivino el animal que estaba pensando el usuario, se le pide al usuario indicar el animal que estaba pensando y como diferenciarlo del animal que le mostró el programa.\n", 97 | "\n", 98 | "
\n", 99 | " \n", 100 | "
\n", 101 | "\n", 102 | "Se puede apreciar en esta imagen que las respuestas afirmativas son los hijos izquierdos de todo nodo y que las respuestas negativas son los hijos derechos de cada nodo. Conforme el programa es más usado, la base de conocimiento se incrementa cada vez más, hasta tener un árbol suficientemente entrenado como para poder adivinar cualquier animal, sin importar lo especifico que este sea.\n", 103 | "\n", 104 | "
\n", 105 | " \n", 106 | "
\n", 107 | "\n", 108 | "Es importante notar que el árbol adivinador será tan preciso como la información que se le proporcione." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "id": "18996aa6", 114 | "metadata": {}, 115 | "source": [ 116 | "\n", 117 | "\n", 118 | "## Implementación del algoritmo\n", 119 | "\n", 120 | "Ya que nos hemos familiarizado con el uso de la POO, vamos a hacer uso de clases para implementar nuestro algoritmo.\n", 121 | "\n", 122 | "Vamos a hacer uso de la clase Nodo y de la clase ArbolAdivinador, normalmente la clase Nodo se define como clase interna dentro de la clase ArbolBinario con la intención de ocultar algunas de sus características además de reafirmar el hecho de que no se pueden crear árboles si no se tienen nodos." 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "id": "c4a3f7fd", 128 | "metadata": {}, 129 | "source": [ 130 | "\n", 131 | "\n", 132 | "## Clase Nodo\n", 133 | "\n", 134 | "La clase `Nodo`, es una clase muy sencilla que solo consta del constructor, un par de atributos y un par de métodos." 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 2, 140 | "id": "41edc1bc", 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "Esto es una prueba\n", 148 | "Soy el hijo izquierdo\n", 149 | "Soy el hijo derecho\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "#Clase Nodo que hereda de la clase object\n", 155 | "class Nodo(object):\n", 156 | " # Constructor de Nodos\n", 157 | " def __init__(self, value):\n", 158 | " self.izq = None\n", 159 | " self.dato = value\n", 160 | " self.der = None\n", 161 | " self.padre = None\n", 162 | "\n", 163 | " # Sobrecarga del metodo string para imprimir el dato del nodo\n", 164 | " def __str__(self):\n", 165 | " if self.dato is None:\n", 166 | " pass\n", 167 | " else:\n", 168 | " return '{}'.format(self.dato)\n", 169 | "\n", 170 | "# Se crean los nodos necesarios\n", 171 | "raiz = Nodo(\"Esto es una prueba\")\n", 172 | "hijoizq = Nodo(\"Soy el hijo izquierdo\")\n", 173 | "hijoder = Nodo(\"Soy el hijo derecho\")\n", 174 | "\n", 175 | "# De manera manual se genera un ABB\n", 176 | "raiz.izq = hijoizq\n", 177 | "raiz.der = hijoder\n", 178 | "\n", 179 | "# pruebas de la clase Nodo\n", 180 | "print(raiz)\n", 181 | "print(raiz.izq)\n", 182 | "print(raiz.der)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "id": "c8fcf275", 188 | "metadata": {}, 189 | "source": [ 190 | "\n", 191 | "\n", 192 | "# Clase ArbolAdivinador\n", 193 | "\n", 194 | "La clase `ArbolAdivinador` se encarga organizar los nodo de tal forma que podamos construir un árbol binario que nos permita adivinar el animal en el que esta pensando el usuario." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 3, 200 | "id": "001a82cf", 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "name": "stdout", 205 | "output_type": "stream", 206 | "text": [ 207 | "Estas pensando en un animal? Si\n", 208 | "Es un pajaro? si\n", 209 | "¡Soy el más grande!\n", 210 | "███████████████████████████████─\n", 211 | "──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\n", 212 | "────────▀█▄█▄█▀──────▀█▄█▄█▀────\n", 213 | "Estas pensando en un animal? No\n", 214 | "Gracias por jugar :)\n" 215 | ] 216 | } 217 | ], 218 | "source": [ 219 | "#from string import lower\n", 220 | "\n", 221 | "'''Clase basada en arboles binarios para identificar en que\n", 222 | "animal estas pensando'''\n", 223 | "class ArbolAdivinador(object):\n", 224 | " \n", 225 | " # Constructor de adivinadores\n", 226 | " def __init__(self):\n", 227 | " self.raiz = Nodo(\"pajaro\")\n", 228 | " \n", 229 | " #Funcion para determinar si se desea continuar con mas preguntas\n", 230 | " def si(self, preg):\n", 231 | " #se muestra una pregunta en consola y se pide la respuesta del usuario\n", 232 | " resp = str.lower(input(preg))\n", 233 | " return (resp[0] == 's')\n", 234 | " \n", 235 | " def adivina(self):\n", 236 | " ciclo = True\n", 237 | " while ciclo:\n", 238 | " #en caso de no querer continuar con mas preguntas\n", 239 | " if not self.si(\"Estas pensando en un animal? \"):\n", 240 | " print('Gracias por jugar :)')\n", 241 | " break\n", 242 | " #nodo temporal que sirve para recorrer el arbol\n", 243 | " temporal = self.raiz\n", 244 | " #se hacen preguntas al usuario hasta llegar a una hoja\n", 245 | " #siempre que se tenga hijo izquierdo podemos preguntar\n", 246 | " while temporal.izq != None:\n", 247 | " #si la respuesta es afirmativa avanzamos al hijo izquierdo\n", 248 | " if self.si(temporal.dato + \"? \"):\n", 249 | " temporal = temporal.izq\n", 250 | " #de otra forma avanza al hijo derecho\n", 251 | " else:\n", 252 | " temporal = temporal.der\n", 253 | " #se llega a un nodo hoja\n", 254 | " animal = temporal.dato\n", 255 | " #si se adivino termina, en caso contrario hay que obtener info.\n", 256 | " if self.si(\"Es un \" + animal + \"? \"):\n", 257 | " print(\"¡Soy el más grande!\")\n", 258 | " print(\"███████████████████████████████─\")\n", 259 | " print(\"──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\")\n", 260 | " print(\"────────▀█▄█▄█▀──────▀█▄█▄█▀────\")\n", 261 | " else:\n", 262 | " #nuevo animal\n", 263 | " nuevo = input(\"¿Qué animal era? \")\n", 264 | " #nueva pregunta para diferenciar a la hoja actual del nuevo animal\n", 265 | " info = input(\"¿Qué diferencia a un \" + animal + \" de un \" + nuevo + \"? \")\n", 266 | " #se actualiza el nodo con la nueva pregunta\n", 267 | " temporal.dato = info\n", 268 | " #se agrega como izquierdo al animal que estaba en la hoja\n", 269 | " temporal.izq = Nodo(animal)\n", 270 | " #y como derecho el nuevo animal\n", 271 | " temporal.der = Nodo(nuevo)\n", 272 | " \n", 273 | "def main():\n", 274 | " adivino = ArbolAdivinador()\n", 275 | " adivino.adivina()\n", 276 | "\n", 277 | "main()" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "id": "6346b89a", 283 | "metadata": {}, 284 | "source": [ 285 | "\n", 286 | "\n", 287 | "# Referencias\n", 288 | "\n", 289 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 290 | "2. Referencias Libro Web: Introduccion a Python.\n", 291 | "3. Referencias Daniel T. Joyce: Object-Oriented Data Structures.\n", 292 | "4. Referencias John C. Mitchell: Concepts in programing Languages." 293 | ] 294 | } 295 | ], 296 | "metadata": { 297 | "kernelspec": { 298 | "display_name": "Python 3 (ipykernel)", 299 | "language": "python", 300 | "name": "python3" 301 | }, 302 | "language_info": { 303 | "codemirror_mode": { 304 | "name": "ipython", 305 | "version": 3 306 | }, 307 | "file_extension": ".py", 308 | "mimetype": "text/x-python", 309 | "name": "python", 310 | "nbconvert_exporter": "python", 311 | "pygments_lexer": "ipython3", 312 | "version": "3.8.10" 313 | } 314 | }, 315 | "nbformat": 4, 316 | "nbformat_minor": 5 317 | } 318 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/04_02_ArbolAdivinador.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ff0f0ccb", 6 | "metadata": {}, 7 | "source": [ 8 | "\n", 9 | "

Arbol Adivinador

\n", 10 | "
\n", 11 | " \n", 12 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 13 | "
Ayudante: Diana Laura Rojas Cristino
\n", 14 | "
Ayudante: Rodrigo Alejandro Sánchez Morales
\n", 15 | "
Materia: Manejo de Datos
\n", 16 | "
" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "id": "4da85cca", 22 | "metadata": {}, 23 | "source": [ 24 | "**Objetivo general**\n", 25 | "\n", 26 | "* Conocer el funcionamiento de una estructura de datos de tipo árbol\n", 27 | "\n", 28 | "**Objetivos particulares**\n", 29 | "\n", 30 | "* Conocer el funcionamiento del árbol adivinador\n", 31 | "\n", 32 | "## Contenido\n", 33 | "\n", 34 | "- [Introducción](#1)\n", 35 | "- [Arbol Adivinador](#2)\n", 36 | " - [Descripción del algoritmo ](#2-1)\n", 37 | " - [Implementación del algoritmo](#2-2)\n", 38 | "- [Clase Nodo](#3)\n", 39 | "- [Clase ArbolAdivinador](#4)\n", 40 | "- [Referencias](#5)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "0b6ce2a8", 46 | "metadata": {}, 47 | "source": [ 48 | "\n", 49 | "\n", 50 | "# Introducción \n", 51 | "\n", 52 | "Los árboles binarios no solo sirven para realizar búsquedas, de hecho los árboles se ocupan de manera muy frecuente en áreas como bases de datos, inteligencia artificial o sistemas operativos.\n", 53 | "\n", 54 | "En esta presentación vamos a ver el ejemplo de algoritmo empleado desde hace mucho tiempo para simular aprendizaje y con base en este aprendizaje (base de conocimiento) lograr predecir lo que piensa el usuario." 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "id": "ca9ccf1a", 60 | "metadata": {}, 61 | "source": [ 62 | "\n", 63 | "\n", 64 | "# Arbol Adivinador\n", 65 | "\n", 66 | "Este árbol (igual que los que veremos más adelante) esta conformado por nodos, la única diferencia es que en este árbol binario de búsqueda, cada nodo interno (nodo que no sea una hoja) contiene una pregunta y cada hoja del árbol es un animal.\n", 67 | "\n", 68 | "Haciendo uso de la estructura de datos conocida como árbol binario, vamos a tratar de adivinar el animal en el que esta pensando el usuario, en caso de adivinar el objetivo se logro, pero en caso contrario se le pide al usuario que indique en que animal estaba pensando y en como diferenciarlo del animal que le mostró el algoritmo.\n", 69 | "\n", 70 | "La idea detrás de este algoritmo es muy sencilla y muy parecida a la **búsqueda binaria**, cada pregunta que se le realiza al usuario descarta una gran cantidad de posibles animales, ya que la respuesta es booleana y eso acota el posible espacio de búsqueda.\n", 71 | "\n", 72 | "De igual manera que con los árboles binarios, cada nodo del árbol adivinador se ve de la siguiente forma.\n", 73 | "\n", 74 | "
\n", 75 | " \n", 76 | "
\n", 77 | "\n", 78 | "Aunque una sutil diferencia es que el dato contenido dentro de cada nodo intermedio será una pregunta, las hojas serán animales, las respuestas afirmativas a cada pregunta son los hijos izquierdos de todo nodo interno y las respuestas negativas son los hijos derechos de cada nodo intermedio." 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "id": "79a88043", 84 | "metadata": {}, 85 | "source": [ 86 | "\n", 87 | "\n", 88 | "## Descripción del algoritmo \n", 89 | "\n", 90 | "El árbol comienza con un solo nodo (la raíz) y esa es la base de conocimiento, así que el programa le pregunta al usuario si el animal que esta pensando es ese que contiene la raíz, digamos un pájaro.\n", 91 | "\n", 92 | "
\n", 93 | " \n", 94 | "
\n", 95 | "\n", 96 | "Si la respuesta es afirmativa, el algoritmo cumple con su objetivo ya que adivino el animal que estaba pensando el usuario. Sin embargo en caso de que la respuesta sea negativa, es decir que no se adivino el animal que estaba pensando el usuario, se le pide al usuario indicar el animal que estaba pensando y como diferenciarlo del animal que le mostró el programa.\n", 97 | "\n", 98 | "
\n", 99 | " \n", 100 | "
\n", 101 | "\n", 102 | "Se puede apreciar en esta imagen que las respuestas afirmativas son los hijos izquierdos de todo nodo y que las respuestas negativas son los hijos derechos de cada nodo. Conforme el programa es más usado, la base de conocimiento se incrementa cada vez más, hasta tener un árbol suficientemente entrenado como para poder adivinar cualquier animal, sin importar lo especifico que este sea.\n", 103 | "\n", 104 | "
\n", 105 | " \n", 106 | "
\n", 107 | "\n", 108 | "Es importante notar que el árbol adivinador será tan preciso como la información que se le proporcione." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "id": "18996aa6", 114 | "metadata": {}, 115 | "source": [ 116 | "\n", 117 | "\n", 118 | "## Implementación del algoritmo\n", 119 | "\n", 120 | "Ya que nos hemos familiarizado con el uso de la POO, vamos a hacer uso de clases para implementar nuestro algoritmo.\n", 121 | "\n", 122 | "Vamos a hacer uso de la clase Nodo y de la clase ArbolAdivinador, normalmente la clase Nodo se define como clase interna dentro de la clase ArbolBinario con la intención de ocultar algunas de sus características además de reafirmar el hecho de que no se pueden crear árboles si no se tienen nodos." 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "id": "c4a3f7fd", 128 | "metadata": {}, 129 | "source": [ 130 | "\n", 131 | "\n", 132 | "## Clase Nodo\n", 133 | "\n", 134 | "La clase `Nodo`, es una clase muy sencilla que solo consta del constructor, un par de atributos y un par de métodos." 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 1, 140 | "id": "41edc1bc", 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "Esto es una prueba\n", 148 | "Soy el hijo izquierdo\n", 149 | "Soy el hijo derecho\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "#Clase Nodo que hereda de la clase object\n", 155 | "class Nodo(object):\n", 156 | " # Constructor de Nodos\n", 157 | " def __init__(self, value):\n", 158 | " self.izq = None\n", 159 | " self.dato = value\n", 160 | " self.der = None\n", 161 | " self.padre = None\n", 162 | "\n", 163 | " # Sobrecarga del metodo string para imprimir el dato del nodo\n", 164 | " def __str__(self):\n", 165 | " if self.dato is None:\n", 166 | " pass\n", 167 | " else:\n", 168 | " return '{}'.format(self.dato)\n", 169 | "\n", 170 | "# Se crean los nodos necesarios\n", 171 | "raiz = Nodo(\"Esto es una prueba\")\n", 172 | "hijoizq = Nodo(\"Soy el hijo izquierdo\")\n", 173 | "hijoder = Nodo(\"Soy el hijo derecho\")\n", 174 | "\n", 175 | "# De manera manual se genera un ABB\n", 176 | "raiz.izq = hijoizq\n", 177 | "raiz.der = hijoder\n", 178 | "\n", 179 | "# pruebas de la clase Nodo\n", 180 | "print(raiz)\n", 181 | "print(raiz.izq)\n", 182 | "print(raiz.der)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "id": "c8fcf275", 188 | "metadata": {}, 189 | "source": [ 190 | "\n", 191 | "\n", 192 | "# Clase ArbolAdivinador\n", 193 | "\n", 194 | "La clase `ArbolAdivinador` se encarga organizar los nodo de tal forma que podamos construir un árbol binario que nos permita adivinar el animal en el que esta pensando el usuario." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "id": "001a82cf", 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "name": "stdin", 205 | "output_type": "stream", 206 | "text": [ 207 | "Estas pensando en un animal? si\n", 208 | "Es un pajaro? no\n", 209 | "¿Qué animal era? rana\n", 210 | "¿Qué diferencia a un pajaro de un rana? salta\n", 211 | "Estas pensando en un animal? si\n", 212 | "salta? si\n", 213 | "Es un pajaro? no\n", 214 | "¿Qué animal era? rana\n", 215 | "¿Qué diferencia a un pajaro de un rana? salta\n", 216 | "Estas pensando en un animal? si\n", 217 | "salta? si\n", 218 | "salta? si\n", 219 | "Es un pajaro? si\n" 220 | ] 221 | }, 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "¡Soy el más grande!\n", 227 | "███████████████████████████████─\n", 228 | "──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\n", 229 | "────────▀█▄█▄█▀──────▀█▄█▄█▀────\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "#from string import lower\n", 235 | "\n", 236 | "'''Clase basada en arboles binarios para identificar en que\n", 237 | "animal estas pensando'''\n", 238 | "class ArbolAdivinador(object):\n", 239 | " \n", 240 | " # Constructor de adivinadores\n", 241 | " def __init__(self):\n", 242 | " self.raiz = Nodo(\"pajaro\")\n", 243 | " \n", 244 | " #Funcion para determinar si se desea continuar con mas preguntas\n", 245 | " def si(self, preg):\n", 246 | " #se muestra una pregunta en consola y se pide la respuesta del usuario\n", 247 | " resp = str.lower(input(preg))\n", 248 | " return (resp[0] == 's')\n", 249 | " \n", 250 | " def adivina(self):\n", 251 | " ciclo = True\n", 252 | " while ciclo:\n", 253 | " #en caso de no querer continuar con mas preguntas\n", 254 | " if not self.si(\"Estas pensando en un animal? \"):\n", 255 | " print('Gracias por jugar :)')\n", 256 | " break\n", 257 | " #nodo temporal que sirve para recorrer el arbol\n", 258 | " temporal = self.raiz\n", 259 | " #se hacen preguntas al usuario hasta llegar a una hoja\n", 260 | " #siempre que se tenga hijo izquierdo podemos preguntar\n", 261 | " while temporal.izq != None:\n", 262 | " #si la respuesta es afirmativa avanzamos al hijo izquierdo\n", 263 | " if self.si(temporal.dato + \"? \"):\n", 264 | " temporal = temporal.izq\n", 265 | " #de otra forma avanza al hijo derecho\n", 266 | " else:\n", 267 | " temporal = temporal.der\n", 268 | " #se llega a un nodo hoja\n", 269 | " animal = temporal.dato\n", 270 | " #si se adivino termina, en caso contrario hay que obtener info.\n", 271 | " if self.si(\"Es un \" + animal + \"? \"):\n", 272 | " print(\"¡Soy el más grande!\")\n", 273 | " print(\"███████████████████████████████─\")\n", 274 | " print(\"──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\")\n", 275 | " print(\"────────▀█▄█▄█▀──────▀█▄█▄█▀────\")\n", 276 | " else:\n", 277 | " #nuevo animal\n", 278 | " nuevo = input(\"¿Qué animal era? \")\n", 279 | " #nueva pregunta para diferenciar a la hoja actual del nuevo animal\n", 280 | " info = input(\"¿Qué diferencia a un \" + animal + \" de un \" + nuevo + \"? \")\n", 281 | " #se actualiza el nodo con la nueva pregunta\n", 282 | " temporal.dato = info\n", 283 | " #se agrega como izquierdo al animal que estaba en la hoja\n", 284 | " temporal.izq = Nodo(animal)\n", 285 | " #y como derecho el nuevo animal\n", 286 | " temporal.der = Nodo(nuevo)\n", 287 | " \n", 288 | "def main():\n", 289 | " adivino = ArbolAdivinador()\n", 290 | " adivino.adivina()\n", 291 | "\n", 292 | "main()" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "id": "6346b89a", 298 | "metadata": {}, 299 | "source": [ 300 | "\n", 301 | "\n", 302 | "# Referencias\n", 303 | "\n", 304 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 305 | "2. Referencias Libro Web: Introduccion a Python.\n", 306 | "3. Referencias Daniel T. Joyce: Object-Oriented Data Structures.\n", 307 | "4. Referencias John C. Mitchell: Concepts in programing Languages." 308 | ] 309 | } 310 | ], 311 | "metadata": { 312 | "kernelspec": { 313 | "display_name": "Python 3 (ipykernel)", 314 | "language": "python", 315 | "name": "python3" 316 | }, 317 | "language_info": { 318 | "codemirror_mode": { 319 | "name": "ipython", 320 | "version": 3 321 | }, 322 | "file_extension": ".py", 323 | "mimetype": "text/x-python", 324 | "name": "python", 325 | "nbconvert_exporter": "python", 326 | "pygments_lexer": "ipython3", 327 | "version": "3.11.6" 328 | } 329 | }, 330 | "nbformat": 4, 331 | "nbformat_minor": 5 332 | } 333 | -------------------------------------------------------------------------------- /03_AlgoritmosBusqueda/04_ArbolesBinariosBusqueda/00_ArbolAdivinador/.ipynb_checkpoints/04_02_ArbolAdivinador-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ff0f0ccb", 6 | "metadata": {}, 7 | "source": [ 8 | "\n", 9 | "

Arbol Adivinador

\n", 10 | "
\n", 11 | " \n", 12 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 13 | "
Ayudante: Diana Laura Rojas Cristino
\n", 14 | "
Ayudante: Rodrigo Alejandro Sánchez Morales
\n", 15 | "
Materia: Manejo de Datos
\n", 16 | "
" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "id": "4da85cca", 22 | "metadata": {}, 23 | "source": [ 24 | "**Objetivo general**\n", 25 | "\n", 26 | "* Conocer el funcionamiento de una estructura de datos de tipo árbol\n", 27 | "\n", 28 | "**Objetivos particulares**\n", 29 | "\n", 30 | "* Conocer el funcionamiento del árbol adivinador\n", 31 | "\n", 32 | "## Contenido\n", 33 | "\n", 34 | "- [Introducción](#1)\n", 35 | "- [Arbol Adivinador](#2)\n", 36 | " - [Descripción del algoritmo ](#2-1)\n", 37 | " - [Implementación del algoritmo](#2-2)\n", 38 | "- [Clase Nodo](#3)\n", 39 | "- [Clase ArbolAdivinador](#4)\n", 40 | "- [Referencias](#5)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "0b6ce2a8", 46 | "metadata": {}, 47 | "source": [ 48 | "\n", 49 | "\n", 50 | "# Introducción \n", 51 | "\n", 52 | "Los árboles binarios no solo sirven para realizar búsquedas, de hecho los árboles se ocupan de manera muy frecuente en áreas como bases de datos, inteligencia artificial o sistemas operativos.\n", 53 | "\n", 54 | "En esta presentación vamos a ver el ejemplo de algoritmo empleado desde hace mucho tiempo para simular aprendizaje y con base en este aprendizaje (base de conocimiento) lograr predecir lo que piensa el usuario." 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "id": "ca9ccf1a", 60 | "metadata": {}, 61 | "source": [ 62 | "\n", 63 | "\n", 64 | "# Arbol Adivinador\n", 65 | "\n", 66 | "Este árbol (igual que los que veremos más adelante) esta conformado por nodos, la única diferencia es que en este árbol binario de búsqueda, cada nodo interno (nodo que no sea una hoja) contiene una pregunta y cada hoja del árbol es un animal.\n", 67 | "\n", 68 | "Haciendo uso de la estructura de datos conocida como árbol binario, vamos a tratar de adivinar el animal en el que esta pensando el usuario, en caso de adivinar el objetivo se logro, pero en caso contrario se le pide al usuario que indique en que animal estaba pensando y en como diferenciarlo del animal que le mostró el algoritmo.\n", 69 | "\n", 70 | "La idea detrás de este algoritmo es muy sencilla y muy parecida a la **búsqueda binaria**, cada pregunta que se le realiza al usuario descarta una gran cantidad de posibles animales, ya que la respuesta es booleana y eso acota el posible espacio de búsqueda.\n", 71 | "\n", 72 | "De igual manera que con los árboles binarios, cada nodo del árbol adivinador se ve de la siguiente forma.\n", 73 | "\n", 74 | "
\n", 75 | " \n", 76 | "
\n", 77 | "\n", 78 | "Aunque una sutil diferencia es que el dato contenido dentro de cada nodo intermedio será una pregunta, las hojas serán animales, las respuestas afirmativas a cada pregunta son los hijos izquierdos de todo nodo interno y las respuestas negativas son los hijos derechos de cada nodo intermedio." 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "id": "79a88043", 84 | "metadata": {}, 85 | "source": [ 86 | "\n", 87 | "\n", 88 | "## Descripción del algoritmo \n", 89 | "\n", 90 | "El árbol comienza con un solo nodo (la raíz) y esa es la base de conocimiento, así que el programa le pregunta al usuario si el animal que esta pensando es ese que contiene la raíz, digamos un pájaro.\n", 91 | "\n", 92 | "
\n", 93 | " \n", 94 | "
\n", 95 | "\n", 96 | "Si la respuesta es afirmativa, el algoritmo cumple con su objetivo ya que adivino el animal que estaba pensando el usuario. Sin embargo en caso de que la respuesta sea negativa, es decir que no se adivino el animal que estaba pensando el usuario, se le pide al usuario indicar el animal que estaba pensando y como diferenciarlo del animal que le mostró el programa.\n", 97 | "\n", 98 | "
\n", 99 | " \n", 100 | "
\n", 101 | "\n", 102 | "Se puede apreciar en esta imagen que las respuestas afirmativas son los hijos izquierdos de todo nodo y que las respuestas negativas son los hijos derechos de cada nodo. Conforme el programa es más usado, la base de conocimiento se incrementa cada vez más, hasta tener un árbol suficientemente entrenado como para poder adivinar cualquier animal, sin importar lo especifico que este sea.\n", 103 | "\n", 104 | "
\n", 105 | " \n", 106 | "
\n", 107 | "\n", 108 | "Es importante notar que el árbol adivinador será tan preciso como la información que se le proporcione." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "id": "18996aa6", 114 | "metadata": {}, 115 | "source": [ 116 | "\n", 117 | "\n", 118 | "## Implementación del algoritmo\n", 119 | "\n", 120 | "Ya que nos hemos familiarizado con el uso de la POO, vamos a hacer uso de clases para implementar nuestro algoritmo.\n", 121 | "\n", 122 | "Vamos a hacer uso de la clase Nodo y de la clase ArbolAdivinador, normalmente la clase Nodo se define como clase interna dentro de la clase ArbolBinario con la intención de ocultar algunas de sus características además de reafirmar el hecho de que no se pueden crear árboles si no se tienen nodos." 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "id": "c4a3f7fd", 128 | "metadata": {}, 129 | "source": [ 130 | "\n", 131 | "\n", 132 | "## Clase Nodo\n", 133 | "\n", 134 | "La clase `Nodo`, es una clase muy sencilla que solo consta del constructor, un par de atributos y un par de métodos." 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 1, 140 | "id": "41edc1bc", 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "Esto es una prueba\n", 148 | "Soy el hijo izquierdo\n", 149 | "Soy el hijo derecho\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "#Clase Nodo que hereda de la clase object\n", 155 | "class Nodo(object):\n", 156 | " # Constructor de Nodos\n", 157 | " def __init__(self, value):\n", 158 | " self.izq = None\n", 159 | " self.dato = value\n", 160 | " self.der = None\n", 161 | " self.padre = None\n", 162 | "\n", 163 | " # Sobrecarga del metodo string para imprimir el dato del nodo\n", 164 | " def __str__(self):\n", 165 | " if self.dato is None:\n", 166 | " pass\n", 167 | " else:\n", 168 | " return '{}'.format(self.dato)\n", 169 | "\n", 170 | "# Se crean los nodos necesarios\n", 171 | "raiz = Nodo(\"Esto es una prueba\")\n", 172 | "hijoizq = Nodo(\"Soy el hijo izquierdo\")\n", 173 | "hijoder = Nodo(\"Soy el hijo derecho\")\n", 174 | "\n", 175 | "# De manera manual se genera un ABB\n", 176 | "raiz.izq = hijoizq\n", 177 | "raiz.der = hijoder\n", 178 | "\n", 179 | "# pruebas de la clase Nodo\n", 180 | "print(raiz)\n", 181 | "print(raiz.izq)\n", 182 | "print(raiz.der)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "id": "c8fcf275", 188 | "metadata": {}, 189 | "source": [ 190 | "\n", 191 | "\n", 192 | "# Clase ArbolAdivinador\n", 193 | "\n", 194 | "La clase `ArbolAdivinador` se encarga organizar los nodo de tal forma que podamos construir un árbol binario que nos permita adivinar el animal en el que esta pensando el usuario." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "id": "001a82cf", 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "name": "stdin", 205 | "output_type": "stream", 206 | "text": [ 207 | "Estas pensando en un animal? si\n", 208 | "Es un pajaro? no\n", 209 | "¿Qué animal era? rana\n", 210 | "¿Qué diferencia a un pajaro de un rana? salta\n", 211 | "Estas pensando en un animal? si\n", 212 | "salta? si\n", 213 | "Es un pajaro? no\n", 214 | "¿Qué animal era? rana\n", 215 | "¿Qué diferencia a un pajaro de un rana? salta\n", 216 | "Estas pensando en un animal? si\n", 217 | "salta? si\n", 218 | "salta? si\n", 219 | "Es un pajaro? si\n" 220 | ] 221 | }, 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "¡Soy el más grande!\n", 227 | "███████████████████████████████─\n", 228 | "──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\n", 229 | "────────▀█▄█▄█▀──────▀█▄█▄█▀────\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "#from string import lower\n", 235 | "\n", 236 | "'''Clase basada en arboles binarios para identificar en que\n", 237 | "animal estas pensando'''\n", 238 | "class ArbolAdivinador(object):\n", 239 | " \n", 240 | " # Constructor de adivinadores\n", 241 | " def __init__(self):\n", 242 | " self.raiz = Nodo(\"pajaro\")\n", 243 | " \n", 244 | " #Funcion para determinar si se desea continuar con mas preguntas\n", 245 | " def si(self, preg):\n", 246 | " #se muestra una pregunta en consola y se pide la respuesta del usuario\n", 247 | " resp = str.lower(input(preg))\n", 248 | " return (resp[0] == 's')\n", 249 | " \n", 250 | " def adivina(self):\n", 251 | " ciclo = True\n", 252 | " while ciclo:\n", 253 | " #en caso de no querer continuar con mas preguntas\n", 254 | " if not self.si(\"Estas pensando en un animal? \"):\n", 255 | " print('Gracias por jugar :)')\n", 256 | " break\n", 257 | " #nodo temporal que sirve para recorrer el arbol\n", 258 | " temporal = self.raiz\n", 259 | " #se hacen preguntas al usuario hasta llegar a una hoja\n", 260 | " #siempre que se tenga hijo izquierdo podemos preguntar\n", 261 | " while temporal.izq != None:\n", 262 | " #si la respuesta es afirmativa avanzamos al hijo izquierdo\n", 263 | " if self.si(temporal.dato + \"? \"):\n", 264 | " temporal = temporal.izq\n", 265 | " #de otra forma avanza al hijo derecho\n", 266 | " else:\n", 267 | " temporal = temporal.der\n", 268 | " #se llega a un nodo hoja\n", 269 | " animal = temporal.dato\n", 270 | " #si se adivino termina, en caso contrario hay que obtener info.\n", 271 | " if self.si(\"Es un \" + animal + \"? \"):\n", 272 | " print(\"¡Soy el más grande!\")\n", 273 | " print(\"███████████████████████████████─\")\n", 274 | " print(\"──────▀█▄▀▄▀████▀──▀█▄▀▄▀████▀──\")\n", 275 | " print(\"────────▀█▄█▄█▀──────▀█▄█▄█▀────\")\n", 276 | " else:\n", 277 | " #nuevo animal\n", 278 | " nuevo = input(\"¿Qué animal era? \")\n", 279 | " #nueva pregunta para diferenciar a la hoja actual del nuevo animal\n", 280 | " info = input(\"¿Qué diferencia a un \" + animal + \" de un \" + nuevo + \"? \")\n", 281 | " #se actualiza el nodo con la nueva pregunta\n", 282 | " temporal.dato = info\n", 283 | " #se agrega como izquierdo al animal que estaba en la hoja\n", 284 | " temporal.izq = Nodo(animal)\n", 285 | " #y como derecho el nuevo animal\n", 286 | " temporal.der = Nodo(nuevo)\n", 287 | " \n", 288 | "def main():\n", 289 | " adivino = ArbolAdivinador()\n", 290 | " adivino.adivina()\n", 291 | "\n", 292 | "main()" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "id": "6346b89a", 298 | "metadata": {}, 299 | "source": [ 300 | "\n", 301 | "\n", 302 | "# Referencias\n", 303 | "\n", 304 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 305 | "2. Referencias Libro Web: Introduccion a Python.\n", 306 | "3. Referencias Daniel T. Joyce: Object-Oriented Data Structures.\n", 307 | "4. Referencias John C. Mitchell: Concepts in programing Languages." 308 | ] 309 | } 310 | ], 311 | "metadata": { 312 | "kernelspec": { 313 | "display_name": "Python 3 (ipykernel)", 314 | "language": "python", 315 | "name": "python3" 316 | }, 317 | "language_info": { 318 | "codemirror_mode": { 319 | "name": "ipython", 320 | "version": 3 321 | }, 322 | "file_extension": ".py", 323 | "mimetype": "text/x-python", 324 | "name": "python", 325 | "nbconvert_exporter": "python", 326 | "pygments_lexer": "ipython3", 327 | "version": "3.11.6" 328 | } 329 | }, 330 | "nbformat": 4, 331 | "nbformat_minor": 5 332 | } 333 | -------------------------------------------------------------------------------- /04_Simulacion/Utils/gutils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Aug 6 17:35:09 2020 5 | @author: luiggi 6 | """ 7 | import numpy as np 8 | #from mpl_toolkits.mplot3d import Axes3D 9 | import matplotlib.pyplot as plt 10 | plt.style.use('fivethirtyeight') 11 | #plt.style.use('seaborn') 12 | 13 | 14 | class planoCartesiano(): 15 | 16 | def __init__(self, rows = 1, cols = 1, par = None, par_fig={'figsize':(10,5)}, title=''): 17 | """ 18 | Crea e inicializa una figura de matplotlib. 19 | Parameters 20 | ---------- 21 | rows : int, opcional 22 | Número de renglones del arreglo de subplots. The default is 1. 23 | cols : int, opcional 24 | Número de columnas del arreglo de subplots. The default is 1. 25 | par : list of dicts, opcional 26 | Lista de diccionarios; cada diccionario define los parámetros que 27 | se usarán decorar los `Axes` de cada subplot. The default is None. 28 | par_fig : dict, opcional 29 | Diccionario con los parámetros para decorar la figura. 30 | The default is {}. 31 | """ 32 | self.__fig = plt.figure(**par_fig) 33 | self.__fig.suptitle(title, fontweight='light', fontsize='12', color='blue') 34 | self.__nfigs = rows * cols 35 | 36 | import matplotlib 37 | self.__mpl_ver = matplotlib.__version__.split(sep='.') 38 | 39 | if par != None: 40 | Nfill = self.__nfigs - len(par) 41 | else: 42 | Nfill = self.__nfigs 43 | par = [ ] 44 | 45 | [par.append({}) for n in range(Nfill)] 46 | 47 | self.__ax = [plt.subplot(rows, cols, n, **par[n-1]) for n in range(1,self.__nfigs + 1)] 48 | plt.tight_layout() 49 | 50 | 51 | def plot(self, n = 1, x = None, y = None, par=None): 52 | assert (n >= 1 and n <= self.__nfigs), \ 53 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 54 | 55 | if par != None: 56 | out = self.__ax[n-1].plot(x, y, **par) 57 | else: 58 | out = self.__ax[n-1].plot(x, y) 59 | 60 | return out 61 | 62 | def scatter(self, n = 1, x = None, y = None, par=None): 63 | 64 | assert (n >= 1 and n <= self.__nfigs), \ 65 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 66 | 67 | if par != None: 68 | out = self.__ax[n-1].scatter(x, y, **par) 69 | else: 70 | out = self.__ax[n-1].scatter(x, y) 71 | return out 72 | 73 | def bar(self, n = 1, x = None, y = None, par=None): 74 | assert (n >= 1 and n <= self.__nfigs), \ 75 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 76 | 77 | if par != None: 78 | out = self.__ax[n-1].bar(x, y, **par) 79 | else: 80 | out = self.__ax[n-1].bar(x, y) 81 | 82 | return out 83 | 84 | def format_func(value, tick_number): 85 | # find number of multiples of pi/2 86 | N = int(np.round(2 * value / np.pi)) 87 | if N == 0: 88 | return "0" 89 | elif N == 1: 90 | return r"$\pi/2$" 91 | elif N == 2: 92 | return r"$\pi$" 93 | elif N % 2 > 0: 94 | return r"${0}\pi/2$".format(N) 95 | else: 96 | return r"${0}\pi$".format(N // 2) 97 | 98 | def ticks(self, n = 1, xticks = [], yticks = [], trig = False): 99 | assert (n >= 1 and n <= self.__nfigs), \ 100 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 101 | 102 | if trig: 103 | self.__ax[n-1].xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) 104 | self.__ax[n-1].xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) 105 | self.__ax[n-1].xaxis.set_major_formatter(plt.FuncFormatter(planoCartesiano.format_func)) 106 | else: 107 | if len(xticks) != 0: 108 | self.__ax[n-1].set_xticks(xticks) 109 | if len(yticks) != 0: 110 | self.__ax[n-1].set_yticks(yticks) 111 | 112 | def label_ticks(self, n = 1, xlabel = [], ylabel = []): 113 | assert (n >= 1 and n <= self.__nfigs), \ 114 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 115 | 116 | if len(xlabel): 117 | self.__ax[n-1].set_xticklabels(xlabel) 118 | if len(ylabel): 119 | self.__ax[n-1].set_yticklabels(ylabel) 120 | 121 | def limits(self, n = 1, x = (), y = ()): 122 | assert (n >= 1 and n <= self.__nfigs), \ 123 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 124 | 125 | if len(x): 126 | offset = np.fabs(x[1] - x[0]) * 0.2 127 | self.__ax[n-1].set_xlim((x[0]-offset,x[1]+offset)) 128 | if len(y): 129 | offset = np.fabs(y[1] - y[0]) * 0.2 130 | self.__ax[n-1].set_ylim((y[0]-offset,y[1]+offset)) 131 | 132 | def colorbar(self, n=1, m=None, par=None): 133 | assert (n >= 1 and n <= self.__nfigs), \ 134 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 135 | 136 | if par != None: 137 | self.__fig.colorbar(m, ax = self.__ax[n-1], **par) 138 | else: 139 | self.__fig.colorbar(m, ax = self.__ax[n-1]) 140 | 141 | def legend(self, par=None): 142 | """ 143 | Muestra las leyendas de todos los subplots, si están definidos. 144 | Parameters 145 | ---------- 146 | par : dict, opcional 147 | Diccionario con los parámetros para decorar las leyendas. 148 | The default is None. 149 | Returns 150 | ------- 151 | None. 152 | 153 | See Also 154 | -------- 155 | matplotlib.axes.Axes.legend(). 156 | """ 157 | if par != None: 158 | [self.__ax[n].legend(**par) for n in range(0,self.__nfigs)] 159 | else: 160 | [self.__ax[n].legend() for n in range(0,self.__nfigs)] 161 | 162 | 163 | def show(self): 164 | """ 165 | Muestra las gráficas de cada subplot. 166 | 167 | See Also 168 | -------- 169 | matplotlib.pyplot.show(). 170 | 171 | """ 172 | plt.show() 173 | 174 | def annotate(self, n = 1, par=None): 175 | """ 176 | Parameters 177 | ---------- 178 | n : TYPE, optional 179 | DESCRIPTION. The default is 1. 180 | par : TYPE, optional 181 | DESCRIPTION. The default is None. 182 | Returns 183 | ------- 184 | TYPE 185 | DESCRIPTION. 186 | """ 187 | assert (n >= 1 and n <= self.__nfigs), \ 188 | "Plotter.plot(%d) out of bounds. Valid bounds : [1,%d]" % (n,self.__nfigs) 189 | 190 | # Debido a incompatibilidades de Matplotlib 3.2 191 | if int(self.__mpl_ver[1]) < 3: 192 | par['s'] = par['text'] 193 | del par['text'] 194 | 195 | return self.__ax[n-1].annotate(**par) 196 | 197 | def RMS(ua, u): 198 | """ 199 | Calcula el error cuadrático medio entre u y ua. 200 | 201 | Parameters 202 | ---------- 203 | ua: np.array 204 | Arreglo de valores aproximados. 205 | 206 | u: np.array 207 | Arreglo de valores exactos. 208 | 209 | Returns 210 | ------- 211 | float 212 | El error cuadrático medio entre u y ua. 213 | """ 214 | return np.sqrt(np.sum((ua - u)**2) / len(ua)) 215 | 216 | def RMS1(ua, u): 217 | """ 218 | Calcula el error cuadrático medio entre u y ua. 219 | 220 | Parameters 221 | ---------- 222 | ua: np.array 223 | Arreglo de valores aproximados. 224 | 225 | u: np.array 226 | Arreglo de valores exactos. 227 | 228 | Returns 229 | ------- 230 | float 231 | El error cuadrático medio entre u y ua. 232 | """ 233 | return np.sqrt(np.sum((ua - u)**2) / len(ua)) 234 | 235 | def biseccion(f,Tol,N,a,b): 236 | """ 237 | implementa el metodo de la biseccion 238 | para encontrar la raiz de una funcion. 239 | 240 | Parameters 241 | ---------- 242 | f: function 243 | funcion para calcular raiz. 244 | 245 | Tol: float 246 | Tolerancia. 247 | 248 | N: integer 249 | Numero de iteraciones maximo. 250 | 251 | a: float 252 | limite izquierdo. 253 | 254 | b: float 255 | limite derecho. 256 | 257 | Returns 258 | ------- 259 | float 260 | La raiz de la funcion f. 261 | list 262 | Valores en la sucesion del algoritmo. 263 | """ 264 | sucesion=[] 265 | fa=f(a) 266 | fb=f(b) 267 | #no hay un cambio de signo (teorema del valor medio) 268 | #no existe raiz en el intervalo [a,b] 269 | if fa*fb>0: 270 | print ("no hay raiz en [a,b]") 271 | return 272 | #contador de iteraciones 273 | n=1 274 | x0=0.0 275 | #mientras no se exceda el numero de iteraciones 276 | while n<=N: 277 | #se busca la raiz en el punto medio 278 | x1=(a+b)/2.0 279 | fx=f(x1) 280 | sucesion.append(x1) 281 | #en caso de que la iteracion siguiente y la diferencia 282 | #entre la iteracion anterior no excedan Tol, entonces 283 | #la iteracion actual se aproxima a la solucion buscada 284 | if abs(f(x1)) <= Tol and abs(x1-x0) <= Tol: 285 | return x1, sucesion 286 | #en caso de no cumplir el criterio de tolerancia 287 | #se actualiza el rango de busqueda 288 | if (fa*fx <0.0): 289 | b=x1 290 | if (fx*fa >0.0): 291 | a=x1 292 | x0=x1 293 | #se incrementa el contador de iteraciones 294 | n=n+1 295 | 296 | '''Esta funcion implementa el metodo de la falsa posicion 297 | para encontrar la raiz de una funcion. 298 | f: funcion de la cual se busca la raiz 299 | Tol: tolerancia del error numerico 300 | N: numero maximo de iteraciones 301 | a: limite inferior del rango inicial 302 | b: limite superior del rango inicial 303 | ''' 304 | def falsaPosicion(f,Tol,N,a,b): 305 | fa=f(a) 306 | fb=f(b) 307 | #en caso de que no haya cambio de signo, no existe raiz 308 | if fa*fb>0: 309 | print("No existe raiz en [a,b]") 310 | return 311 | #contador de iteraciones 312 | n=1 313 | #se toma una raiz inicial arbitraria 314 | x0=0.0 315 | sucesion = [] 316 | #mientras no se exceda el numero de iteraciones 317 | while n<=N: 318 | #se actualiza el rango de busqueda 319 | fa,fb =f(a),f(b) 320 | #se calcula la nueva iteracion 321 | x1= (a*fb-b*fa)/(fb-fa) 322 | fx=f(x1) 323 | sucesion.append(x1) 324 | #en caso de que la diferencia entre la iteracion actual 325 | #y la iteracion anterior no excedan Tol, y que la raiz 326 | #evaluada no exceda la tolerancia, se devuelve la raiz 327 | if abs(f(x1)) <= Tol and abs(x1-x0) <= Tol: 328 | return x1, sucesion 329 | #en caso de no cumplir el criterio de tolerancia 330 | #se actualiza el rango de busqueda 331 | if (fa*fx <0.0): 332 | b=x1 333 | if (fx*fa >0.0): 334 | a=x1 335 | #se actualiza x0 336 | x0=x1 337 | #se incrementa el contador de iteraciones 338 | n=n+1 339 | 340 | '''Esta funcion implementa el metodo de la falsa posicion 341 | para encontrar la raiz de una funcion. 342 | f: funcion de la cual se busca la raiz 343 | df: derivada de f 344 | Tol: tolerancia del error numerico 345 | N: numero maximo de iteraciones 346 | x0: aproximacion inicial 347 | ''' 348 | def newton(f,Tol,N,x0): 349 | #contador de iteraciones 350 | n=1 351 | #mientras no se haya superado el limite de iteraciones 352 | while n<=N: 353 | #se evalua la funcion y su derivada 354 | fx=f(x0) 355 | dfx=derivada(f,x0, Tol) 356 | #se calcula la siguiente aproximacion 357 | xn = x0-(fx/float(dfx)) 358 | #en caso de cumplir criterios se devuelve la raiz 359 | if abs(f(xn)) <= Tol and abs(xn-x0) <= Tol: 360 | return xn 361 | #actualizamos las aproximaciones 362 | x0 = xn 363 | #se incrementa el contador de iteraciones 364 | n=n+1 365 | raise Exception("Se alcanzo el maximo numero de iteraciones y no se encontro raiz") 366 | 367 | def derivada(f, x, tol): 368 | return (f(x+tol)-f(x))/(tol) 369 | 370 | # algoritmo para sustitucion hacia delante 371 | # n es el tamano de la dimension del problema 372 | # matriz L, vector b ya estan dados como parametros 373 | # guardar los resultados en el vector y 374 | # Ly=b 375 | def sustDelante(L, b): 376 | n=len(L) 377 | y=np.empty_like(b) 378 | for i in range(0,n): 379 | y[i] = b[i] 380 | for j in range(0,i): 381 | y[i] -= L[i][j]*y[j] 382 | y[i] /= L[i][i] 383 | return y 384 | 385 | # algoritmo para sustitucion hacia atras 386 | # n es el tamano de la dimension del problema 387 | # matriz U, vector y ya estan dados como parametros 388 | # guardar los resultados en el vector x 389 | # Ux=y 390 | def sustAtras(U, y): 391 | n=len(U) 392 | x=np.empty_like(y) 393 | x[n-1] = y[n-1]/U[n-1][n-1] 394 | for i in range(n-2,-1,-1): 395 | x[i] = y[i] 396 | for j in range(i+1,n): 397 | x[i] -= U[i][j]*x[j] 398 | x[i] /= U[i][i] 399 | return x 400 | 401 | # algoritmo para la factorizacion de Cholesky 402 | # L y L transpuesta se alamacenan en la misma matriz 403 | def cholesky(mat): 404 | L = np.zeros_like(mat) 405 | #Creamos un for que vaya de 0 al numero de renglones de la matriz. 406 | for k in range(len(mat)): 407 | #Creamos un for para ir sumando. 408 | for i in range(k): 409 | suma = mat[k,i] 410 | for j in range(i): 411 | suma -= (L[i,j]* L[k,j]) 412 | L[k,i] = (suma)/ L[i,i] 413 | L[i,k] = L[k,i] 414 | suma = mat[k,k] 415 | for j in range(k): 416 | suma -= (L[k,j]*L[k,j]) 417 | L[k,k] = np.sqrt(suma) 418 | return L 419 | 420 | #----------------------- TEST OF THE MODULE ---------------------------------- 421 | if __name__ == '__main__': 422 | #test prueba 423 | print("prueba") 424 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/03_RadixBucket/.ipynb_checkpoints/01_RadixBucket-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "JAsbRnI2Mz94" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

RadixSort y BucketSort (análisis)

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León.
\n", 24 | "
Ayudante: Diana Laura Rojas Cristino
\n", 25 | "
Ayudante: Rodrigo Alejandro Sánchez Morales
\n", 26 | "
Manejo de Datos
\n", 27 | "
" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "h4IewVdLVj8s" 34 | }, 35 | "source": [ 36 | "# Introducción\n", 37 | "\n", 38 | "Este par de algoritmos de ordenamiento (RadixSort y BucketSort) los podemos considerar algoritmos \"exóticos\", ya que a diferencia de los algoritmos vistos previamente, estos no se basan en comparaciones entre los elementos a ordenar.\n", 39 | "\n", 40 | "Por otro lado estos algoritmos requiere de conocimientos a priori de los datos a ordenar, por ejemplo la longitud en terminos de digitos decimales de los elementos a ordenar." 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": { 46 | "id": "Z2HsvTi77D9Y" 47 | }, 48 | "source": [ 49 | "# *RadixSort*\n", 50 | "\n", 51 | "Este algoritmo ordena los elementos de manera similar a como funcionan los tableros que anuncian las llegadas de los aviones en un aeropuerto. Imaginemos que los valores a ordenar los podemos colocar en renglones donde cada renglón contiene casillas para cada dígito del elemento a ordenar, algo así.\n", 52 | "\n", 53 | "$$\n", 54 | "\\begin{array}{ccccc}\n", 55 | "\\left[d_{n}\\right] & \\left[\\ldots\\right] & \\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[d_{0}\\right]\\end{array}\n", 56 | "$$\n", 57 | "\n", 58 | "La idea detrás de este algoritmo es ordenar cada digito de derecha a izquierda por cada elemento a ordenar, modificando la posición del elemento a ordenar en caso de que el dígito a ordenar haya sufrido alguna modificación respecto a la posición en la colección.\n", 59 | "\n", 60 | "
\n", 61 | "\n", 62 | "
" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": { 68 | "id": "-Dt5F9Xacou3" 69 | }, 70 | "source": [ 71 | "## Descripción\n", 72 | "\n", 73 | "Para que el algoritmo *RadixSort* funcione de manera correcta hay que **conocer la longitud (en términos) de dígitos** del elemento más extenso a ordenar, una vez que se conoce esta longitud se completan con ceros (a la izquierda del dígito $d_{n}$ en caso de ser necesario). Una vez que todos los elementos a ordenar tienen la misma longitud comienza el algoritmo con los siguientes pasos:\n", 74 | "\n", 75 | "\n", 76 | "1. Comenzamos a ordenar la columna correspondiente al $d_{0}$ (que se le conoce como el dígito menos significativo), se realizan las respectivas modificaciones en las posiciones de los renglones en caso de ser necesario y se continua con la columna $d_{1}$.\n", 77 | "2. Se ordena la columna $d_{1}$, de manera similar a como se hizo con la columna anterior y se procede a la siguiente.\n", 78 | "3. Continuamos ordenando todas las columnas (con sus respectivas modificaciones sobre los renglones), hasta llegar a la columna $d_{n}$ (el dígito más significativo).\n", 79 | "4. Al ordenar el dígito más significativo de cada renglón termina el algoritmo.\n", 80 | "\n", 81 | "\n", 82 | "\n" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": { 88 | "id": "qwuSS-rte3Ds" 89 | }, 90 | "source": [ 91 | "## Ejemplo\n", 92 | "\n", 93 | "Supongamos que se tiene el siguiente conjunto de datos a ordenar que podemos organizarlos de la siguiente manera.\n", 94 | "\n", 95 | "$$\n", 96 | "\\begin{array}{ccc}\n", 97 | "\\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[d_{0}\\right]\\\\\n", 98 | "\\left[1\\right] & \\left[0\\right] & \\left[5\\right]\\\\\n", 99 | "\\left[0\\right] & \\left[2\\right] & \\left[5\\right]\\\\\n", 100 | "\\left[3\\right] & \\left[0\\right] & \\left[1\\right]\n", 101 | "\\end{array}\n", 102 | "$$\n", 103 | "\n", 104 | "Ahora la idea es comenzar a ordenar la primer columna (la columna correspondiente al digito $d_{0}$) se ordena esa columna, considerando que el $d_{0}$ pertenece a todo un renglon y por lo tanto si el $d_{0}$ de algún renglón cambia su posición, también lo debe hacer todo el renglón. Después de ordenar el $d_{0}$, esta colección de datos se ve de la siguiente forma.\n", 105 | "\n", 106 | "$$\n", 107 | "\\begin{array}{ccc}\n", 108 | "\\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 109 | "\\left[3\\right] & \\left[0\\right] & \\left[\\color{green}1\\right]\\\\\n", 110 | "\\left[1\\right] & \\left[0\\right] & \\left[\\color{green}5\\right]\\\\\n", 111 | "\\left[0\\right] & \\left[2\\right] & \\left[\\color{green}5\\right]\n", 112 | "\\end{array}\n", 113 | "$$\n", 114 | "\n", 115 | "Se procede a ordenar la columna correspondiente al $d_{1}$ y podemos notar que no hay cambios en los renglones, ya que la columna $d_{1}$ ya se encuentra ordenada.\n", 116 | "\n", 117 | "$$\n", 118 | "\\begin{array}{ccc}\n", 119 | "\\left[d_{2}\\right] & \\left[\\color{green}{d_{1}}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 120 | "\\left[3\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}1\\right]\\\\\n", 121 | "\\left[1\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}5\\right]\\\\\n", 122 | "\\left[0\\right] & \\left[\\color{green}2\\right] & \\left[\\color{green}5\\right]\n", 123 | "\\end{array}\n", 124 | "$$\n", 125 | "\n", 126 | "Por último, se ordena la columna $d_{2}$ y la colección queda de la siguiente forma.\n", 127 | "\n", 128 | "$$\n", 129 | "\\begin{array}{ccc}\n", 130 | "\\left[\\color{green}{d_{2}}\\right] & \\left[\\color{green}{d_{1}}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 131 | "\\left[\\color{green}0\\right] & \\left[\\color{green}2\\right] & \\left[\\color{green}5\\right]\\\\\n", 132 | "\\left[\\color{green}1\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}5\\right]\\\\\n", 133 | "\\left[\\color{green}3\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}1\\right]\n", 134 | "\\end{array}\n", 135 | "$$\n", 136 | "\n", 137 | "Y la colección queda ordenada.\n" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "id": "mlm6KfnURLCA" 144 | }, 145 | "source": [ 146 | "## Análisis y Orden de Complejidad\n", 147 | "\n", 148 | "Dado que este algoritmo no se basa en comparaciones podemos pensar que el ordenar cada columna ($d_{i})$ toma tiene un costo lineal, es decir $O(n)$ ya que unicamente estamos organizando cada elemento respecto al dígito, tarea muy **similar a cuando organizamos elementos dentro de contenedores o cubetas**.\n", 149 | "\n", 150 | "Ahora supongamos que el elemento de mayor longitud dentro de la colección esta conformado por $k-digitos$, entonces se tendrían que ordenar $k$ columnas, por lo tanto el algoritmo *RadixSort* pertenece al orden de complejidad $O(kn)$.\n", 151 | "\n", 152 | "Así que podemos pensar que el peor caso para este algoritmo es cuando $k$ es demasiado grande (y sobretodo si son pocos los elementos que poseén la misma longitud). Pensemos que $k\\approx n$, entonces el orden al que pertenecería este algoritmo sería $O(nn)=O(n²)$.\n", 153 | "\n" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": { 159 | "id": "qjDkvoF89_3n" 160 | }, 161 | "source": [ 162 | "# Ordenamiento por cubetas (*BucketSort*)\n", 163 | "\n", 164 | "Este algoritmo (no comparativo) consiste en generar contenedores (cubetas) que cumplan con determinadas caracteristicas, enviar a los elementos que cumplan con estas a su respectivo contenedor y ordenar cada contenedor de manera individual." 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": { 170 | "id": "gsxkxdZvznIp" 171 | }, 172 | "source": [ 173 | "## Descripción\n", 174 | "\n", 175 | "De manera similar a *RadixSort*, para el ótimo funcionamiento de este algoritmo se requieren ciertas caracteristicas y en este caso es que los elementos a ordenar se ecuentren distribuidos de manera uniforme sobre el espacio a ordenar. A continuación una descripción de como funciona este algoritmos:\n", 176 | "\n", 177 | "1. Dado que se conoce a priori el espacio donde se distribuyen los elementos a ordenar, se genéran contenedores (cubetas) con ciertas caracteristicas, por ejemplo un rango de valores, para almacenar a los elementos que cumplan con estas caracteristicas.\n", 178 | "2. Se recorren todos los elementos a ordenar y se va colocando uno a uno en el contenedor correspondiente.\n", 179 | "2. Se ordena cada contenedor de manera individual con este mismo algoritmo (o con alguno visto previamente.\n", 180 | "3. Se extraen los elementos de cada contenedor comenzando con el contenedor que almacene a los elementos de menor valor y finalizando con el contenedor que almacena a los elementos de mayor valor.\n", 181 | "4. El algoritmo termina cuando los elementos del último contener han sido extraidos.\n", 182 | "\n", 183 | "
\n", 184 | "\n", 185 | "
" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": { 191 | "id": "ou8sIl3O27CY" 192 | }, 193 | "source": [ 194 | "## Ejemplo\n", 195 | "\n", 196 | "En la imagen superior se muestra un ejemplo en el cuál se busca ordenar los datos.\n", 197 | "\n", 198 | "$$\n", 199 | "\\left[11\\right]\\left[9\\right]\\left[21\\right]\\left[8\\right]\\left[17\\right]\\left[19\\right]\\left[13\\right]\\left[1\\right]\\left[24\\right]\\left[12\\right]$$\n", 200 | "\n", 201 | "Dado que se conoce a priori el rango en el cuál se encuentran distribuidos los datos, podemos generar 5 contenedores que abarcan los rangos.\n", 202 | "\n", 203 | "$$\n", 204 | "\\left[0,5\\right),\\left[5,10\\right),\\left[10,15\\right),\\left[15,20\\right),\\left[20,26\\right)\n", 205 | "$$\n", 206 | "\n", 207 | "Y al organizar los datos en los contenedres se verían así:\n", 208 | "\n", 209 | "$$\n", 210 | "\\begin{array}{cc}\n", 211 | "\\left[0,5\\right): & 1\\\\\n", 212 | "\\left[5,10\\right): & 9,8\\\\\n", 213 | "\\left[10,15\\right): & 11,13,12\\\\\n", 214 | "\\left[15,20\\right): & 17,19\\\\\n", 215 | "\\left[2,26\\right): & 21,24\n", 216 | "\\end{array}\n", 217 | "$$\n", 218 | "\n", 219 | "Después de ordenar cada contenedor individualmente, los contenedores se ven así:\n", 220 | "\n", 221 | "$$\n", 222 | "\\begin{array}{cc}\n", 223 | "\\left[0,5\\right): & 1\\\\\n", 224 | "\\left[5,10\\right): & 8,9\\\\\n", 225 | "\\left[10,15\\right): & 11,12,13\\\\\n", 226 | "\\left[15,20\\right): & 17,19\\\\\n", 227 | "\\left[2,26\\right): & 21,24\n", 228 | "\\end{array}\n", 229 | "$$\n", 230 | "\n", 231 | "Y al extraer todos los datos de cada contenedor, de manera ordenada los datos finalmente quedan ordenados.\n", 232 | "\n", 233 | "$$\n", 234 | "\\left[1\\right]\\left[8\\right]\\left[9\\right]\\left[11\\right]\\left[12\\right]\\left[13\\right]\\left[17\\right]\\left[19\\right]\\left[21\\right]\\left[24\\right]$$\n", 235 | "\n", 236 | "\n", 237 | "\n", 238 | "\n" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": { 244 | "id": "KjHjPb_U4TbJ" 245 | }, 246 | "source": [ 247 | "## Análisis y Orden de complejidad\n", 248 | "\n", 249 | "Para llevar a cabo el análisis de la complejidad hay que preguntarse ¿qué tipo de algoritmo de ordenamiento se usará para ordenar individualmente cada cubeta y eso ayuda a determinar el orden de complejidad al que pertenece este algoritmo.\n", 250 | "\n", 251 | "Algunos autores consideran a *RadixSort* un caso particular de *BucketSort*.\n", 252 | "\n", 253 | "Se deja como ejercicio determinar el orden de complejidad al que pertenece el algoritmo *BucketSort*." 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": { 259 | "id": "dTMtQcsc4QA8" 260 | }, 261 | "source": [ 262 | "# Ordenando Objetos\n", 263 | "\n", 264 | "Es importante notar que este y todos los algoritmos de ordenamiento vistos funcionan con cualquier objeto que sea ordenable (realizando las respectivas adecuaciones), es decir, con todo clase de objetos en la que podamos establecer un orden, por ejemplo: $\\mathbb{N},\\,\\mathbb{Z},\\,\\mathbb{Q},\\,\\mathbb{R}$, incluso con $\\mathbb{C}$ o elementos más complejos como **vectores, matrices, palabras o todo aquello en lo que podamos establecer un orden**." 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": { 270 | "id": "pc6ND99T6HDA" 271 | }, 272 | "source": [ 273 | "## Algoritmos de ordenamiento en paralelo\n", 274 | "\n", 275 | "Todos los algoritmos vistos funcionan de manera **secuencial**, es decir se realiza un paso (operacion) a la vez, sin embargo esta estrategia (secuencial) es prácticamente obsoleta.\n", 276 | "\n", 277 | "¿Si tuvieramos más de una unidad de procesamiento (CPU), podríamos **implementar algunos de estos algoritmos en paralelo**?." 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": { 283 | "id": "YHiyGAPySr_f" 284 | }, 285 | "source": [ 286 | "#Referencias\n", 287 | "\n", 288 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 289 | "2. Libro Web: [Introduccion a Python](https://uniwebsidad.com/libros/algoritmos-python/capitulo-20/cuanto-cuesta-el-merge-sort?from=librosweb).\n", 290 | "3. Daniel T. Joyce: Object-Oriented Data Structures.\n", 291 | "4. John C. Mitchell: Concepts in programing Languages." 292 | ] 293 | } 294 | ], 295 | "metadata": { 296 | "colab": { 297 | "include_colab_link": true, 298 | "name": "03_RadixBucket.ipynb", 299 | "provenance": [], 300 | "toc_visible": true 301 | }, 302 | "kernelspec": { 303 | "display_name": "Python 3 (ipykernel)", 304 | "language": "python", 305 | "name": "python3" 306 | }, 307 | "language_info": { 308 | "codemirror_mode": { 309 | "name": "ipython", 310 | "version": 3 311 | }, 312 | "file_extension": ".py", 313 | "mimetype": "text/x-python", 314 | "name": "python", 315 | "nbconvert_exporter": "python", 316 | "pygments_lexer": "ipython3", 317 | "version": "3.11.6" 318 | } 319 | }, 320 | "nbformat": 4, 321 | "nbformat_minor": 4 322 | } 323 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/03_RadixBucket/01_RadixBucket.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "JAsbRnI2Mz94" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

RadixSort y BucketSort (análisis)

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León.
\n", 24 | "
Ayudante: Ercik Eduardo Aguilar Hernández
\n", 25 | "
Manejo de Datos
\n", 26 | "
" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "id": "h4IewVdLVj8s" 33 | }, 34 | "source": [ 35 | "# Introducción\n", 36 | "\n", 37 | "Este par de algoritmos de ordenamiento (RadixSort y BucketSort) los podemos considerar algoritmos \"exóticos\", ya que a diferencia de los algoritmos vistos previamente, estos no se basan en comparaciones entre los elementos a ordenar.\n", 38 | "\n", 39 | "Por otro lado estos algoritmos requieren de conocimientos a priori de los datos a ordenar, por ejemplo la longitud en terminos de dígitos decimales de los elementos a ordenar." 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "Z2HsvTi77D9Y" 46 | }, 47 | "source": [ 48 | "# *RadixSort*\n", 49 | "\n", 50 | "Este algoritmo ordena los elementos de manera similar a como funcionan los tableros que anuncian las llegadas de los aviones en un aeropuerto. Imaginemos que los valores a ordenar los podemos colocar en renglones, donde cada renglón contiene casillas para cada dígito del elemento a ordenar, algo así.\n", 51 | "\n", 52 | "$$\n", 53 | "\\begin{array}{ccccc}\n", 54 | "\\left[d_{n}\\right] & \\left[\\ldots\\right] & \\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[d_{0}\\right]\\end{array}\n", 55 | "$$\n", 56 | "\n", 57 | "La idea detrás de este algoritmo es ordenar cada dígito de derecha a izquierda por cada elemento a ordenar, modificando la posición del elemento a ordenar en caso de que el dígito a ordenar haya sufrido alguna modificación respecto a la posición en la colección.\n", 58 | "\n", 59 | "
\n", 60 | "\n", 61 | "
" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "id": "-Dt5F9Xacou3" 68 | }, 69 | "source": [ 70 | "## Descripción\n", 71 | "\n", 72 | "Para que el algoritmo *RadixSort* funcione de manera correcta hay que **conocer la longitud (en términos) de dígitos** del elemento más extenso a ordenar, una vez que se conoce esta longitud se completan con ceros (a la izquierda del dígito $d_{n}$ en caso de ser necesario). Una vez que todos los elementos a ordenar tienen la misma longitud comienza el algoritmo con los siguientes pasos:\n", 73 | "\n", 74 | "\n", 75 | "1. Comenzamos a ordenar la columna correspondiente al $d_{0}$ (que se le conoce como el dígito menos significativo), se realizan las respectivas modificaciones en las posiciones de los renglones en caso de ser necesario y se continua con la columna $d_{1}$.\n", 76 | "2. Se ordena la columna $d_{1}$, de manera similar a como se hizo con la columna anterior y se procede a la siguiente.\n", 77 | "3. Continuamos ordenando todas las columnas (con sus respectivas modificaciones sobre los renglones), hasta llegar a la columna $d_{n}$ (el dígito más significativo).\n", 78 | "4. Al ordenar el dígito más significativo de cada renglón termina el algoritmo.\n", 79 | "\n", 80 | "\n", 81 | "\n" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": { 87 | "id": "qwuSS-rte3Ds" 88 | }, 89 | "source": [ 90 | "## Ejemplo\n", 91 | "\n", 92 | "Supongamos que se tiene el siguiente conjunto de datos a ordenar que podemos organizarlos de la siguiente manera.\n", 93 | "\n", 94 | "$$\n", 95 | "\\begin{array}{ccc}\n", 96 | "\\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[d_{0}\\right]\\\\\n", 97 | "\\left[1\\right] & \\left[0\\right] & \\left[5\\right]\\\\\n", 98 | "\\left[0\\right] & \\left[2\\right] & \\left[5\\right]\\\\\n", 99 | "\\left[3\\right] & \\left[0\\right] & \\left[1\\right]\n", 100 | "\\end{array}\n", 101 | "$$\n", 102 | "\n", 103 | "Ahora la idea es comenzar a ordenar la primer columna (la columna correspondiente al digito $d_{0}$) se ordena esa columna, considerando que el $d_{0}$ pertenece a todo un renglon y por lo tanto si el $d_{0}$ de algún renglón cambia su posición, también lo debe hacer todo el renglón. Después de ordenar el $d_{0}$, esta colección de datos se ve de la siguiente forma.\n", 104 | "\n", 105 | "$$\n", 106 | "\\begin{array}{ccc}\n", 107 | "\\left[d_{2}\\right] & \\left[d_{1}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 108 | "\\left[3\\right] & \\left[0\\right] & \\left[\\color{green}1\\right]\\\\\n", 109 | "\\left[1\\right] & \\left[0\\right] & \\left[\\color{green}5\\right]\\\\\n", 110 | "\\left[0\\right] & \\left[2\\right] & \\left[\\color{green}5\\right]\n", 111 | "\\end{array}\n", 112 | "$$\n", 113 | "\n", 114 | "Se procede a ordenar la columna correspondiente al $d_{1}$ y podemos notar que no hay cambios en los renglones, ya que la columna $d_{1}$ ya se encuentra ordenada.\n", 115 | "\n", 116 | "$$\n", 117 | "\\begin{array}{ccc}\n", 118 | "\\left[d_{2}\\right] & \\left[\\color{green}{d_{1}}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 119 | "\\left[3\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}1\\right]\\\\\n", 120 | "\\left[1\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}5\\right]\\\\\n", 121 | "\\left[0\\right] & \\left[\\color{green}2\\right] & \\left[\\color{green}5\\right]\n", 122 | "\\end{array}\n", 123 | "$$\n", 124 | "\n", 125 | "Por último, se ordena la columna $d_{2}$ y la colección queda de la siguiente forma.\n", 126 | "\n", 127 | "$$\n", 128 | "\\begin{array}{ccc}\n", 129 | "\\left[\\color{green}{d_{2}}\\right] & \\left[\\color{green}{d_{1}}\\right] & \\left[\\color{green}{d_{0}}\\right]\\\\\n", 130 | "\\left[\\color{green}0\\right] & \\left[\\color{green}2\\right] & \\left[\\color{green}5\\right]\\\\\n", 131 | "\\left[\\color{green}1\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}5\\right]\\\\\n", 132 | "\\left[\\color{green}3\\right] & \\left[\\color{green}0\\right] & \\left[\\color{green}1\\right]\n", 133 | "\\end{array}\n", 134 | "$$\n", 135 | "\n", 136 | "Y la colección queda ordenada.\n" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": { 142 | "id": "mlm6KfnURLCA" 143 | }, 144 | "source": [ 145 | "## Análisis y Orden de Complejidad\n", 146 | "\n", 147 | "Dado que este algoritmo no se basa en comparaciones podemos pensar que el ordenar cada columna ($d_{i})$ tiene un costo lineal, es decir $O(n)$ ya que unicamente estamos organizando cada elemento respecto al dígito, tarea muy **similar a cuando organizamos elementos dentro de contenedores o cubetas**.\n", 148 | "\n", 149 | "Ahora supongamos que el elemento de mayor longitud dentro de la colección esta conformado por $k-dígitos$, entonces se tendrían que ordenar $k$ columnas, por lo tanto el algoritmo *RadixSort* pertenece al orden de complejidad $O(kn)$.\n", 150 | "\n", 151 | "Así que podemos pensar que el peor caso para este algoritmo es cuando $k$ es demasiado grande (y sobretodo si son pocos los elementos que poseén la misma longitud). Pensemos que $k\\approx n$, entonces el orden al que pertenecería este algoritmo sería $O(nn)=O(n²)$.\n", 152 | "\n" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": { 158 | "id": "qjDkvoF89_3n" 159 | }, 160 | "source": [ 161 | "# Ordenamiento por cubetas (*BucketSort*)\n", 162 | "\n", 163 | "Este algoritmo (no comparativo) consiste en generar contenedores (cubetas) que cumplan con determinadas características, enviar a los elementos que cumplan con estas a su respectivo contenedor y ordenar cada contenedor de manera individual." 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": { 169 | "id": "gsxkxdZvznIp" 170 | }, 171 | "source": [ 172 | "## Descripción\n", 173 | "\n", 174 | "De manera similar a *RadixSort*, para el ótimo funcionamiento de este algoritmo se requieren ciertas características y en este caso es que los elementos a ordenar se ecuentren distribuidos de manera uniforme sobre el espacio a ordenar. A continuación una descripción de como funciona este algoritmos:\n", 175 | "\n", 176 | "1. Dado que se conoce a priori el espacio donde se distribuyen los elementos a ordenar, se genéran contenedores (cubetas) con ciertas características, por ejemplo un rango de valores, para almacenar a los elementos que cumplan con estas características.\n", 177 | "2. Se recorren todos los elementos a ordenar y se va colocando uno a uno en el contenedor correspondiente.\n", 178 | "2. Se ordena cada contenedor de manera individual con este mismo algoritmo (o con alguno visto previamente.\n", 179 | "3. Se extraen los elementos de cada contenedor comenzando con el contenedor que almacene a los elementos de menor valor y finalizando con el contenedor que almacena a los elementos de mayor valor.\n", 180 | "4. El algoritmo termina cuando los elementos del último contener han sido extraidos.\n", 181 | "\n", 182 | "
\n", 183 | "\n", 184 | "
" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": { 190 | "id": "ou8sIl3O27CY" 191 | }, 192 | "source": [ 193 | "## Ejemplo\n", 194 | "\n", 195 | "En la imagen superior se muestra un ejemplo en el cuál se busca ordenar los datos.\n", 196 | "\n", 197 | "$$\n", 198 | "\\left[11\\right]\\left[9\\right]\\left[21\\right]\\left[8\\right]\\left[17\\right]\\left[19\\right]\\left[13\\right]\\left[1\\right]\\left[24\\right]\\left[12\\right]$$\n", 199 | "\n", 200 | "Dado que se conoce a priori el rango en el cuál se encuentran distribuidos los datos, podemos generar 5 contenedores que abarcan los rangos.\n", 201 | "\n", 202 | "$$\n", 203 | "\\left[0,5\\right),\\left[5,10\\right),\\left[10,15\\right),\\left[15,20\\right),\\left[20,26\\right)\n", 204 | "$$\n", 205 | "\n", 206 | "Y al organizar los datos en los contenedres se verían así:\n", 207 | "\n", 208 | "$$\n", 209 | "\\begin{array}{cc}\n", 210 | "\\left[0,5\\right): & 1\\\\\n", 211 | "\\left[5,10\\right): & 9,8\\\\\n", 212 | "\\left[10,15\\right): & 11,13,12\\\\\n", 213 | "\\left[15,20\\right): & 17,19\\\\\n", 214 | "\\left[2,26\\right): & 21,24\n", 215 | "\\end{array}\n", 216 | "$$\n", 217 | "\n", 218 | "Después de ordenar cada contenedor individualmente, los contenedores se ven así:\n", 219 | "\n", 220 | "$$\n", 221 | "\\begin{array}{cc}\n", 222 | "\\left[0,5\\right): & 1\\\\\n", 223 | "\\left[5,10\\right): & 8,9\\\\\n", 224 | "\\left[10,15\\right): & 11,12,13\\\\\n", 225 | "\\left[15,20\\right): & 17,19\\\\\n", 226 | "\\left[2,26\\right): & 21,24\n", 227 | "\\end{array}\n", 228 | "$$\n", 229 | "\n", 230 | "Y al extraer todos los datos de cada contenedor, de manera ordenada los datos finalmente quedan ordenados.\n", 231 | "\n", 232 | "$$\n", 233 | "\\left[1\\right]\\left[8\\right]\\left[9\\right]\\left[11\\right]\\left[12\\right]\\left[13\\right]\\left[17\\right]\\left[19\\right]\\left[21\\right]\\left[24\\right]$$\n", 234 | "\n", 235 | "\n", 236 | "\n", 237 | "\n" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": { 243 | "id": "KjHjPb_U4TbJ" 244 | }, 245 | "source": [ 246 | "## Análisis y Orden de complejidad\n", 247 | "\n", 248 | "Para llevar a cabo el análisis de la complejidad hay que preguntarse ¿qué tipo de algoritmo de ordenamiento se usará para ordenar individualmente cada cubeta y eso ayuda a determinar el orden de complejidad al que pertenece este algoritmo.\n", 249 | "\n", 250 | "Algunos autores consideran a *RadixSort* un caso particular de *BucketSort*.\n", 251 | "\n", 252 | "Se deja como ejercicio determinar el orden de complejidad al que pertenece el algoritmo *BucketSort*." 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": { 258 | "id": "dTMtQcsc4QA8" 259 | }, 260 | "source": [ 261 | "# Ordenando Objetos\n", 262 | "\n", 263 | "Es importante notar que este y todos los algoritmos de ordenamiento vistos funcionan con cualquier objeto que sea ordenable (realizando las respectivas adecuaciones), es decir, con todo clase de objetos en la que podamos establecer un orden, por ejemplo: $\\mathbb{N},\\,\\mathbb{Z},\\,\\mathbb{Q},\\,\\mathbb{R}$, incluso con $\\mathbb{C}$ o elementos más complejos como **vectores, matrices, palabras o todo aquello en lo que podamos establecer un orden**." 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": { 269 | "id": "pc6ND99T6HDA" 270 | }, 271 | "source": [ 272 | "## Algoritmos de ordenamiento en paralelo\n", 273 | "\n", 274 | "Todos los algoritmos vistos funcionan de manera **secuencial**, es decir se realiza un paso (operacion) a la vez, sin embargo esta estrategia (secuencial) es prácticamente obsoleta.\n", 275 | "\n", 276 | "¿Si tuvieramos más de una unidad de procesamiento (CPU), podríamos **implementar algunos de estos algoritmos en paralelo**?." 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": { 282 | "id": "YHiyGAPySr_f" 283 | }, 284 | "source": [ 285 | "#Referencias\n", 286 | "\n", 287 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 288 | "2. Libro Web: [Introduccion a Python](https://uniwebsidad.com/libros/algoritmos-python/capitulo-20/cuanto-cuesta-el-merge-sort?from=librosweb).\n", 289 | "3. Daniel T. Joyce: Object-Oriented Data Structures.\n", 290 | "4. John C. Mitchell: Concepts in programing Languages." 291 | ] 292 | } 293 | ], 294 | "metadata": { 295 | "colab": { 296 | "name": "03_RadixBucket.ipynb", 297 | "provenance": [], 298 | "toc_visible": true, 299 | "include_colab_link": true 300 | }, 301 | "kernelspec": { 302 | "display_name": "Python 3 (ipykernel)", 303 | "language": "python", 304 | "name": "python3" 305 | }, 306 | "language_info": { 307 | "codemirror_mode": { 308 | "name": "ipython", 309 | "version": 3 310 | }, 311 | "file_extension": ".py", 312 | "mimetype": "text/x-python", 313 | "name": "python", 314 | "nbconvert_exporter": "python", 315 | "pygments_lexer": "ipython3", 316 | "version": "3.11.6" 317 | } 318 | }, 319 | "nbformat": 4, 320 | "nbformat_minor": 0 321 | } -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/01_MergeQuick.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "JWcfyFMC2txs" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

MergeSort y QuickSort (análisis)

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 24 | "
Ayudante: Diana Laura Rojas Cristino
\n", 25 | "
Ayudante: Rodrigo Alejandro Sánchez Morales\n", 26 | "
\n", 27 | "
Materia: Manejo de Datos
\n", 28 | "
" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "XjwNdcb02txu" 35 | }, 36 | "source": [ 37 | "**Objetivo general**\n", 38 | "\n", 39 | "* Aprender los fundamentos y pasos a seguir de los algoritmos de ordenamiento Mergesort y Quicksort.\n", 40 | "\n", 41 | "**Objetivos particulares**\n", 42 | "\n", 43 | "* Conocer el funcionamiento de un algoritmo Mergesort y su complejidad computacional.\n", 44 | "* Conocer el funcionamiento de un algoritmo Mergesort y su complejidad computacional.\n", 45 | "* Comprender los ejemplos dados.\n", 46 | "\n", 47 | "## Contenido\n", 48 | "\n", 49 | "- [Introducción](#1)\n", 50 | "- [*Mergesort*](#2)\n", 51 | " - [Presentación del algoritmo](#2-1)\n", 52 | " - [Algoritmo básico](#2-2)\n", 53 | " - [¿Qué sucede con colecciones de tamaño $n$?](#2-3)\n", 54 | " - [Demostración](#2-4)\n", 55 | " - [Orden de complejidad (cota superior asintótica)](#2-5)\n", 56 | "- [*Quicksort*](#3)\n", 57 | " - [Análisis](#3-1)\n", 58 | " - [Algoritmo básico ](#3-2)\n", 59 | " - [Orden de complejidad (cota superior asintótica)](#3-3)\n", 60 | " \n", 61 | "- [Algoritmos en paralelo](#4)\n", 62 | " - [Ley de Amdahal](#4-1)\n", 63 | "\n", 64 | "- [Referencias](#5)\n" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": { 70 | "id": "wb6sJgkU2txv" 71 | }, 72 | "source": [ 73 | "\n", 74 | "\n", 75 | "# Introducción\n", 76 | "\n", 77 | "El algoritmo de ordenamiento *MergeSort*, es uno de los algoritmos que se estudia con frecuencia cuando se comienza con el análisis de algoritmos.\n", 78 | "\n", 79 | "La estrategia principal de este algoritmo de ordenamiento es la conocida como \"divide y venceras\". Inicialmente se tiene un conjunto o estructura de datos (lista, vector, arreglo, etc) de tamaño $n$ que se encuentran desordenados y que mediante algún atributo podemos ordenar.\n", 80 | "\n", 81 | "Otro de los algoritmos que ha mostrado un desempeño muy bueno en términos de tiempo de ejecución es el algoritmo conocido como *QuickSort*.\n", 82 | "\n", 83 | "La forma en la que funciona *QuickSort* es muy similar a *MergeSort* en el sentido de que inicialmente se tiene un conjunto o estructura de datos (lista, vector, arreglo, etc) de tamaño $n$ que se encuentran desordenados y que mediante algún atributo podemos ordenar. La diferencia entre ambos algoritmos es que *QuickSort* se toma un **pivote** para poder acomodar a los menores y mayores." 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": { 89 | "id": "IEwVI7U42txw" 90 | }, 91 | "source": [ 92 | "\n", 93 | "# *Mergesort*\n", 94 | "\n", 95 | "La idea de este algoritmo es la siguiente:\n", 96 | "\n", 97 | "1. Partir el conjunto en 2 subconjuntos de tamaño $\\frac{n}2$.\n", 98 | "2. Posteriormente volver a dividir estos en 4 subconjuntos de tamaño $\\frac{n}4$, se repite este proceso hasta que se tienen subconjuntos de tamaño 2.\n", 99 | "3. Ya que se tienen conjuntos de tamaño a lo más 1, se toma un par de estos elementos y se mezclan para formar un subconjunto ordenado.\n", 100 | "4. Cada uno de estos subconjuntos ordenados se mezclan de manera recursiva y ordenada, hasta que todo el conjunto de datos se encuentra ordenado.\n", 101 | "\n", 102 | "
\n", 103 | "\n", 104 | "
\n", 105 | "\n", 106 | "Dado estos antecedentes procedemos a definir la función de recurrencia, para poder identificar a que orden de complejidad pertenece este algoritmo recursivo." 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "id": "0CFpAwLn2txw" 113 | }, 114 | "source": [ 115 | "\n", 116 | "## Presentación del algoritmo\n", 117 | "\n", 118 | "Para el caso cuando se requiere ordenar una colección (lista) de tamaño 1 (o 0 caso trivial), basta con devolver dicha lista ya que esta ya esta ordenada, lo cual toma tiempo constante, digamos $b$.\n", 119 | "\n", 120 | "Para el caso de una colección de tamaño 2 ó mayor, es necesario partir a la mitad dicha colección, ordenar ambas subcolecciones y mezclarlas. Ahora consideremos que para simplificar el análisis de la complejidad diremos que $a$ es el tiempo que toma al microprocesador realizar una operación.\n", 121 | "\n", 122 | "Es por esto que ordenar una colección de tamaño $n$ tomará en total.\n", 123 | "\n", 124 | "$$2T(\\frac{n}{2})+a\\cdot n$$" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": { 130 | "id": "dLBH4fns2txx" 131 | }, 132 | "source": [ 133 | "\n", 134 | "## Algoritmo básico\n", 135 | "\n", 136 | "A continuación se muestra el pseudocódigo del algoritmo para ordenar por mezcla.\n", 137 | "\n", 138 | "
\n", 139 | "\n", 140 | "
" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": { 146 | "id": "tFu5T8iW2txx" 147 | }, 148 | "source": [ 149 | "\n", 150 | "## ¿Qué sucede con colecciones de tamaño $n$?\n", 151 | "\n", 152 | "Dado el análisis (y el pseudocódigo del algoritmo) podemos ver que ordenar una colección de tamaño $n$ tomara $2T(\\frac{n}{2})+a\\cdot n$. Pero este valor aun no permite identificar a que orden de complejidad pertenece este algoritmo.\n", 153 | "\n", 154 | "Es por eso que necesitamos definir la función de recurrencia de la siguiente forma.\n", 155 | "\n", 156 | "Función de recurrencia para el algoritmo de ordenamiento *MergeSort*:\n", 157 | "\n", 158 | "$$T(n)=\\begin{cases}\n", 159 | "b & n=0\\,\\acute{o}\\,n=1\\\\\n", 160 | "2T(\\frac{n}{2})+a\\cdot n & n\\geq2\n", 161 | "\\end{cases} \\tag{1}$$\n", 162 | "\n", 163 | "A la función (1), se le conoce como la función de recurrencia asociada al algoritmo de ordenamiento *MergeSort*. Ya que conocemos la función de recurrencia podemos tratar de determinar de manera formal cuantas operaciones le toma a este algoritmo ordenar una colección de datos.\n", 164 | "\n" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": { 170 | "id": "Qe9PMBBk2txy" 171 | }, 172 | "source": [ 173 | "\n", 174 | "## Demostración\n", 175 | "\n", 176 | "Esta demostración se sustenta en el análisis realizado previamene y en el [teorema maestro](https://es.wikipedia.org/wiki/Teorema_maestro).\n", 177 | "\n", 178 | "Sea $T(n)$ el número de operaciones que le toma al algoritmo anterior ordenar una lista de tamaño $n$ y dada la función de recurrencia.\n", 179 | "\n", 180 | "P.D. $$T(n)=n\\cdot b+a\\cdot n\\cdot\\log_{2}n$$\n", 181 | "\n", 182 | "Para mayor claridad de la demostración definimos $n=2^{k}$\n", 183 | "\n", 184 | "$$\\begin{eqnarray*}\n", 185 | "T(n)\t& = &\tT(2^{k}) \\\\\n", 186 | " & = & 2T(2^{k-1})+a\\cdot2^{k}....Definición\\\\\n", 187 | " & = & 2(2T(2^{k-2})+a\\cdot2^{k-1})+a\\cdot2^{k}.....Leyes\\,exponentes\\,y\\,Función\\,recurrencia \\\\\n", 188 | " & = & 2^{2}T(2^{k-2})+a\\cdot2^{k}+a\\cdot2^{k}.......Algebra\\,elemental\\\\\n", 189 | "\t& = & 2^{2}(2T(2^{k-3})+a\\cdot2^{k-2})+2\\cdot a\\cdot2^{k}.....Función\\,recurrencia\\\\\n", 190 | "i-veces & \\vdots & \\\\\n", 191 | "\t& = & 2^{i}T(2^{k-i})+i\\cdot a\\cdot2^{k} \\\\\n", 192 | "i=k\t\t& \\vdots & \\\\\n", 193 | "\t& = & 2^{k}T(2^{k-k})+k\\cdot a\\cdot2^{k}......2^{k-k}=1 \\\\\n", 194 | "\t& = &\t2^{k}b+k\\cdot a\\cdot2^{k}........T(1)=b \\\\\n", 195 | "\t& = &\tn\\cdot b+k\\cdot a\\cdot n......n=2^{k} \\\\\n", 196 | "\t& = &\tn\\cdot \\color{red}b+ \\color{red}a\\cdot n\\cdot\\log_{2}n....(2) \\\\\n", 197 | "\\end{eqnarray*}$$" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "id": "kKVQHEuv2txy" 204 | }, 205 | "source": [ 206 | "\n", 207 | "## Orden de complejidad (cota superior asintótica)\n", 208 | "\n", 209 | "Ya que $a$ y $b$ son constantes podemos concluir que de la ecuación (2), la función que 'crece' más rápido es\n", 210 | "\n", 211 | "$$a\\cdot n\\cdot\\log_{2}n$$\n", 212 | "\n", 213 | "Esa es la función que **acota superiormente el desempeño del algoritmo** *MergeSort*.\n", 214 | "\n", 215 | "Finalmente si asumimos que $a=c$, entonces se puede concluir que $T(n)\\in O(n\\cdot\\log_{2}n)$, es decir que el orden de complejidad al cual pertenece el algoritmo *MergeSort* es $n\\cdot\\log_{2}n$.\n", 216 | "\n", 217 | "En otras palabras podemos decir que el número de operaciones que le toma a *MergeSort* ordenar una colección de tamaño $n$ es proporcional a $n\\cdot\\log_{2}n$.\n", 218 | "\n", 219 | "Esto significa (con sustento matemático) que *MergeSort* tiene un mejor desempeño que *InsertionSort, SeleccionSort* o *BubbleSort* en cuanto a la cantidad de operaciones (tiempo) que le toma ordenar una colección de datos.\n", 220 | "\n", 221 | "En otros términos podemos decir que si pusiéramos a competir (en términos de tiempo) a *MergeSort* contra, por ejemplo *BubbleSort*, el ganador seria *MergeSort*." 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": { 227 | "id": "Uwtwwjcf2txz" 228 | }, 229 | "source": [ 230 | "\n", 231 | "\n", 232 | "# *Quicksort*\n", 233 | "\n", 234 | "La idea del algoritmo es la siguiente:\n", 235 | "\n", 236 | "1. Tomamos un valor de la lista de datos a ordenar (que idealmente parte a la colección a la mitad), a ese valor le llamamos pivote.\n", 237 | "2. Una vez que se eligió al pivote, comparamos a todos los elementos contra el pivote y **almacenamos los menores al lado izquierdo del pivote y a los mayores del lado derecho** los cual nos deja 2 subconjuntos de tamaño $\\frac{n}2$.\n", 238 | "2. Posteriormente volvemos a tomar un pivote en cada una de las respectivas subconjuntos, e idealmente volvemos a dividir estas en 4 subconjuntos de tamaño $\\frac{n}4$, se repite este proceso hasta que se tienen subconjuntos de tamaño 2.\n", 239 | "3. Ya que se tienen conjuntos de tamaño a lo mas 2, se ordenan de manera individual cada uno de ellos.\n", 240 | "4. Cada uno de estos subconjuntos ordenados se mezclan de manera recursiva y ordenada, hasta que todo el conjunto de datos se encuentra ordenado.\n", 241 | "\n", 242 | "
\n", 243 | "\n", 244 | "
" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "metadata": { 250 | "id": "9u7i0d792txz" 251 | }, 252 | "source": [ 253 | "\n", 254 | "\n", 255 | "## Análisis\n", 256 | "\n", 257 | "Hint, para identificar el peor caso es necesario prestar especial atención al pivote." 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "id": "RQ1PAQ5z2tx0" 264 | }, 265 | "source": [ 266 | "\n", 267 | "\n", 268 | "## Algoritmo básico" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 1, 274 | "metadata": { 275 | "id": "DeBOCNUy2tx0", 276 | "outputId": "e5af31e0-2864-4cf8-e296-e7777c06bea5" 277 | }, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "[1, 2, 3, 4, 5, 7, 8, 9]\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "# Definicion recursiva de quicksort\n", 289 | "def quickSort(lista):\n", 290 | " # si la lista es de tamano 1 o menor se devuelve\n", 291 | " if len(lista) < 2:\n", 292 | " return lista\n", 293 | " # en otro caso se parte la lista y se resuelve recursivamente\n", 294 | " else:\n", 295 | " # se parte la lista original (n operaciones)\n", 296 | " menores, pivote, mayores = particion(lista)\n", 297 | " # 2*T(n/2)\n", 298 | " return quickSort(menores)+[pivote]+quickSort(mayores)\n", 299 | "\n", 300 | "# Definicion del algoritmo para partir una lista en mayores y menores\n", 301 | "def particion(lista):\n", 302 | " mayores, menores = [], []\n", 303 | " # pivote para realizar la comparación\n", 304 | " pivote = lista[0]\n", 305 | " for i in range(1,len(lista)):\n", 306 | " if lista[i] < pivote:\n", 307 | " menores.append(lista[i])\n", 308 | " else:\n", 309 | " mayores.append(lista[i])\n", 310 | " # se devuelven ambas listas y el pivote\n", 311 | " return menores, pivote, mayores\n", 312 | "\n", 313 | "print(quickSort([2,8,5,3,9,4,1,7]))" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": { 319 | "id": "jRXtKHv52tx1" 320 | }, 321 | "source": [ 322 | "\n", 323 | "\n", 324 | "## Orden de complejidad (cota superior asintótica)\n", 325 | "\n", 326 | "Se deja como ejercicio al lector." 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": { 332 | "id": "NbRVQXP02tx1" 333 | }, 334 | "source": [ 335 | "\n", 336 | "\n", 337 | "# Algoritmos en paralelo\n", 338 | "\n", 339 | "Existen muchas restricciones y detalles a tomar en cuenta antes de comenzar con el análisis de algoritmos en paralelo, si embargo una de las más importantes es la ley de Amdahal." 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "metadata": { 345 | "id": "TtrE6KuW2tx1" 346 | }, 347 | "source": [ 348 | "\n", 349 | "## Ley de Amdahal\n", 350 | "\n", 351 | "Sea $f$ la fracción de operaciones en un calculo computacional que será llevado a cabo de manera secuencial, donde $0\\leq f\\leq1$. La máxima velocidad $\\Psi$ alcanzada mediante programación en paralelo con una computadora con $p$ procesadores enfocados en el mismo calculo es:\n", 352 | "\n", 353 | "$$\\Psi\\leq\\frac{1}{f+(1-f)/p}$$" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": { 359 | "id": "gPuByGVC2tx2" 360 | }, 361 | "source": [ 362 | "\n", 363 | "# Referencias\n", 364 | "\n", 365 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 366 | "2. Libro Web: [Introduccion a Python](https://uniwebsidad.com/libros/algoritmos-python/capitulo-20/cuanto-cuesta-el-merge-sort?from=librosweb).\n", 367 | "3. Daniel T. Joyce: Object-Oriented Data Structures.\n", 368 | "4. John C. Mitchell: Concepts in programing Languages." 369 | ] 370 | } 371 | ], 372 | "metadata": { 373 | "colab": { 374 | "include_colab_link": true, 375 | "provenance": [], 376 | "toc_visible": true 377 | }, 378 | "kernelspec": { 379 | "display_name": "Python 3 (ipykernel)", 380 | "language": "python", 381 | "name": "python3" 382 | }, 383 | "language_info": { 384 | "codemirror_mode": { 385 | "name": "ipython", 386 | "version": 3 387 | }, 388 | "file_extension": ".py", 389 | "mimetype": "text/x-python", 390 | "name": "python", 391 | "nbconvert_exporter": "python", 392 | "pygments_lexer": "ipython3", 393 | "version": "3.11.6" 394 | }, 395 | "vscode": { 396 | "interpreter": { 397 | "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" 398 | } 399 | } 400 | }, 401 | "nbformat": 4, 402 | "nbformat_minor": 4 403 | } 404 | -------------------------------------------------------------------------------- /02_AlgoritmosOrdenamiento/02_MergeQuick/.ipynb_checkpoints/01_MergeQuick-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "JWcfyFMC2txs" 17 | }, 18 | "source": [ 19 | "\n", 20 | "

MergeSort y QuickSort (análisis)

\n", 21 | "
\n", 22 | " \n", 23 | "
Profesor: M. en C. Miguel Angel Pérez León
\n", 24 | "
Ayudante: Diana Laura Rojas Cristino
\n", 25 | "
Ayudante: Rodrigo Alejandro Sánchez Morales\n", 26 | "
\n", 27 | "
Materia: Manejo de Datos
\n", 28 | "
" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "XjwNdcb02txu" 35 | }, 36 | "source": [ 37 | "**Objetivo general**\n", 38 | "\n", 39 | "* Aprender los fundamentos y pasos a seguir de los algoritmos de ordenamiento Mergesort y Quicksort.\n", 40 | "\n", 41 | "**Objetivos particulares**\n", 42 | "\n", 43 | "* Conocer el funcionamiento de un algoritmo Mergesort y su complejidad computacional.\n", 44 | "* Conocer el funcionamiento de un algoritmo Mergesort y su complejidad computacional.\n", 45 | "* Comprender los ejemplos dados.\n", 46 | "\n", 47 | "## Contenido\n", 48 | "\n", 49 | "- [Introducción](#1)\n", 50 | "- [*Mergesort*](#2)\n", 51 | " - [Presentación del algoritmo](#2-1)\n", 52 | " - [Algoritmo básico](#2-2)\n", 53 | " - [¿Qué sucede con colecciones de tamaño $n$?](#2-3)\n", 54 | " - [Demostración](#2-4)\n", 55 | " - [Orden de complejidad (cota superior asintótica)](#2-5)\n", 56 | "- [*Quicksort*](#3)\n", 57 | " - [Análisis](#3-1)\n", 58 | " - [Algoritmo básico ](#3-2)\n", 59 | " - [Orden de complejidad (cota superior asintótica)](#3-3)\n", 60 | " \n", 61 | "- [Algoritmos en paralelo](#4)\n", 62 | " - [Ley de Amdahal](#4-1)\n", 63 | "\n", 64 | "- [Referencias](#5)\n" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": { 70 | "id": "wb6sJgkU2txv" 71 | }, 72 | "source": [ 73 | "\n", 74 | "\n", 75 | "# Introducción\n", 76 | "\n", 77 | "El algoritmo de ordenamiento *MergeSort*, es uno de los algoritmos que se estudia con frecuencia cuando se comienza con el análisis de algoritmos.\n", 78 | "\n", 79 | "La estrategia principal de este algoritmo de ordenamiento es la conocida como \"divide y venceras\". Inicialmente se tiene un conjunto o estructura de datos (lista, vector, arreglo, etc) de tamaño $n$ que se encuentran desordenados y que mediante algún atributo podemos ordenar.\n", 80 | "\n", 81 | "Otro de los algoritmos que ha mostrado un desempeño muy bueno en términos de tiempo de ejecución es el algoritmo conocido como *QuickSort*.\n", 82 | "\n", 83 | "La forma en la que funciona *QuickSort* es muy similar a *MergeSort* en el sentido de que inicialmente se tiene un conjunto o estructura de datos (lista, vector, arreglo, etc) de tamaño $n$ que se encuentran desordenados y que mediante algún atributo podemos ordenar. La diferencia entre ambos algoritmos es que *QuickSort* se toma un **pivote** para poder acomodar a los menores y mayores." 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": { 89 | "id": "IEwVI7U42txw" 90 | }, 91 | "source": [ 92 | "\n", 93 | "# *Mergesort*\n", 94 | "\n", 95 | "La idea de este algoritmo es la siguiente:\n", 96 | "\n", 97 | "1. Partir el conjunto en 2 subconjuntos de tamaño $\\frac{n}2$.\n", 98 | "2. Posteriormente volver a dividir estos en 4 subconjuntos de tamaño $\\frac{n}4$, se repite este proceso hasta que se tienen subconjuntos de tamaño 2.\n", 99 | "3. Ya que se tienen conjuntos de tamaño a lo más 1, se toma un par de estos elementos y se mezclan para formar un subconjunto ordenado.\n", 100 | "4. Cada uno de estos subconjuntos ordenados se mezclan de manera recursiva y ordenada, hasta que todo el conjunto de datos se encuentra ordenado.\n", 101 | "\n", 102 | "
\n", 103 | "\n", 104 | "
\n", 105 | "\n", 106 | "Dado estos antecedentes procedemos a definir la función de recurrencia, para poder identificar a que orden de complejidad pertenece este algoritmo recursivo." 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "id": "0CFpAwLn2txw" 113 | }, 114 | "source": [ 115 | "\n", 116 | "## Presentación del algoritmo\n", 117 | "\n", 118 | "Para el caso cuando se requiere ordenar una colección (lista) de tamaño 1 (o 0 caso trivial), basta con devolver dicha lista ya que esta ya esta ordenada, lo cual toma tiempo constante, digamos $b$.\n", 119 | "\n", 120 | "Para el caso de una colección de tamaño 2 ó mayor, es necesario partir a la mitad dicha colección, ordenar ambas subcolecciones y mezclarlas. Ahora consideremos que para simplificar el análisis de la complejidad diremos que $a$ es el tiempo que toma al microprocesador realizar una operación.\n", 121 | "\n", 122 | "Es por esto que ordenar una colección de tamaño $n$ tomará en total.\n", 123 | "\n", 124 | "$$2T(\\frac{n}{2})+a\\cdot n$$" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": { 130 | "id": "dLBH4fns2txx" 131 | }, 132 | "source": [ 133 | "\n", 134 | "## Algoritmo básico\n", 135 | "\n", 136 | "A continuación se muestra el pseudocódigo del algoritmo para ordenar por mezcla.\n", 137 | "\n", 138 | "
\n", 139 | "\n", 140 | "
" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": { 146 | "id": "tFu5T8iW2txx" 147 | }, 148 | "source": [ 149 | "\n", 150 | "## ¿Qué sucede con colecciones de tamaño $n$?\n", 151 | "\n", 152 | "Dado el análisis (y el pseudocódigo del algoritmo) podemos ver que ordenar una colección de tamaño $n$ tomara $2T(\\frac{n}{2})+a\\cdot n$. Pero este valor aun no permite identificar a que orden de complejidad pertenece este algoritmo.\n", 153 | "\n", 154 | "Es por eso que necesitamos definir la función de recurrencia de la siguiente forma.\n", 155 | "\n", 156 | "Función de recurrencia para el algoritmo de ordenamiento *MergeSort*:\n", 157 | "\n", 158 | "$$T(n)=\\begin{cases}\n", 159 | "b & n=0\\,\\acute{o}\\,n=1\\\\\n", 160 | "2T(\\frac{n}{2})+a\\cdot n & n\\geq2\n", 161 | "\\end{cases} \\tag{1}$$\n", 162 | "\n", 163 | "A la función (1), se le conoce como la función de recurrencia asociada al algoritmo de ordenamiento *MergeSort*. Ya que conocemos la función de recurrencia podemos tratar de determinar de manera formal cuantas operaciones le toma a este algoritmo ordenar una colección de datos.\n", 164 | "\n" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": { 170 | "id": "Qe9PMBBk2txy" 171 | }, 172 | "source": [ 173 | "\n", 174 | "## Demostración\n", 175 | "\n", 176 | "Esta demostración se sustenta en el análisis realizado previamene y en el [teorema maestro](https://es.wikipedia.org/wiki/Teorema_maestro).\n", 177 | "\n", 178 | "Sea $T(n)$ el número de operaciones que le toma al algoritmo anterior ordenar una lista de tamaño $n$ y dada la función de recurrencia.\n", 179 | "\n", 180 | "P.D. $$T(n)=n\\cdot b+a\\cdot n\\cdot\\log_{2}n$$\n", 181 | "\n", 182 | "Para mayor claridad de la demostración definimos $n=2^{k}$\n", 183 | "\n", 184 | "$$\\begin{eqnarray*}\n", 185 | "T(n)\t& = &\tT(2^{k}) \\\\\n", 186 | " & = & 2T(2^{k-1})+a\\cdot2^{k}....Definición\\\\\n", 187 | " & = & 2(2T(2^{k-2})+a\\cdot2^{k-1})+a\\cdot2^{k}.....Leyes\\,exponentes\\,y\\,Función\\,recurrencia \\\\\n", 188 | " & = & 2^{2}T(2^{k-2})+a\\cdot2^{k}+a\\cdot2^{k}.......Algebra\\,elemental\\\\\n", 189 | "\t& = & 2^{2}(2T(2^{k-3})+a\\cdot2^{k-2})+2\\cdot a\\cdot2^{k}.....Función\\,recurrencia\\\\\n", 190 | "i-veces & \\vdots & \\\\\n", 191 | "\t& = & 2^{i}T(2^{k-i})+i\\cdot a\\cdot2^{k} \\\\\n", 192 | "i=k\t\t& \\vdots & \\\\\n", 193 | "\t& = & 2^{k}T(2^{k-k})+k\\cdot a\\cdot2^{k}......2^{k-k}=1 \\\\\n", 194 | "\t& = &\t2^{k}b+k\\cdot a\\cdot2^{k}........T(1)=b \\\\\n", 195 | "\t& = &\tn\\cdot b+k\\cdot a\\cdot n......n=2^{k} \\\\\n", 196 | "\t& = &\tn\\cdot \\color{red}b+ \\color{red}a\\cdot n\\cdot\\log_{2}n....(2) \\\\\n", 197 | "\\end{eqnarray*}$$" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "id": "kKVQHEuv2txy" 204 | }, 205 | "source": [ 206 | "\n", 207 | "## Orden de complejidad (cota superior asintótica)\n", 208 | "\n", 209 | "Ya que $a$ y $b$ son constantes podemos concluir que de la ecuación (2), la función que 'crece' más rápido es\n", 210 | "\n", 211 | "$$a\\cdot n\\cdot\\log_{2}n$$\n", 212 | "\n", 213 | "Esa es la función que **acota superiormente el desempeño del algoritmo** *MergeSort*.\n", 214 | "\n", 215 | "Finalmente si asumimos que $a=c$, entonces se puede concluir que $T(n)\\in O(n\\cdot\\log_{2}n)$, es decir que el orden de complejidad al cual pertenece el algoritmo *MergeSort* es $n\\cdot\\log_{2}n$.\n", 216 | "\n", 217 | "En otras palabras podemos decir que el número de operaciones que le toma a *MergeSort* ordenar una colección de tamaño $n$ es proporcional a $n\\cdot\\log_{2}n$.\n", 218 | "\n", 219 | "Esto significa (con sustento matemático) que *MergeSort* tiene un mejor desempeño que *InsertionSort, SeleccionSort* o *BubbleSort* en cuanto a la cantidad de operaciones (tiempo) que le toma ordenar una colección de datos.\n", 220 | "\n", 221 | "En otros términos podemos decir que si pusiéramos a competir (en términos de tiempo) a *MergeSort* contra, por ejemplo *BubbleSort*, el ganador seria *MergeSort*." 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": { 227 | "id": "Uwtwwjcf2txz" 228 | }, 229 | "source": [ 230 | "\n", 231 | "\n", 232 | "# *Quicksort*\n", 233 | "\n", 234 | "La idea del algoritmo es la siguiente:\n", 235 | "\n", 236 | "1. Tomamos un valor de la lista de datos a ordenar (que idealmente parte a la colección a la mitad), a ese valor le llamamos pivote.\n", 237 | "2. Una vez que se eligió al pivote, comparamos a todos los elementos contra el pivote y **almacenamos los menores al lado izquierdo del pivote y a los mayores del lado derecho** los cual nos deja 2 subconjuntos de tamaño $\\frac{n}2$.\n", 238 | "2. Posteriormente volvemos a tomar un pivote en cada una de las respectivas subconjuntos, e idealmente volvemos a dividir estas en 4 subconjuntos de tamaño $\\frac{n}4$, se repite este proceso hasta que se tienen subconjuntos de tamaño 2.\n", 239 | "3. Ya que se tienen conjuntos de tamaño a lo mas 2, se ordenan de manera individual cada uno de ellos.\n", 240 | "4. Cada uno de estos subconjuntos ordenados se mezclan de manera recursiva y ordenada, hasta que todo el conjunto de datos se encuentra ordenado.\n", 241 | "\n", 242 | "
\n", 243 | "\n", 244 | "
" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "metadata": { 250 | "id": "9u7i0d792txz" 251 | }, 252 | "source": [ 253 | "\n", 254 | "\n", 255 | "## Análisis\n", 256 | "\n", 257 | "Hint, para identificar el peor caso es necesario prestar especial atención al pivote." 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "id": "RQ1PAQ5z2tx0" 264 | }, 265 | "source": [ 266 | "\n", 267 | "\n", 268 | "## Algoritmo básico" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 1, 274 | "metadata": { 275 | "id": "DeBOCNUy2tx0", 276 | "outputId": "e5af31e0-2864-4cf8-e296-e7777c06bea5" 277 | }, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "[1, 2, 3, 4, 5, 7, 8, 9]\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "# Definicion recursiva de quicksort\n", 289 | "def quickSort(lista):\n", 290 | " # si la lista es de tamano 1 o menor se devuelve\n", 291 | " if len(lista) < 2:\n", 292 | " return lista\n", 293 | " # en otro caso se parte la lista y se resuelve recursivamente\n", 294 | " else:\n", 295 | " # se parte la lista original (n operaciones)\n", 296 | " menores, pivote, mayores = particion(lista)\n", 297 | " # 2*T(n/2)\n", 298 | " return quickSort(menores)+[pivote]+quickSort(mayores)\n", 299 | "\n", 300 | "# Definicion del algoritmo para partir una lista en mayores y menores\n", 301 | "def particion(lista):\n", 302 | " mayores, menores = [], []\n", 303 | " # pivote para realizar la comparación\n", 304 | " pivote = lista[0]\n", 305 | " for i in range(1,len(lista)):\n", 306 | " if lista[i] < pivote:\n", 307 | " menores.append(lista[i])\n", 308 | " else:\n", 309 | " mayores.append(lista[i])\n", 310 | " # se devuelven ambas listas y el pivote\n", 311 | " return menores, pivote, mayores\n", 312 | "\n", 313 | "print(quickSort([2,8,5,3,9,4,1,7]))" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": { 319 | "id": "jRXtKHv52tx1" 320 | }, 321 | "source": [ 322 | "\n", 323 | "\n", 324 | "## Orden de complejidad (cota superior asintótica)\n", 325 | "\n", 326 | "Se deja como ejercicio al lector." 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": { 332 | "id": "NbRVQXP02tx1" 333 | }, 334 | "source": [ 335 | "\n", 336 | "\n", 337 | "# Algoritmos en paralelo\n", 338 | "\n", 339 | "Existen muchas restricciones y detalles a tomar en cuenta antes de comenzar con el análisis de algoritmos en paralelo, si embargo una de las más importantes es la ley de Amdahal." 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "metadata": { 345 | "id": "TtrE6KuW2tx1" 346 | }, 347 | "source": [ 348 | "\n", 349 | "## Ley de Amdahal\n", 350 | "\n", 351 | "Sea $f$ la fracción de operaciones en un calculo computacional que será llevado a cabo de manera secuencial, donde $0\\leq f\\leq1$. La máxima velocidad $\\Psi$ alcanzada mediante programación en paralelo con una computadora con $p$ procesadores enfocados en el mismo calculo es:\n", 352 | "\n", 353 | "$$\\Psi\\leq\\frac{1}{f+(1-f)/p}$$" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": { 359 | "id": "gPuByGVC2tx2" 360 | }, 361 | "source": [ 362 | "\n", 363 | "# Referencias\n", 364 | "\n", 365 | "1. Thomas H. Cormen: Introduction to Algorithms.\n", 366 | "2. Libro Web: [Introduccion a Python](https://uniwebsidad.com/libros/algoritmos-python/capitulo-20/cuanto-cuesta-el-merge-sort?from=librosweb).\n", 367 | "3. Daniel T. Joyce: Object-Oriented Data Structures.\n", 368 | "4. John C. Mitchell: Concepts in programing Languages." 369 | ] 370 | } 371 | ], 372 | "metadata": { 373 | "colab": { 374 | "include_colab_link": true, 375 | "provenance": [], 376 | "toc_visible": true 377 | }, 378 | "kernelspec": { 379 | "display_name": "Python 3 (ipykernel)", 380 | "language": "python", 381 | "name": "python3" 382 | }, 383 | "language_info": { 384 | "codemirror_mode": { 385 | "name": "ipython", 386 | "version": 3 387 | }, 388 | "file_extension": ".py", 389 | "mimetype": "text/x-python", 390 | "name": "python", 391 | "nbconvert_exporter": "python", 392 | "pygments_lexer": "ipython3", 393 | "version": "3.11.6" 394 | }, 395 | "vscode": { 396 | "interpreter": { 397 | "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" 398 | } 399 | } 400 | }, 401 | "nbformat": 4, 402 | "nbformat_minor": 4 403 | } 404 | --------------------------------------------------------------------------------