├── 1 Search
├── 1 Blind Search
│ ├── BrFS.ipynb
│ ├── README.md
│ ├── code
│ │ ├── BrFS.py
│ │ ├── __pycache__
│ │ │ ├── BrFS.cpython-38.pyc
│ │ │ ├── node.cpython-38.pyc
│ │ │ ├── open_list.cpython-38.pyc
│ │ │ └── puzzle.cpython-38.pyc
│ │ ├── node.py
│ │ ├── open_list.py
│ │ ├── problems_r8.txt
│ │ ├── puzzle.py
│ │ └── test_brfs_puzzle.py
│ └── img
│ │ ├── alg2.1.png
│ │ └── alg2.3.png
├── 2 Informed Search
│ ├── 2_A_.ipynb
│ ├── BrFS.py
│ ├── README.md
│ ├── __pycache__
│ │ ├── BrFS.cpython-38.pyc
│ │ ├── node.cpython-38.pyc
│ │ ├── open_list.cpython-38.pyc
│ │ └── puzzle.cpython-38.pyc
│ ├── node.py
│ ├── open_list.py
│ ├── problems_r8.txt
│ ├── puzzle.py
│ └── test_brfs_puzzle.py
└── 3 Adversarial Search
│ └── 3_Adversarial_Search.ipynb
├── 2 Programacion Logica
├── 1.swinb
├── 2.swinb
└── 3.swinb
├── 3 Machine Learning
├── 1 regresion.ipynb
├── 2 Neural Networks.ipynb
└── 3 clustering_Kmeans.ipynb
└── README.md
/1 Search/1 Blind Search/BrFS.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "1. BrFS",
7 | "provenance": [],
8 | "collapsed_sections": []
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "source": [
22 | "Accesible en: https://colab.research.google.com/drive/16AS-V5F66s4KWzpCRfLhCi9KM_l0vdyx?usp=sharing"
23 | ],
24 | "metadata": {
25 | "id": "HGXRILQ0V8Tm"
26 | }
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "source": [
31 | "# Búsqueda\n",
32 | "\n",
33 | "En esta clase resolveremos un problema claśico, el 8-puzzle, utilizando Breadth-First Search (BrFS).\n",
34 | "\n",
35 | "\n"
36 | ],
37 | "metadata": {
38 | "id": "9zqyxrzboFLK"
39 | }
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "source": [
44 | "La clase `Node` representa un search state genérico, que será útil para cualquier problema de búsqueda. \n",
45 | "\n",
46 | "Cada uno de los estados de búsqueda, tendrá asociado un puntaje almacenado en la propiedad `key`, el cual nos indicará cuando un nodo es mejor (o solo mas prometedor) que otro. En este caso, a menor `key`, mas prometedor es el nodo. \n",
47 | "\n",
48 | "Tendrá los métodos __gt__ y __lt__ implementan los operadores mayor y menor que, y verifican que si nodo `v` es menor que un nodo `u`, el nodo `v` es mejor."
49 | ],
50 | "metadata": {
51 | "id": "sy4ypMzcogBd"
52 | }
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {
58 | "id": "tqksIGtK6ezG"
59 | },
60 | "outputs": [],
61 | "source": [
62 | "class Node:\n",
63 | " def __init__(self, search_state, parent=None, action=''):\n",
64 | " self.state = search_state # El estado (en este caso, objeto de tipo puzzle)\n",
65 | " self.parent = parent # El estado padre.\n",
66 | " self.action = action # El nombre de la accion que derivó en este estado (string)\n",
67 | " \n",
68 | " def __repr__(self):\n",
69 | " return self.state.__repr__()\n",
70 | "\n",
71 | " # Función utilizada para reconstruir la solución. Llama al método trace del estado padre hasta que no exista padre.\n",
72 | " def trace(self): \n",
73 | " s = ''\n",
74 | " if self.parent:\n",
75 | " s = self.parent.trace()\n",
76 | " s += '-' + self.action + '->'\n",
77 | " s += str(self.state)\n",
78 | " return s"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "source": [
84 | "#clase Puzzle\n",
85 | "\n",
86 | "Esta representa un estado del problema. La función mas importante es el método `succ`, que se encarga de la generación de estados sucesores."
87 | ],
88 | "metadata": {
89 | "id": "tql96P2Rpx9n"
90 | }
91 | },
92 | {
93 | "cell_type": "code",
94 | "source": [
95 | "import sys\n",
96 | "import copy\n",
97 | "import numpy as np\n",
98 | "\n",
99 | "\n",
100 | "class Puzzle:\n",
101 | " goal8 = list(range(9))\n",
102 | " def __init__(self, board=None, blank=-1):\n",
103 | " if not board:\n",
104 | " self.x = 3\n",
105 | " self.size = 9\n",
106 | " self.board = [i for i in range(0, self.size)]\n",
107 | " self.blank = 0\n",
108 | " else:\n",
109 | " self.board = board\n",
110 | " if len(self.board) == 9:\n",
111 | " self.x = 3\n",
112 | " self.size = 9\n",
113 | " else:\n",
114 | " print('puzzle size not supported')\n",
115 | " sys.exit(1)\n",
116 | " if blank == -1:\n",
117 | " self.blank = board.index(0)\n",
118 | "\n",
119 | "\n",
120 | " def __hash__(self):\n",
121 | " return hash(tuple(self.board))\n",
122 | "\n",
123 | " def __eq__(self, other):\n",
124 | " return self.board == other.board\n",
125 | "\n",
126 | " def __repr__(self):\n",
127 | " def tostr(d):\n",
128 | " if d > 0:\n",
129 | " return \"%2d\" % (d)\n",
130 | " else:\n",
131 | " return \" \"\n",
132 | " s = '\\n'\n",
133 | " for i in range(0, self.x):\n",
134 | " s += \"|\"\n",
135 | " s += \"|\".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]])\n",
136 | " s += \"|\\n\"\n",
137 | " return s\n",
138 | "\n",
139 | " def successors(self):\n",
140 | " '''\n",
141 | " Crea una lista de tuplas de la forma (estado, accion, costo)\n",
142 | " donde estado es el estado sucesor de self que se genera al ejecutar\n",
143 | " accion (un string) y costo (un numero real) es el costo de accion\n",
144 | " '''\n",
145 | " def create_child(newblank):\n",
146 | " child = copy.deepcopy(self)\n",
147 | " child.blank = newblank\n",
148 | " child.board[child.blank] = 0\n",
149 | " child.board[self.blank] = self.board[newblank]\n",
150 | " return child\n",
151 | "\n",
152 | " succ = []\n",
153 | " if self.blank > self.x - 1:\n",
154 | " c = create_child(self.blank-self.x)\n",
155 | " succ.append((c, 'down', 1))\n",
156 | " if self.blank % self.x > 0:\n",
157 | " c = create_child(self.blank-1)\n",
158 | " succ.append((c, 'right', 1))\n",
159 | " if self.blank % self.x < self.x - 1:\n",
160 | " c = create_child(self.blank+1)\n",
161 | " succ.append((c, 'left', 1))\n",
162 | " if self.blank < self.size - self.x:\n",
163 | " c = create_child(self.blank+self.x)\n",
164 | " succ.append((c, 'up', 1))\n",
165 | " return succ\n",
166 | "\n",
167 | " def is_goal(self):\n",
168 | " return Puzzle.goal8 == self.board "
169 | ],
170 | "metadata": {
171 | "id": "JZkr7Qm66r4_"
172 | },
173 | "execution_count": null,
174 | "outputs": []
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "source": [
179 | "# Open List\n",
180 | "Como es una implementación de búsqueda en anchura, la OPEN es implementada como una cola"
181 | ],
182 | "metadata": {
183 | "id": "yHyOz-_sWuX8"
184 | }
185 | },
186 | {
187 | "cell_type": "code",
188 | "source": [
189 | "from collections import deque \n",
190 | "\n",
191 | "class OpenList_BrFS:\n",
192 | " # Inicia una lista vacia\n",
193 | " def __init__(self):\n",
194 | " self.items = deque([])\n",
195 | "\n",
196 | " # La cantidad de elementos en el heap\n",
197 | " @staticmethod\n",
198 | " def size(self):\n",
199 | " return len(self.items)\n",
200 | "\n",
201 | " # Retorna el mejor elemento del heap\n",
202 | " def top(self):\n",
203 | " if self.size == 0:\n",
204 | " return None\n",
205 | " else:\n",
206 | " return self.items[0]\n",
207 | "\n",
208 | " # Retorna el primer elemento y lo elimina\n",
209 | " def extract(self):\n",
210 | " if len(self.items):\n",
211 | " return self.items.popleft()\n",
212 | " else : \n",
213 | " None\n",
214 | "\n",
215 | " # Inserta un elemento en el heap\n",
216 | " def insert(self, element):\n",
217 | " self.items.append(element)\n",
218 | "\n",
219 | " # Verifica si esta vacia\n",
220 | " def is_empty(self):\n",
221 | " return self.size == 0\n"
222 | ],
223 | "metadata": {
224 | "id": "w50CoA2xY7T9"
225 | },
226 | "execution_count": null,
227 | "outputs": []
228 | },
229 | {
230 | "cell_type": "code",
231 | "source": [
232 | "import time\n",
233 | "\n",
234 | "class BrFS:\n",
235 | " def __init__(self, initial_state):\n",
236 | " self.expansions = 0\n",
237 | " self.initial_state = initial_state\n",
238 | " self.solution = None\n",
239 | " self.open = OpenList_BrFS()\n",
240 | " self.generated = {}\n",
241 | "\n",
242 | "\n",
243 | "\n",
244 | " def search(self):\n",
245 | " self.start_time = time.process_time()\n",
246 | " \n",
247 | " initial_node = Node(self.initial_state)\n",
248 | " initial_node.g = 0\n",
249 | " self.open.insert(initial_node) \n",
250 | " self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde\n",
251 | "\n",
252 | " while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones) \n",
253 | " n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad))\n",
254 | "\n",
255 | " if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto)\n",
256 | " self.end_time = time.process_time() \n",
257 | " self.solution = n # Define el estado extraido como solución (para reconstruirlo luego)\n",
258 | " return n\n",
259 | " succ = n.state.successors() # Genera los sucesores\n",
260 | " self.expansions += 1 # Aumenta en 1 las expansiones\n",
261 | " for child_state, action, cost in succ: # Por cada uno de los estados sucesores\n",
262 | " child_node = self.generated.get(child_state) # Si no existe en generados retorna 0 (false)\n",
263 | " path_cost = n.g + cost # costo del camino encontrado hasta child_state\n",
264 | " if child_node is None : # si el estado no existe en OPEN U CLOSE\n",
265 | " child_node = Node(child_state, n) # creamos el nodo de child_state\n",
266 | " self.generated[child_state] = child_node # lo agregamos a generados\n",
267 | " child_node.action = action # definimos el nombre de la acción del nodo\n",
268 | " child_node.parent = n # definimos el padre\n",
269 | " child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion\n",
270 | " self.open.insert(child_node) # agrega el nodo a la OPEN \n",
271 | " \n",
272 | " self.end_time = time.process_time() \n",
273 | " print(\"No solution found\") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución.\n",
274 | " return None\n",
275 | "\n",
276 | " "
277 | ],
278 | "metadata": {
279 | "id": "Z7IkA9ZGY8Lf"
280 | },
281 | "execution_count": null,
282 | "outputs": []
283 | },
284 | {
285 | "cell_type": "code",
286 | "source": [
287 | "problem = Puzzle([4, 7, 5, 0, 8, 2, 6, 1, 3])\n",
288 | "\n",
289 | "s = BrFS(problem) \n",
290 | "result = s.search()\n",
291 | "print('Expansiones: %10d' % s.expansions )\n",
292 | "print('Generados: %10d' % len(s.generated) )\n",
293 | "print('Costo: %10d' % result.g )\n",
294 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n",
295 | "\n",
296 | "print(\"Solucion*-***************************************\")\n",
297 | "print(result.trace())"
298 | ],
299 | "metadata": {
300 | "colab": {
301 | "base_uri": "https://localhost:8080/"
302 | },
303 | "id": "TsGLjxaaZAwm",
304 | "outputId": "1d3a2c38-8c3a-4a4c-cabe-d7360e7440d8"
305 | },
306 | "execution_count": null,
307 | "outputs": [
308 | {
309 | "output_type": "stream",
310 | "name": "stdout",
311 | "text": [
312 | "Expansiones: 142540\n",
313 | "Generados: 161359\n",
314 | "Costo: 25\n",
315 | "Tiempo: 10.64\n",
316 | "Solucion*-***************************************\n",
317 | "\n",
318 | "| 4| 7| 5|\n",
319 | "| | 8| 2|\n",
320 | "| 6| 1| 3|\n",
321 | "-down->\n",
322 | "| | 7| 5|\n",
323 | "| 4| 8| 2|\n",
324 | "| 6| 1| 3|\n",
325 | "-left->\n",
326 | "| 7| | 5|\n",
327 | "| 4| 8| 2|\n",
328 | "| 6| 1| 3|\n",
329 | "-left->\n",
330 | "| 7| 5| |\n",
331 | "| 4| 8| 2|\n",
332 | "| 6| 1| 3|\n",
333 | "-up->\n",
334 | "| 7| 5| 2|\n",
335 | "| 4| 8| |\n",
336 | "| 6| 1| 3|\n",
337 | "-right->\n",
338 | "| 7| 5| 2|\n",
339 | "| 4| | 8|\n",
340 | "| 6| 1| 3|\n",
341 | "-down->\n",
342 | "| 7| | 2|\n",
343 | "| 4| 5| 8|\n",
344 | "| 6| 1| 3|\n",
345 | "-right->\n",
346 | "| | 7| 2|\n",
347 | "| 4| 5| 8|\n",
348 | "| 6| 1| 3|\n",
349 | "-up->\n",
350 | "| 4| 7| 2|\n",
351 | "| | 5| 8|\n",
352 | "| 6| 1| 3|\n",
353 | "-up->\n",
354 | "| 4| 7| 2|\n",
355 | "| 6| 5| 8|\n",
356 | "| | 1| 3|\n",
357 | "-left->\n",
358 | "| 4| 7| 2|\n",
359 | "| 6| 5| 8|\n",
360 | "| 1| | 3|\n",
361 | "-left->\n",
362 | "| 4| 7| 2|\n",
363 | "| 6| 5| 8|\n",
364 | "| 1| 3| |\n",
365 | "-down->\n",
366 | "| 4| 7| 2|\n",
367 | "| 6| 5| |\n",
368 | "| 1| 3| 8|\n",
369 | "-right->\n",
370 | "| 4| 7| 2|\n",
371 | "| 6| | 5|\n",
372 | "| 1| 3| 8|\n",
373 | "-right->\n",
374 | "| 4| 7| 2|\n",
375 | "| | 6| 5|\n",
376 | "| 1| 3| 8|\n",
377 | "-up->\n",
378 | "| 4| 7| 2|\n",
379 | "| 1| 6| 5|\n",
380 | "| | 3| 8|\n",
381 | "-left->\n",
382 | "| 4| 7| 2|\n",
383 | "| 1| 6| 5|\n",
384 | "| 3| | 8|\n",
385 | "-down->\n",
386 | "| 4| 7| 2|\n",
387 | "| 1| | 5|\n",
388 | "| 3| 6| 8|\n",
389 | "-down->\n",
390 | "| 4| | 2|\n",
391 | "| 1| 7| 5|\n",
392 | "| 3| 6| 8|\n",
393 | "-right->\n",
394 | "| | 4| 2|\n",
395 | "| 1| 7| 5|\n",
396 | "| 3| 6| 8|\n",
397 | "-up->\n",
398 | "| 1| 4| 2|\n",
399 | "| | 7| 5|\n",
400 | "| 3| 6| 8|\n",
401 | "-up->\n",
402 | "| 1| 4| 2|\n",
403 | "| 3| 7| 5|\n",
404 | "| | 6| 8|\n",
405 | "-left->\n",
406 | "| 1| 4| 2|\n",
407 | "| 3| 7| 5|\n",
408 | "| 6| | 8|\n",
409 | "-down->\n",
410 | "| 1| 4| 2|\n",
411 | "| 3| | 5|\n",
412 | "| 6| 7| 8|\n",
413 | "-down->\n",
414 | "| 1| | 2|\n",
415 | "| 3| 4| 5|\n",
416 | "| 6| 7| 8|\n",
417 | "-right->\n",
418 | "| | 1| 2|\n",
419 | "| 3| 4| 5|\n",
420 | "| 6| 7| 8|\n",
421 | "\n"
422 | ]
423 | }
424 | ]
425 | },
426 | {
427 | "cell_type": "code",
428 | "source": [
429 | "#prblema 3 : 03 0 1 8 7 2 4 5 6 3\n",
430 | "\n",
431 | "problem = Puzzle([0, 1, 8, 7, 2, 4, 5, 6, 3])\n",
432 | "\n",
433 | "s = BrFS(problem) \n",
434 | "result = s.search()\n",
435 | "print('Expansiones: %10d' % s.expansions )\n",
436 | "print('Generados: %10d' % len(s.generated) )\n",
437 | "print('Costo: %10d' % result.g )\n",
438 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n",
439 | "\n",
440 | "print(\"Solucion*-***************************************\")\n",
441 | "print(result.trace())"
442 | ],
443 | "metadata": {
444 | "colab": {
445 | "base_uri": "https://localhost:8080/"
446 | },
447 | "id": "tVHD5iLoRg2U",
448 | "outputId": "9a6f8650-a7b5-4c52-b967-fe558dab7e71"
449 | },
450 | "execution_count": null,
451 | "outputs": [
452 | {
453 | "output_type": "stream",
454 | "name": "stdout",
455 | "text": [
456 | "Expansiones: 44479\n",
457 | "Generados: 61733\n",
458 | "Costo: 20\n",
459 | "Tiempo: 3.18\n",
460 | "Solucion*-***************************************\n",
461 | "\n",
462 | "| | 1| 8|\n",
463 | "| 7| 2| 4|\n",
464 | "| 5| 6| 3|\n",
465 | "-left->\n",
466 | "| 1| | 8|\n",
467 | "| 7| 2| 4|\n",
468 | "| 5| 6| 3|\n",
469 | "-up->\n",
470 | "| 1| 2| 8|\n",
471 | "| 7| | 4|\n",
472 | "| 5| 6| 3|\n",
473 | "-left->\n",
474 | "| 1| 2| 8|\n",
475 | "| 7| 4| |\n",
476 | "| 5| 6| 3|\n",
477 | "-down->\n",
478 | "| 1| 2| |\n",
479 | "| 7| 4| 8|\n",
480 | "| 5| 6| 3|\n",
481 | "-right->\n",
482 | "| 1| | 2|\n",
483 | "| 7| 4| 8|\n",
484 | "| 5| 6| 3|\n",
485 | "-up->\n",
486 | "| 1| 4| 2|\n",
487 | "| 7| | 8|\n",
488 | "| 5| 6| 3|\n",
489 | "-up->\n",
490 | "| 1| 4| 2|\n",
491 | "| 7| 6| 8|\n",
492 | "| 5| | 3|\n",
493 | "-right->\n",
494 | "| 1| 4| 2|\n",
495 | "| 7| 6| 8|\n",
496 | "| | 5| 3|\n",
497 | "-down->\n",
498 | "| 1| 4| 2|\n",
499 | "| | 6| 8|\n",
500 | "| 7| 5| 3|\n",
501 | "-left->\n",
502 | "| 1| 4| 2|\n",
503 | "| 6| | 8|\n",
504 | "| 7| 5| 3|\n",
505 | "-up->\n",
506 | "| 1| 4| 2|\n",
507 | "| 6| 5| 8|\n",
508 | "| 7| | 3|\n",
509 | "-left->\n",
510 | "| 1| 4| 2|\n",
511 | "| 6| 5| 8|\n",
512 | "| 7| 3| |\n",
513 | "-down->\n",
514 | "| 1| 4| 2|\n",
515 | "| 6| 5| |\n",
516 | "| 7| 3| 8|\n",
517 | "-right->\n",
518 | "| 1| 4| 2|\n",
519 | "| 6| | 5|\n",
520 | "| 7| 3| 8|\n",
521 | "-up->\n",
522 | "| 1| 4| 2|\n",
523 | "| 6| 3| 5|\n",
524 | "| 7| | 8|\n",
525 | "-right->\n",
526 | "| 1| 4| 2|\n",
527 | "| 6| 3| 5|\n",
528 | "| | 7| 8|\n",
529 | "-down->\n",
530 | "| 1| 4| 2|\n",
531 | "| | 3| 5|\n",
532 | "| 6| 7| 8|\n",
533 | "-left->\n",
534 | "| 1| 4| 2|\n",
535 | "| 3| | 5|\n",
536 | "| 6| 7| 8|\n",
537 | "-down->\n",
538 | "| 1| | 2|\n",
539 | "| 3| 4| 5|\n",
540 | "| 6| 7| 8|\n",
541 | "-right->\n",
542 | "| | 1| 2|\n",
543 | "| 3| 4| 5|\n",
544 | "| 6| 7| 8|\n",
545 | "\n"
546 | ]
547 | }
548 | ]
549 | },
550 | {
551 | "cell_type": "code",
552 | "source": [
553 | "#prblema 3 : 03 0 1 8 7 2 4 5 6 3\n",
554 | "\n",
555 | "problem = Puzzle([3, 1, 2, 0, 4, 5, 6, 7, 8])\n",
556 | "\n",
557 | "s = BrFS(problem) \n",
558 | "result = s.search()\n",
559 | "print('Expansiones: %10d' % s.expansions )\n",
560 | "print('Generados: %10d' % len(s.generated) )\n",
561 | "print('Costo: %10d' % result.g )\n",
562 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n",
563 | "\n",
564 | "print(\"Solucion*-***************************************\")\n",
565 | "print(result.trace())"
566 | ],
567 | "metadata": {
568 | "colab": {
569 | "base_uri": "https://localhost:8080/"
570 | },
571 | "id": "V9xRERWIR9l0",
572 | "outputId": "464f03a4-f4bc-4ff5-9569-06360eb4d76f"
573 | },
574 | "execution_count": null,
575 | "outputs": [
576 | {
577 | "output_type": "stream",
578 | "name": "stdout",
579 | "text": [
580 | "Expansiones: 1\n",
581 | "Generados: 4\n",
582 | "Costo: 1\n",
583 | "Tiempo: 0.00\n",
584 | "Solucion*-***************************************\n",
585 | "\n",
586 | "| 3| 1| 2|\n",
587 | "| | 4| 5|\n",
588 | "| 6| 7| 8|\n",
589 | "-down->\n",
590 | "| | 1| 2|\n",
591 | "| 3| 4| 5|\n",
592 | "| 6| 7| 8|\n",
593 | "\n"
594 | ]
595 | }
596 | ]
597 | },
598 | {
599 | "cell_type": "markdown",
600 | "source": [
601 | "# Preguntas:\n",
602 | "- La solución encontrada es la solución óptima (no existe otra solución con menor costo)? ¿Por que? Demuestrelo.\n",
603 | "- Convierta la clase BrFS a la clase DFS (Depth-First Search [Búsqueda en profundidad]) y al la clase Dijkstra (que implementa el algoritmo de Dijkstra). \n",
604 | "- ¿La solución encontrada por DFS es la óptima? ¿Por que? Demuestrelo.\n",
605 | "- ¿El algoritmo de Dijkstra realiza el mismo procedimiento y esfuerzo (cantidad de expansiones) que el algoritmo BFS? ¿Por que?"
606 | ],
607 | "metadata": {
608 | "id": "VmT2jgkjrXGf"
609 | }
610 | }
611 | ]
612 | }
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/README.md:
--------------------------------------------------------------------------------
1 | # Algoritmos de búsqueda
2 |
3 | 
4 | 
5 |
6 |
7 | Partes fundamentales de un algoritmo de búsqueda:
8 | - `Open` list: Lista de estados abiertos (generados pero no expandidos). Cola de prioridad
9 | - `Close` list: Lista de estados cerrados (ya expandidos). Tabla hash.
10 | - `s` y `u`: Estados. Representan un estado del problema en un momento determinado.
11 | - `Goal()`: Función que recibe un estado y determina si corresponde a un estado objetivo.
12 | - `Succ()`: Función que recibe un estado `s` y genera los estados sucesores. Los estados sucesores son todos aquellos estados $v \in V$ que derivan de aplicar todas las acciones disponibles.
13 | - `Ìmprove(u,v)`: Agrega cada estado sucesor a la lista de `Open`, sí corresponde.
14 |
15 |
16 | Bibliografia:
17 | Edelkamp, S., & Schrodl, S. (2011). Heuristic search: theory and applications. Elsevier.
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/BrFS.py:
--------------------------------------------------------------------------------
1 | from node import Node
2 | import time
3 | from open_list import OpenList_BrFS
4 |
5 | class BrFS:
6 | def __init__(self, initial_state):
7 | self.expansions = 0
8 | #self.generated = 0 # es la lista de estados generados OPEN U CLOSE
9 | self.initial_state = initial_state
10 | self.solution = None
11 | self.open = OpenList_BrFS()
12 | self.generated = {}
13 |
14 |
15 |
16 | def search(self):
17 | self.start_time = time.process_time()
18 |
19 | initial_node = Node(self.initial_state)
20 | initial_node.g = 0
21 | self.open.insert(initial_node)
22 | self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde
23 |
24 | while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones)
25 | n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad))
26 |
27 | if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto)
28 | self.end_time = time.process_time()
29 | self.solution = n # Define el estado extraido como solución (para reconstruirlo luego)
30 | return n
31 | succ = n.state.successors() # Genera los sucesores
32 | self.expansions += 1 # Aumenta en 1 las expansiones
33 | for child_state, action, cost in succ: # Por cada uno de los estados sucesores
34 | child_node = self.generated.get(child_state) # Si no existe en generados retorna 0 (false)
35 | path_cost = n.g + cost # costo del camino encontrado hasta child_state
36 | if child_node is None : # si el estado no existe en OPEN U CLOSE
37 | child_node = Node(child_state, n) # creamos el nodo de child_state
38 | self.generated[child_state] = child_node # lo agregamos a generados
39 | child_node.action = action # definimos el nombre de la acción del nodo
40 | child_node.parent = n # definimos el padre
41 | child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion
42 | self.open.insert(child_node) # agrega el nodo a la OPEN
43 |
44 | self.end_time = time.process_time()
45 | print("No solution found") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución.
46 | return None
47 |
48 |
49 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/__pycache__/BrFS.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/BrFS.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/__pycache__/node.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/node.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/__pycache__/open_list.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/open_list.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/__pycache__/puzzle.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/puzzle.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/node.py:
--------------------------------------------------------------------------------
1 | class Node:
2 | def __init__(self, search_state, parent=None, action=''):
3 | self.state = search_state
4 | self.parent = parent # Es el estado padre.
5 | if parent: # compatibilidad con DFS/BrFS
6 | self.depth = parent.depth + 1
7 | else:
8 | self.depth = 0
9 | self.action = action # es el nombre de la accion
10 | #self.heap_index = 0
11 |
12 | def __repr__(self):
13 | return self.state.__repr__()
14 |
15 | def trace(self): # reconstruye la solución
16 | s = ''
17 | if self.parent:
18 | s = self.parent.trace()
19 | s += '-' + self.action + '->'
20 | s += str(self.state)
21 | return s
22 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/open_list.py:
--------------------------------------------------------------------------------
1 | import heapq
2 | from collections import deque
3 |
4 | class OpenList_BrFS:
5 | # Inicia una lista vacia
6 | def __init__(self):
7 | self.items = deque([])
8 |
9 | # La cantidad de elementos en el heap
10 | @staticmethod
11 | def size(self):
12 | return len(self.items)
13 |
14 | # Retorna el mejor elemento del heap
15 | def top(self):
16 | if self.size == 0:
17 | return None
18 | else:
19 | return self.items[0]
20 |
21 | # Retorna el primer elemento y lo elimina
22 | def extract(self):
23 | if len(self.items):
24 | return self.items.popleft()
25 | else :
26 | None
27 |
28 | # Inserta un elemento en el heap
29 | def insert(self, element):
30 | self.items.append(element)
31 |
32 | # Verifica si esta vacia
33 | def is_empty(self):
34 | return self.size == 0
35 |
36 |
37 | class OpenList:
38 | # Inicia una lista vacia
39 | def __init__(self):
40 | self.items = []
41 |
42 | # La cantidad de elementos en el heap
43 | @staticmethod
44 | def size(self):
45 | return len(self.items)
46 |
47 | # Retorna el mejor elemento del heap
48 | def top(self):
49 | if self.size == 0:
50 | return None
51 | else:
52 | return self.items[0]
53 | # Retorna el mejor elemento del heap y lo elimina
54 | def extract(self):
55 | if len(self.items):
56 | return heapq.heappop(self.items)
57 | else :
58 | None
59 |
60 | # Inserta un elemento en el heap
61 | def insert(self, element):
62 | heapq.heappush(self.items, element)
63 |
64 | # Verifica si esta vacia
65 | def is_empty(self):
66 | return self.size == 0
67 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/problems_r8.txt:
--------------------------------------------------------------------------------
1 | 00 4 7 5 0 8 2 6 1 3
2 | 01 6 8 7 4 3 2 1 5 0
3 | 02 0 6 7 1 2 4 3 8 5
4 | 03 0 1 8 7 2 4 5 6 3
5 | 04 5 0 8 7 2 4 6 1 3
6 | 05 0 4 6 2 1 5 3 8 7
7 | 06 0 2 8 4 5 1 7 6 3
8 | 07 2 3 8 0 4 1 6 7 5
9 | 08 5 7 3 0 2 8 4 1 6
10 | 09 0 4 2 1 3 8 6 5 7
11 | 10 4 5 8 1 3 0 6 7 2
12 | 11 3 8 4 7 5 2 6 1 0
13 | 12 2 1 5 0 6 8 7 3 4
14 | 13 4 8 2 5 6 0 7 1 3
15 | 14 4 6 2 3 7 0 5 1 8
16 | 15 2 4 7 3 5 0 1 8 6
17 | 16 4 5 1 8 7 3 0 2 6
18 | 17 7 6 3 1 5 4 2 0 8
19 | 18 3 7 8 6 5 0 4 2 1
20 | 19 0 1 8 5 2 7 4 6 3
21 | 20 1 6 5 3 4 7 2 8 0
22 | 21 2 4 1 0 6 5 3 7 8
23 | 22 4 2 0 5 8 1 7 3 6
24 | 23 7 1 5 8 2 3 6 0 4
25 | 24 4 5 6 8 1 3 2 0 7
26 | 25 7 1 5 4 0 6 3 2 8
27 | 26 3 6 2 5 7 4 1 0 8
28 | 27 6 3 7 0 2 4 5 1 8
29 | 28 7 2 8 6 0 4 3 5 1
30 | 29 6 5 4 1 8 7 3 0 2
31 | 30 0 3 7 2 8 5 6 1 4
32 | 31 0 8 1 7 5 4 3 2 6
33 | 32 8 5 2 0 4 1 7 3 6
34 | 33 2 7 3 1 5 4 0 6 8
35 | 34 0 5 7 8 2 6 3 4 1
36 | 35 5 1 3 0 8 6 7 4 2
37 | 36 5 7 1 6 3 4 2 8 0
38 | 37 0 2 3 7 4 1 8 6 5
39 | 38 1 2 4 7 8 5 3 6 0
40 | 39 3 8 7 2 4 1 6 5 0
41 | 40 1 4 2 6 0 5 8 7 3
42 | 41 8 5 7 4 2 1 3 0 6
43 | 42 5 7 8 1 0 4 3 6 2
44 | 43 8 3 2 0 7 1 6 4 5
45 | 44 5 2 3 7 6 4 0 1 8
46 | 45 1 2 0 5 4 7 3 8 6
47 | 46 5 3 2 7 1 0 8 4 6
48 | 47 6 7 8 1 0 3 2 4 5
49 | 48 2 3 0 5 6 7 1 4 8
50 | 49 4 0 2 1 5 3 8 7 6
51 | 50 0 7 5 2 6 8 1 4 3
52 | 51 3 6 7 5 2 0 8 1 4
53 | 52 3 0 1 7 8 5 4 6 2
54 | 53 4 6 8 0 3 1 5 7 2
55 | 54 3 7 2 8 1 6 0 4 5
56 | 55 0 1 6 3 8 2 7 5 4
57 | 56 3 7 5 4 1 0 2 6 8
58 | 57 3 7 5 1 0 4 8 6 2
59 | 58 6 7 8 0 3 1 4 2 5
60 | 59 2 5 8 3 1 0 7 4 6
61 | 60 0 7 8 5 1 2 4 6 3
62 | 61 3 4 1 0 6 5 7 2 8
63 | 62 1 8 2 3 4 7 5 0 6
64 | 63 2 5 8 0 6 4 1 3 7
65 | 64 3 6 8 5 0 2 7 4 1
66 | 65 5 4 0 1 7 6 2 3 8
67 | 66 0 7 2 1 4 8 3 6 5
68 | 67 2 7 4 8 3 6 0 5 1
69 | 68 3 1 8 4 7 2 6 5 0
70 | 69 6 8 4 1 5 0 7 2 3
71 | 70 8 7 5 0 1 3 4 6 2
72 | 71 0 1 6 7 3 5 4 2 8
73 | 72 1 0 6 7 5 3 4 8 2
74 | 73 1 6 8 3 7 2 0 5 4
75 | 74 0 3 4 8 7 2 1 5 6
76 | 75 2 3 6 7 5 0 8 1 4
77 | 76 7 0 6 8 1 5 4 3 2
78 | 77 0 1 2 8 7 3 5 4 6
79 | 78 3 2 4 1 5 7 8 0 6
80 | 79 0 6 1 7 3 2 5 8 4
81 | 80 7 1 5 8 0 2 3 6 4
82 | 81 6 0 4 2 1 5 8 3 7
83 | 82 6 4 2 7 5 0 8 1 3
84 | 83 8 4 5 2 1 7 3 0 6
85 | 84 1 8 6 0 5 7 3 4 2
86 | 85 7 2 0 1 8 5 3 6 4
87 | 86 7 5 8 4 2 6 3 1 0
88 | 87 6 3 4 7 1 8 2 0 5
89 | 88 2 5 3 6 0 4 8 1 7
90 | 89 5 3 2 4 7 6 0 8 1
91 | 90 6 5 1 2 7 8 0 4 3
92 | 91 3 6 1 7 4 5 8 0 2
93 | 92 1 3 0 2 7 6 5 8 4
94 | 93 0 5 8 1 6 3 4 7 2
95 | 94 0 1 4 5 7 8 6 2 3
96 | 95 3 4 8 6 1 7 2 5 0
97 | 96 1 0 3 2 8 4 6 5 7
98 | 97 1 2 0 7 3 8 5 4 6
99 | 98 8 5 0 1 2 4 3 6 7
100 | 99 0 6 5 1 8 7 3 4 2
101 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/puzzle.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import copy
3 | import numpy as np
4 |
5 |
6 | class Puzzle:
7 | goal8 = list(range(9))
8 | def __init__(self, board=None, blank=-1):
9 | if not board:
10 | self.x = 3
11 | self.size = 9
12 | self.board = [i for i in range(0, self.size)]
13 | self.blank = 0
14 | else:
15 | self.board = board
16 | if len(self.board) == 9:
17 | self.x = 3
18 | self.size = 9
19 | else:
20 | print('puzzle size not supported')
21 | sys.exit(1)
22 | if blank == -1:
23 | self.blank = board.index(0)
24 |
25 |
26 | def __hash__(self):
27 | return hash(tuple(self.board))
28 |
29 | def __eq__(self, other):
30 | return self.board == other.board
31 |
32 | def __repr__(self):
33 | def tostr(d):
34 | if d > 0:
35 | return "%2d" % (d)
36 | else:
37 | return " "
38 | s = '\n'
39 | for i in range(0, self.x):
40 | s += "|"
41 | s += "|".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]])
42 | s += "|\n"
43 | return s
44 |
45 | def successors(self):
46 | '''
47 | Crea una lista de tuplas de la forma (estado, accion, costo)
48 | donde estado es el estado sucesor de self que se genera al ejecutar
49 | accion (un string) y costo (un numero real) es el costo de accion
50 | '''
51 | def create_child(newblank):
52 | child = copy.deepcopy(self)
53 | child.blank = newblank
54 | child.board[child.blank] = 0
55 | child.board[self.blank] = self.board[newblank]
56 | return child
57 |
58 | succ = []
59 | if self.blank > self.x - 1:
60 | c = create_child(self.blank-self.x)
61 | succ.append((c, 'down', 1))
62 | if self.blank % self.x > 0:
63 | c = create_child(self.blank-1)
64 | succ.append((c, 'right', 1))
65 | if self.blank % self.x < self.x - 1:
66 | c = create_child(self.blank+1)
67 | succ.append((c, 'left', 1))
68 | if self.blank < self.size - self.x:
69 | c = create_child(self.blank+self.x)
70 | succ.append((c, 'up', 1))
71 | return succ
72 |
73 | def is_goal(self):
74 | return Puzzle.goal8 == self.board
75 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/code/test_brfs_puzzle.py:
--------------------------------------------------------------------------------
1 | from puzzle import Puzzle
2 | from BrFS import BrFS
3 | from os.path import join
4 |
5 | def load_problems(problems): ## carga los problemas en memoria
6 | puzzles = list()
7 | with open('problems_r8.txt') as f:
8 | for line in f:
9 | puzzle = line.rstrip().split(' ', 1)[1]
10 | problems.append(Puzzle([int(x) for x in puzzle.split(' ')]))
11 | puzzles.append(puzzle)
12 |
13 |
14 |
15 | show_solutions = False # mostramos las soluciones?
16 |
17 | problems = []
18 | load_problems(problems)
19 |
20 | total_time = 0
21 | total_cost = 0
22 | total_expansions = 0
23 | num_problems = 3 # len(problems) # cambiar si quieres ejecutar sobre todos los problemas
24 |
25 |
26 | print('prob\texp\tgenerated\t|sol|\ttiempo\n')
27 |
28 | for prob in range(0, num_problems):
29 | init = problems[prob]
30 | s = BrFS(init) # agregar un tercer parámetro una vez que lo hayas transformado en Weighted A*
31 | result = s.search()
32 | print('%5d%10d%10d%10d%10.2f' % (prob+1, s.expansions, len(s.generated), result.g, s.end_time-s.start_time ))
33 | total_time += s.end_time - s.start_time
34 | total_cost += result.g
35 | total_expansions += s.expansions
36 |
37 | if show_solutions:
38 | print(result.trace())
39 |
40 |
41 | print('Tiempo total: %.2f'%(total_time))
42 | print('Expansiones totales: %d'%(total_expansions))
43 | print('Costo total: %d'%(total_cost))
44 |
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/img/alg2.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/img/alg2.1.png
--------------------------------------------------------------------------------
/1 Search/1 Blind Search/img/alg2.3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/img/alg2.3.png
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/BrFS.py:
--------------------------------------------------------------------------------
1 | from node import Node
2 | import time
3 | from open_list import OpenList
4 |
5 | class BrFS:
6 | def __init__(self, initial_state):
7 | self.expansions = 0
8 | #self.generated = 0 # es la lista de estados generados OPEN U CLOSE
9 | self.initial_state = initial_state
10 | self.solution = None
11 | self.open = OpenList()
12 | self.generated = {}
13 |
14 |
15 |
16 | def search(self):
17 | self.start_time = time.process_time()
18 |
19 | #self.expansions = 0
20 | #self.solution = None
21 | initial_node = Node(self.initial_state)
22 | initial_node.g = 0
23 | initial_node.key = initial_node.g
24 |
25 | self.open.insert(initial_node)
26 | self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde
27 |
28 | while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones)
29 | n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad))
30 |
31 | if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto)
32 | self.end_time = time.process_time()
33 | self.solution = n # Define el estado extraido como solución (para reconstruirlo luego)
34 | return n
35 | succ = n.state.successors() # Genera los sucesores
36 | self.expansions += 1 # Aumenta en 1 las expansiones
37 | for child_state, action, cost in succ: # Por cada uno de los estados sucesores
38 | child_node = self.generated.get(child_state) # Lo agrega a generados
39 | path_cost = n.g + cost # costo del camino encontrado hasta child_state
40 | if child_node is None : # si el estado no existe en OPEN U CLOSE
41 | child_node = Node(child_state, n) # creamos el nodo de child_state
42 | self.generated[child_state] = child_node # lo agregamos a generados
43 | child_node.action = action # definimos el nombre de la acción del nodo
44 | child_node.parent = n # definimos el padre
45 | child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion
46 | child_node.key = child_node.g # actualizamos la key (que ordenará la OPEN LIST)
47 | self.open.insert(child_node) # agrega el nodo a la OPEN
48 |
49 | self.end_time = time.process_time()
50 | print("No solution found") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución.
51 | return None
52 |
53 |
54 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/README.md:
--------------------------------------------------------------------------------
1 | # Algoritmo A*
2 |
3 | El material y pseudocodigo están en el archivo 2_A_.ipynb
4 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/__pycache__/BrFS.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/BrFS.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/__pycache__/node.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/node.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/__pycache__/open_list.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/open_list.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/__pycache__/puzzle.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/puzzle.cpython-38.pyc
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/node.py:
--------------------------------------------------------------------------------
1 | class Node:
2 | def __init__(self, search_state, parent=None, action=''):
3 | self.state = search_state
4 | self.parent = parent # Es el estado padre.
5 | if parent: # compatibilidad con DFS/BrFS
6 | self.depth = parent.depth + 1
7 | else:
8 | self.depth = 0
9 | self.action = action # es el nombre de la accion
10 | self.key = -1 # el el criterio de ordenamiento del nodo
11 | self.g = 0 # corresponde al costo del camino
12 | self.heap_index = 0
13 |
14 | def __repr__(self):
15 | return self.state.__repr__()
16 |
17 | def __gt__(self, other):
18 | if self.key > other.key:
19 | return True
20 | else :
21 | return False
22 |
23 | def __lt__(self, other):
24 | if self.key < other.key:
25 | return True
26 | else :
27 | return False
28 |
29 | def trace(self):
30 | s = ''
31 | if self.parent:
32 | s = self.parent.trace()
33 | s += '-' + self.action + '->'
34 | s += str(self.state)
35 | return s
36 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/open_list.py:
--------------------------------------------------------------------------------
1 | import heapq
2 |
3 | class OpenList:
4 | # Inicia una lista vacia
5 | def __init__(self):
6 | self.items = []
7 |
8 | # La cantidad de elementos en el heap
9 | @staticmethod
10 | def size(self):
11 | return len(self.items)
12 |
13 | # Retorna el mejor elemento del heap
14 | def top(self):
15 | if self.size == 0:
16 | return None
17 | else:
18 | return self.items[0]
19 | # Retorna el mejor elemento del heap y lo elimina
20 | def extract(self):
21 | if len(self.items):
22 | return heapq.heappop(self.items)
23 | else :
24 | None
25 |
26 | # Inserta un elemento en el heap
27 | def insert(self, element):
28 | heapq.heappush(self.items, element)
29 |
30 | # Verifica si esta vacia
31 | def is_empty(self):
32 | return self.size == 0
33 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/problems_r8.txt:
--------------------------------------------------------------------------------
1 | 00 4 7 5 0 8 2 6 1 3
2 | 01 6 8 7 4 3 2 1 5 0
3 | 02 0 6 7 1 2 4 3 8 5
4 | 03 0 1 8 7 2 4 5 6 3
5 | 04 5 0 8 7 2 4 6 1 3
6 | 05 0 4 6 2 1 5 3 8 7
7 | 06 0 2 8 4 5 1 7 6 3
8 | 07 2 3 8 0 4 1 6 7 5
9 | 08 5 7 3 0 2 8 4 1 6
10 | 09 0 4 2 1 3 8 6 5 7
11 | 10 4 5 8 1 3 0 6 7 2
12 | 11 3 8 4 7 5 2 6 1 0
13 | 12 2 1 5 0 6 8 7 3 4
14 | 13 4 8 2 5 6 0 7 1 3
15 | 14 4 6 2 3 7 0 5 1 8
16 | 15 2 4 7 3 5 0 1 8 6
17 | 16 4 5 1 8 7 3 0 2 6
18 | 17 7 6 3 1 5 4 2 0 8
19 | 18 3 7 8 6 5 0 4 2 1
20 | 19 0 1 8 5 2 7 4 6 3
21 | 20 1 6 5 3 4 7 2 8 0
22 | 21 2 4 1 0 6 5 3 7 8
23 | 22 4 2 0 5 8 1 7 3 6
24 | 23 7 1 5 8 2 3 6 0 4
25 | 24 4 5 6 8 1 3 2 0 7
26 | 25 7 1 5 4 0 6 3 2 8
27 | 26 3 6 2 5 7 4 1 0 8
28 | 27 6 3 7 0 2 4 5 1 8
29 | 28 7 2 8 6 0 4 3 5 1
30 | 29 6 5 4 1 8 7 3 0 2
31 | 30 0 3 7 2 8 5 6 1 4
32 | 31 0 8 1 7 5 4 3 2 6
33 | 32 8 5 2 0 4 1 7 3 6
34 | 33 2 7 3 1 5 4 0 6 8
35 | 34 0 5 7 8 2 6 3 4 1
36 | 35 5 1 3 0 8 6 7 4 2
37 | 36 5 7 1 6 3 4 2 8 0
38 | 37 0 2 3 7 4 1 8 6 5
39 | 38 1 2 4 7 8 5 3 6 0
40 | 39 3 8 7 2 4 1 6 5 0
41 | 40 1 4 2 6 0 5 8 7 3
42 | 41 8 5 7 4 2 1 3 0 6
43 | 42 5 7 8 1 0 4 3 6 2
44 | 43 8 3 2 0 7 1 6 4 5
45 | 44 5 2 3 7 6 4 0 1 8
46 | 45 1 2 0 5 4 7 3 8 6
47 | 46 5 3 2 7 1 0 8 4 6
48 | 47 6 7 8 1 0 3 2 4 5
49 | 48 2 3 0 5 6 7 1 4 8
50 | 49 4 0 2 1 5 3 8 7 6
51 | 50 0 7 5 2 6 8 1 4 3
52 | 51 3 6 7 5 2 0 8 1 4
53 | 52 3 0 1 7 8 5 4 6 2
54 | 53 4 6 8 0 3 1 5 7 2
55 | 54 3 7 2 8 1 6 0 4 5
56 | 55 0 1 6 3 8 2 7 5 4
57 | 56 3 7 5 4 1 0 2 6 8
58 | 57 3 7 5 1 0 4 8 6 2
59 | 58 6 7 8 0 3 1 4 2 5
60 | 59 2 5 8 3 1 0 7 4 6
61 | 60 0 7 8 5 1 2 4 6 3
62 | 61 3 4 1 0 6 5 7 2 8
63 | 62 1 8 2 3 4 7 5 0 6
64 | 63 2 5 8 0 6 4 1 3 7
65 | 64 3 6 8 5 0 2 7 4 1
66 | 65 5 4 0 1 7 6 2 3 8
67 | 66 0 7 2 1 4 8 3 6 5
68 | 67 2 7 4 8 3 6 0 5 1
69 | 68 3 1 8 4 7 2 6 5 0
70 | 69 6 8 4 1 5 0 7 2 3
71 | 70 8 7 5 0 1 3 4 6 2
72 | 71 0 1 6 7 3 5 4 2 8
73 | 72 1 0 6 7 5 3 4 8 2
74 | 73 1 6 8 3 7 2 0 5 4
75 | 74 0 3 4 8 7 2 1 5 6
76 | 75 2 3 6 7 5 0 8 1 4
77 | 76 7 0 6 8 1 5 4 3 2
78 | 77 0 1 2 8 7 3 5 4 6
79 | 78 3 2 4 1 5 7 8 0 6
80 | 79 0 6 1 7 3 2 5 8 4
81 | 80 7 1 5 8 0 2 3 6 4
82 | 81 6 0 4 2 1 5 8 3 7
83 | 82 6 4 2 7 5 0 8 1 3
84 | 83 8 4 5 2 1 7 3 0 6
85 | 84 1 8 6 0 5 7 3 4 2
86 | 85 7 2 0 1 8 5 3 6 4
87 | 86 7 5 8 4 2 6 3 1 0
88 | 87 6 3 4 7 1 8 2 0 5
89 | 88 2 5 3 6 0 4 8 1 7
90 | 89 5 3 2 4 7 6 0 8 1
91 | 90 6 5 1 2 7 8 0 4 3
92 | 91 3 6 1 7 4 5 8 0 2
93 | 92 1 3 0 2 7 6 5 8 4
94 | 93 0 5 8 1 6 3 4 7 2
95 | 94 0 1 4 5 7 8 6 2 3
96 | 95 3 4 8 6 1 7 2 5 0
97 | 96 1 0 3 2 8 4 6 5 7
98 | 97 1 2 0 7 3 8 5 4 6
99 | 98 8 5 0 1 2 4 3 6 7
100 | 99 0 6 5 1 8 7 3 4 2
101 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/puzzle.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import copy
3 | import numpy as np
4 |
5 |
6 | class Puzzle:
7 | goal8 = list(range(9))
8 | def __init__(self, board=None, blank=-1):
9 | if not board:
10 | self.x = 3
11 | self.size = 9
12 | self.board = [i for i in range(0, self.size)]
13 | self.blank = 0
14 | else:
15 | self.board = board
16 | if len(self.board) == 9:
17 | self.x = 3
18 | self.size = 9
19 | else:
20 | print('puzzle size not supported')
21 | sys.exit(1)
22 | if blank == -1:
23 | self.blank = board.index(0)
24 |
25 |
26 | def __hash__(self):
27 | return hash(tuple(self.board))
28 |
29 | def __eq__(self, other):
30 | return self.board == other.board
31 |
32 | def __repr__(self):
33 | def tostr(d):
34 | if d > 0:
35 | return "%2d" % (d)
36 | else:
37 | return " "
38 | s = '\n'
39 | for i in range(0, self.x):
40 | s += "|"
41 | s += "|".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]])
42 | s += "|\n"
43 | return s
44 |
45 | def successors(self):
46 | '''
47 | Crea una lista de tuplas de la forma (estado, accion, costo)
48 | donde estado es el estado sucesor de self que se genera al ejecutar
49 | accion (un string) y costo (un numero real) es el costo de accion
50 | '''
51 | def create_child(newblank):
52 | child = copy.deepcopy(self)
53 | child.blank = newblank
54 | child.board[child.blank] = 0
55 | child.board[self.blank] = self.board[newblank]
56 | return child
57 |
58 | succ = []
59 | if self.blank > self.x - 1:
60 | c = create_child(self.blank-self.x)
61 | succ.append((c, 'down', 1))
62 | if self.blank % self.x > 0:
63 | c = create_child(self.blank-1)
64 | succ.append((c, 'right', 1))
65 | if self.blank % self.x < self.x - 1:
66 | c = create_child(self.blank+1)
67 | succ.append((c, 'left', 1))
68 | if self.blank < self.size - self.x:
69 | c = create_child(self.blank+self.x)
70 | succ.append((c, 'up', 1))
71 | return succ
72 |
73 | def is_goal(self):
74 | return Puzzle.goal8 == self.board
75 |
--------------------------------------------------------------------------------
/1 Search/2 Informed Search/test_brfs_puzzle.py:
--------------------------------------------------------------------------------
1 | from puzzle import Puzzle
2 | from BrFS import BrFS
3 | from os.path import join
4 |
5 | def load_problems(problems): ## carga los problemas en memoria
6 | puzzles = list()
7 | with open('problems_r8.txt') as f:
8 | for line in f:
9 | puzzle = line.rstrip().split(' ', 1)[1]
10 | problems.append(Puzzle([int(x) for x in puzzle.split(' ')]))
11 | puzzles.append(puzzle)
12 |
13 |
14 |
15 | show_solutions = False # mostramos las soluciones?
16 |
17 | problems = []
18 | load_problems(problems)
19 |
20 | total_time = 0
21 | total_cost = 0
22 | total_expansions = 0
23 | num_problems = 3 # len(problems) # cambiar si quieres ejecutar sobre todos los problemas
24 |
25 |
26 | print('prob\texp\tgenerated\t|sol|\ttiempo\n')
27 |
28 | for prob in range(0, num_problems):
29 | init = problems[prob]
30 | s = BrFS(init) # agregar un tercer parámetro una vez que lo hayas transformado en Weighted A*
31 | result = s.search()
32 | print('%5d%10d%10d%10d%10.2f' % (prob+1, s.expansions, len(s.generated), result.g, s.end_time-s.start_time ))
33 | total_time += s.end_time - s.start_time
34 | total_cost += result.g
35 | total_expansions += s.expansions
36 |
37 | if show_solutions:
38 | print(result.trace())
39 |
40 |
41 | print('Tiempo total: %.2f'%(total_time))
42 | print('Expansiones totales: %d'%(total_expansions))
43 | print('Costo total: %d'%(total_cost))
44 |
--------------------------------------------------------------------------------
/2 Programacion Logica/1.swinb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ### The SWISH hangout room
5 |
6 | You can add messages to this room from here or using the __Broadcast to hangout__ option from the __Send__ button on any other file. In the latter case the message is added to this room with a link to the files.
7 |
8 |
9 |
10 | % Hecho
11 | perro(fido).
12 | perro(firulais).
13 | perro(bob).
14 |
15 | gato(felix).
16 |
17 | padre(fido, firulais).
18 | padre(fido, bob).
19 |
20 | % Reglas
21 | %animal(_). %∀x animal(x) % no es correcto, todo es un animal
22 |
23 | animal(X):- perro(X) ; gato(X). %∀x perro(x) => animal(x)
24 | %animal(X):- gato(X). %∀x perro(x) => animal(x)
25 |
26 |
27 |
28 | perro(fido)
29 |
30 |
31 |
32 | padre(fido,X)
33 |
34 |
35 |
36 | animal(felix)
37 |
38 |
39 |
40 | # La ejecucicón de una consulta es la unificación sucesiva de la expresion de la consulta con cada linea del programa
41 |
42 |
43 |
44 | [A,B,C,D] = [1,2,3,4].
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/2 Programacion Logica/2.swinb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | :- dynamic numero/2.
5 | numero(1, "uno").
6 | numero(2, "dos").
7 | numero(3, "tres").
8 |
9 | n(par) :- numero(2,_); numero(4,_).
10 | n(impar) :- numero(1,_);numero(3,_).
11 |
12 | preguntar_numeros :-
13 | write("Ingrese un numero"),nl,
14 | read(N),
15 | write("El numero ingresado es"),write(N),
16 | write("Ingrese el numero en palabras"),
17 | read(N2),
18 | write("En palabras es"), write(N2),
19 | retractall(numero(_,_)),
20 | asserta(numero(N, N2)),
21 | numero(5,P),
22 | write("Ingresado es: "),write(P),
23 | funcion2,
24 | n(PPP),
25 | write(PPP).
26 |
27 | funcion2 :-
28 | write("Es una nueva funcion"),nl,nl.
29 |
30 |
31 |
32 | preguntar_numeros.
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/2 Programacion Logica/3.swinb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | :- dynamic numero/2.
5 | numero(1, uno).
6 | numero(2, dos).
7 | numero(3, tres).
8 |
9 | traductor:-
10 | write("ingrese un numero 1 2 o 3"), nl,
11 | read(Numero),
12 | numero(Numero,F),
13 | asserta(numero(10,"soy el 10")),
14 | numero(2,HH),
15 | nl,nl,write(HH),nl,nl,
16 | write(Numero),write(F),
17 | write("El numero traducido es"),nl,
18 | n(P),
19 | write(P).
20 |
21 |
22 | n(one) :- numero(1,_).
23 | n(two) :- numero(2,_).
24 | n(three):- numero(3,_).
25 |
26 |
27 |
28 | traductor.
29 |
30 |
31 |
32 | %:- dynamic numero/2.
33 | numero(1, uno).
34 | numero(2, dos).
35 | numero(3, tres).
36 |
37 |
38 |
39 | traductor2:-
40 | write("ingrese un numero 1 2 o 3"), nl,
41 |
42 | %numero(Numero,F),
43 | %retractall(numero(_,_)),
44 | read(Numero),
45 | numero(Numero,_),
46 | asserta(numero(Numero,_)),
47 | write("El numero traducido es"),nl,
48 | n(P),
49 | write(P).
50 |
51 | n(one) :- numero(1,_).
52 | n(two) :- numero(2,_).
53 | n(three):- numero(3,_).
54 |
55 |
56 |
57 | traductor2
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/3 Machine Learning/1 regresion.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": []
7 | },
8 | "kernelspec": {
9 | "name": "python3",
10 | "display_name": "Python 3"
11 | },
12 | "language_info": {
13 | "name": "python"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "source": [
20 | "# shorturl.at/mqvyR"
21 | ],
22 | "metadata": {
23 | "id": "jLXrQemON4_Z"
24 | }
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {
30 | "colab": {
31 | "base_uri": "https://localhost:8080/"
32 | },
33 | "id": "KLtdTFJC_IQL",
34 | "outputId": "3a39d9b4-0995-49b6-88e6-5902b2affb6b"
35 | },
36 | "outputs": [
37 | {
38 | "output_type": "stream",
39 | "name": "stdout",
40 | "text": [
41 | "El tamaño de los datos (569, 30)\n",
42 | "El tamaño de las etiquetas (569,)\n"
43 | ]
44 | }
45 | ],
46 | "source": [
47 | "from sklearn.datasets import load_breast_cancer\n",
48 | "\n",
49 | "data = load_breast_cancer()\n",
50 | "\n",
51 | "print(\"El tamaño de los datos\", data.data.shape)\n",
52 | "print(\"El tamaño de las etiquetas\", data.target.shape)"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "source": [
58 | "from sklearn.model_selection import train_test_split\n",
59 | "\n",
60 | "x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.25)\n",
61 | "\n",
62 | "print(\"Train size:\", x_train.shape)\n",
63 | "print(\"Test size:\", x_test.shape)\n",
64 | "print(\"Label train\", y_train.shape)\n",
65 | "print(\"Label test\", y_test.shape)"
66 | ],
67 | "metadata": {
68 | "colab": {
69 | "base_uri": "https://localhost:8080/"
70 | },
71 | "id": "I2g4F8BaFHQk",
72 | "outputId": "ea9f2d1c-d3ae-4640-9f39-3f3c7b83932f"
73 | },
74 | "execution_count": null,
75 | "outputs": [
76 | {
77 | "output_type": "stream",
78 | "name": "stdout",
79 | "text": [
80 | "Train size: (426, 30)\n",
81 | "Test size: (143, 30)\n",
82 | "Label train (426,)\n",
83 | "Label test (143,)\n"
84 | ]
85 | }
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "source": [
91 | "from sklearn.linear_model import LogisticRegression\n",
92 | "\n",
93 | "classifier = LogisticRegression(max_iter = 5000)\n",
94 | "classifier.fit(x_train, y_train)"
95 | ],
96 | "metadata": {
97 | "colab": {
98 | "base_uri": "https://localhost:8080/"
99 | },
100 | "id": "ava6C5XnG8-7",
101 | "outputId": "57de84b5-15e8-4554-89f4-d37fb2ca5943"
102 | },
103 | "execution_count": null,
104 | "outputs": [
105 | {
106 | "output_type": "execute_result",
107 | "data": {
108 | "text/plain": [
109 | "LogisticRegression(max_iter=5000)"
110 | ]
111 | },
112 | "metadata": {},
113 | "execution_count": 52
114 | }
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "source": [
120 | "predictions = classifier.predict(x_test)\n",
121 | "print(predictions)"
122 | ],
123 | "metadata": {
124 | "colab": {
125 | "base_uri": "https://localhost:8080/"
126 | },
127 | "id": "QX8kyyTvHh-z",
128 | "outputId": "49ce7346-ed53-475b-a7b8-a43e1d30a7a6"
129 | },
130 | "execution_count": null,
131 | "outputs": [
132 | {
133 | "output_type": "stream",
134 | "name": "stdout",
135 | "text": [
136 | "[1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1\n",
137 | " 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1\n",
138 | " 1 1 0 1 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0\n",
139 | " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 1 1 0 0 0 1 1 1 0 1 1 1 1]\n"
140 | ]
141 | }
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "source": [
147 | "# Para evaluar el modelo, utilizamos el accuracy (exactitud), es decir, el porcentaje\n",
148 | "# de veces que fue clasificado con la clase correcta.\n",
149 | "\n",
150 | "accuracy = classifier.score (x_test, y_test)\n",
151 | "print(accuracy)"
152 | ],
153 | "metadata": {
154 | "colab": {
155 | "base_uri": "https://localhost:8080/"
156 | },
157 | "id": "jwce_gOdH2VS",
158 | "outputId": "0b2f11b7-f8a3-4b1a-a0fc-2481b7f4d94e"
159 | },
160 | "execution_count": null,
161 | "outputs": [
162 | {
163 | "output_type": "stream",
164 | "name": "stdout",
165 | "text": [
166 | "0.972027972027972\n"
167 | ]
168 | }
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "source": [
174 | "from sklearn import metrics\n",
175 | "\n",
176 | "cm = metrics.confusion_matrix(y_test, predictions)\n",
177 | "print(cm)\n",
178 | "#en 143 datos"
179 | ],
180 | "metadata": {
181 | "colab": {
182 | "base_uri": "https://localhost:8080/"
183 | },
184 | "id": "LEx6a2uVLuiS",
185 | "outputId": "d28b2596-898d-4389-e16f-d0fb1066a76c"
186 | },
187 | "execution_count": null,
188 | "outputs": [
189 | {
190 | "output_type": "stream",
191 | "name": "stdout",
192 | "text": [
193 | "[[53 3]\n",
194 | " [ 1 86]]\n"
195 | ]
196 | }
197 | ]
198 | },
199 | {
200 | "cell_type": "markdown",
201 | "source": [
202 | "#MNIST\n",
203 | "\n",
204 | "Construya un clasificador multiclase para el conjunto de datos MNIST"
205 | ],
206 | "metadata": {
207 | "id": "yEgsoE3lNCVy"
208 | }
209 | },
210 | {
211 | "cell_type": "code",
212 | "source": [
213 | "from sklearn.datasets import load_digits\n",
214 | "digits = load_digits()"
215 | ],
216 | "metadata": {
217 | "id": "J3AAyvRJNRUc"
218 | },
219 | "execution_count": null,
220 | "outputs": []
221 | },
222 | {
223 | "cell_type": "code",
224 | "source": [
225 | "import numpy as np \n",
226 | "import matplotlib.pyplot as plt\n",
227 | "plt.figure(figsize=(20,4))\n",
228 | "\n",
229 | "for index, (image, label) in enumerate(zip(digits.data[0:5], digits.target[0:5])):\n",
230 | " plt.subplot(1, 5, index + 1)\n",
231 | " plt.imshow(np.reshape(image, (8,8)), cmap=plt.cm.gray)\n",
232 | " plt.title('Training: %i\\n' % label, fontsize = 20)"
233 | ],
234 | "metadata": {
235 | "colab": {
236 | "base_uri": "https://localhost:8080/",
237 | "height": 258
238 | },
239 | "id": "yCNDx0BZNdCb",
240 | "outputId": "10d3a65f-be64-47b8-d60f-8a6f8bb2a346"
241 | },
242 | "execution_count": null,
243 | "outputs": [
244 | {
245 | "output_type": "display_data",
246 | "data": {
247 | "text/plain": [
248 | ""
249 | ],
250 | "image/png": "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\n"
251 | },
252 | "metadata": {
253 | "needs_background": "light"
254 | }
255 | }
256 | ]
257 | }
258 | ]
259 | }
--------------------------------------------------------------------------------
/3 Machine Learning/3 clustering_Kmeans.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": []
7 | },
8 | "kernelspec": {
9 | "name": "python3",
10 | "display_name": "Python 3"
11 | },
12 | "language_info": {
13 | "name": "python"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "source": [
20 | "# shorturl.at/CXYZ4"
21 | ],
22 | "metadata": {
23 | "id": "uWUhSfng-w1Q"
24 | }
25 | },
26 | {
27 | "cell_type": "code",
28 | "source": [
29 | "import sys\n",
30 | "import sklearn\n",
31 | "import matplotlib\n",
32 | "import numpy as np"
33 | ],
34 | "metadata": {
35 | "id": "_GSrZpjPPFTy"
36 | },
37 | "execution_count": null,
38 | "outputs": []
39 | },
40 | {
41 | "cell_type": "code",
42 | "source": [
43 | "from keras.datasets import mnist\n",
44 | "\n",
45 | "(x_total, y_total), (_, _) = mnist.load_data()\n",
46 | "\n",
47 | "print('Training Data: {}'.format(x_total.shape))\n",
48 | "print('Training Labels: {}'.format(y_total.shape))"
49 | ],
50 | "metadata": {
51 | "colab": {
52 | "base_uri": "https://localhost:8080/"
53 | },
54 | "id": "edtUY4C0PFOf",
55 | "outputId": "dec654a9-682c-4197-a741-49894b25f1bb"
56 | },
57 | "execution_count": null,
58 | "outputs": [
59 | {
60 | "output_type": "stream",
61 | "name": "stdout",
62 | "text": [
63 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n",
64 | "11490434/11490434 [==============================] - 0s 0us/step\n",
65 | "Training Data: (60000, 28, 28)\n",
66 | "Training Labels: (60000,)\n"
67 | ]
68 | }
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "source": [
74 | "import numpy as np\n",
75 | "from sklearn.model_selection import train_test_split\n",
76 | "#from sklearn.datasets import load_digits\n",
77 | "\n",
78 | "#digits = load_digits()\n",
79 | "\n",
80 | "x_train, x_restante, y_train, y_restante = train_test_split(x_total, y_total, test_size=0.35, random_state=1)\n",
81 | "x_test, x_valid, y_test, y_valid = train_test_split(x_restante, y_restante, test_size=0.4285, random_state=1)\n",
82 | "\n",
83 | "print(x_train.shape)\n",
84 | "print(x_test.shape)\n",
85 | "print(x_valid.shape)"
86 | ],
87 | "metadata": {
88 | "colab": {
89 | "base_uri": "https://localhost:8080/"
90 | },
91 | "id": "3FfIjqRjRQCm",
92 | "outputId": "d693d5e1-a400-46b8-f75b-7acaa9c90a8e"
93 | },
94 | "execution_count": null,
95 | "outputs": [
96 | {
97 | "output_type": "stream",
98 | "name": "stdout",
99 | "text": [
100 | "(39000, 28, 28)\n",
101 | "(12001, 28, 28)\n",
102 | "(8999, 28, 28)\n"
103 | ]
104 | }
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "source": [
110 | "import matplotlib.pyplot as plt\n",
111 | "\n",
112 | "# python magic function\n",
113 | "%matplotlib inline"
114 | ],
115 | "metadata": {
116 | "id": "ceXJjXnCPFJL"
117 | },
118 | "execution_count": null,
119 | "outputs": []
120 | },
121 | {
122 | "cell_type": "code",
123 | "source": [
124 | "# create figure with 3x3 subplots using matplotlib.pyplot\n",
125 | "fig, axs = plt.subplots(3, 3, figsize = (12, 12))\n",
126 | "plt.gray()\n",
127 | "\n",
128 | "# loop through subplots and add mnist images\n",
129 | "for i, ax in enumerate(axs.flat):\n",
130 | " ax.imshow(x_train[i])\n",
131 | " ax.axis('off')\n",
132 | " ax.set_title('Number {}'.format(y_train[i]))\n",
133 | " \n",
134 | "# display the figure\n",
135 | "fig.show()\n"
136 | ],
137 | "metadata": {
138 | "colab": {
139 | "base_uri": "https://localhost:8080/",
140 | "height": 699
141 | },
142 | "id": "txC8iqDSPFGe",
143 | "outputId": "59c03d44-72d4-4d92-b842-8b020a75ec23"
144 | },
145 | "execution_count": null,
146 | "outputs": [
147 | {
148 | "output_type": "display_data",
149 | "data": {
150 | "text/plain": [
151 | ""
152 | ],
153 | "image/png": "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qimmAABUQTEFAKAKiikAAFVQTAEAqMLY4V7AYG277bZpNm7cuI6u+cc//jHNHnnkkY6uCfQ4++yz02wkv/K+nS222GK4l/CyannlPd1vwoQJA57T7vtyN7zyvt1JBAsWLEizbn/lfSfcMQUAoAqKKQAAVVBMAQCogmIKAEAVFFMAAKqgmAIAUIWuPy6qnaZpOpp35513ptmsWbM6XQ4QEfPnzx/uJVRns802G+4lwGJz6KGHDvcSFpkTTjih5fghhxySzpk3b16abb311mn2v//7v/1fWBdxxxQAgCoopgAAVEExBQCgCoopAABVUEwBAKiCYgoAQBW6/rioO+64I83+9re/pdnYsfmHPnHixDR729ve1nL8lltuSefssssuabYolFLSrNMjtDrx2GOPpdnll1++2NZBXXbbbbc0O+mkk9LsueeeWxTLAfg/VlhhhTQ7/vjj02yfffYZ8PXaZcsss0yajVTumAIAUAXFFACAKiimAABUQTEFAKAKiikAAFVQTAEAqELXHxf105/+NM1uvvnmNNtmm23SbIsttkiziy66qOX4nDlz0jlrr712mi0KtRwXtWDBgjR74IEH0uy8885LsxNOOGFQa2LotPuanz9/fpptvfXWaXbIIYek2Wmnnda/hXWh9ddff0ivd+mllw7p9WAk2njjjdPsC1/4Qprtueeei2A1vMgdUwAAqqCYAgBQBcUUAIAqKKYAAFRBMQUAoAqKKQAAVSjtjg8qpSy+s4UWgcMOOyzNTj311MW4ksWrluOiOvX888+n2W9+85uW4295y1uGfB1N0+SfyErVsmePO+64NPvsZz/b0TWvvPLKNPvxj3+cZrfeemtHj9eJdnvv3HPPTbONNtpowI/1xBNPpNnrX//6NGt3VFu367Y9W8t+XRSWX375NPvFL36RZptvvnnL8aeeeiqdM2PGjP4vrI/NNtsszSZMmNDRNTtx7bXXptnuu++eZu2OZOwG2X51xxQAgCoopgAAVEExBQCgCoopAABVUEwBAKiCYgoAQBVG9HFRe+21V5qdd955abbkkksuiuW0dNttt6XZkUce2dE1x4zJf95YuHBhR9fsxIYbbphm06ZN6+iaTz75ZMvxlVZaqaPrtdNtR89E1LNnl1pqqTS78MIL06zd0Sjdrt0xaEsssUSaZfv54YcfTuesscYa/V/YCNJte7aW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mtVy/Nprrx3yx4KXeuyxx9Jsv/32W4wrWbxe//rXp9m+++6bZr/85S9bju+5557pnHnz5vV/YaOAO6YAAFRBMQUAoAqKKQAAVVBMAQCogmIKAEAVFFMAAKrguCiAAVhhhRXS7BOf+MSQP97s2bOH/JpAe1/72tfS7L777kuzU089teX4k08+Oeg1jRbumAIAUAXFFACAKiimAABUQTEFAKAKiikAAFXwqnyAATjllFPSbIsttujomjfccEOafeADH+jomkDEUkstlWYTJkxIs7lz56bZHXfckWaXXHJJ/xZGyh1TAACqoJgCAFAFxfgj4aQAABclSURBVBQAgCoopgAAVEExBQCgCoopAABV6Irjonbeeec0W3311Yf88e655540u/7664f88TpRSkmzMWMG/vNGu+vBaLPccsul2WabbTbkj3fCCSek2UMPPTTkjwejxate9ao0u/XWW9Psne98Z5otit7B/+OOKQAAVVBMAQCogmIKAEAVFFMAAKqgmAIAUAXFFACAKnTFcVEHHnhgmu2xxx5D/nhz5sxJs7vvvnvA1zvqqKPS7LHHHkuz7bffPs1e97rXpdnChQv7t7A+mqYZ8BwYqXbdddc023TTTTu65nPPPZdmTz/9dEfXBCJWW221NDvuuOPS7MQTT0yz6667Ls1eeOGFfq2LzrhjCgBAFRRTAACqoJgCAFAFxRQAgCoopgAAVEExBQCgCqXdMUGllCrOEJo0aVKa/elPfxryxxszJu/rnRzFVNM67r///pbj7373u9M5M2fO7Oixul3TNGW41zBQtezZbrD00kun2YwZM9Ks3VFt7fziF79Isx133LGja/L3um3P2q9D45Of/GSafeUrX0mzm2++Oc222267NGt39Bv9l+1Xd0wBAKiCYgoAQBUUUwAAqqCYAgBQBcUUAIAqKKYAAFRh7HAvoD9mzZqVZuuuu25H1zzwwAPTrN3RSeuvv35Hj1eLq666quX4aD0SitHrbW97W5p1eiTUvffem2YHHHBAR9cEIt7whjek2ec+97k0u/3229Os3TFtjoQaPu6YAgBQBcUUAIAqKKYAAFRBMQUAoAqKKQAAVVBMAQCoQmmaJg9LycMRrN0RVNttt92Ar3fiiSem2SqrrJJmY8bkPzd86UtfSrM//elPafbjH/+45fhf//rXdM5o1TRNGe41DNRo3bOd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\n"
154 | },
155 | "metadata": {
156 | "needs_background": "light"
157 | }
158 | }
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "source": [
164 | "# preprocessing the images\n",
165 | "\n",
166 | "# convert each image to 1 dimensional array\n",
167 | "X = x_train.reshape(len(x_train),-1)\n",
168 | "Y = y_train\n",
169 | "\n",
170 | "# normalize the data to 0 - 1\n",
171 | "X = X.astype(float) / 255.\n",
172 | "\n",
173 | "print(X.shape)\n",
174 | "print(X[0].shape)"
175 | ],
176 | "metadata": {
177 | "colab": {
178 | "base_uri": "https://localhost:8080/"
179 | },
180 | "id": "EPwCPR5vQFOZ",
181 | "outputId": "520fbb0b-3288-4fed-8f5d-6051903bd742"
182 | },
183 | "execution_count": null,
184 | "outputs": [
185 | {
186 | "output_type": "stream",
187 | "name": "stdout",
188 | "text": [
189 | "(39000, 784)\n",
190 | "(784,)\n"
191 | ]
192 | }
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "source": [
198 | "X.shape"
199 | ],
200 | "metadata": {
201 | "id": "akRR_EDN1azv"
202 | },
203 | "execution_count": null,
204 | "outputs": []
205 | },
206 | {
207 | "cell_type": "code",
208 | "source": [
209 | "from sklearn.cluster import MiniBatchKMeans\n",
210 | "\n",
211 | "n_digits = len(np.unique(y_test))\n",
212 | "print(n_digits)\n",
213 | "\n",
214 | "# Initialize KMeans model\n",
215 | "kmeans = MiniBatchKMeans(n_clusters = 10, max_iter=100)\n",
216 | "\n",
217 | "# Fit the model to the training data\n",
218 | "kmeans.fit(X)"
219 | ],
220 | "metadata": {
221 | "colab": {
222 | "base_uri": "https://localhost:8080/"
223 | },
224 | "id": "fbfytRGoQFLy",
225 | "outputId": "5f029181-f1ac-4c35-f738-0265884f32c4"
226 | },
227 | "execution_count": null,
228 | "outputs": [
229 | {
230 | "output_type": "stream",
231 | "name": "stdout",
232 | "text": [
233 | "10\n"
234 | ]
235 | },
236 | {
237 | "output_type": "execute_result",
238 | "data": {
239 | "text/plain": [
240 | "MiniBatchKMeans(n_clusters=10)"
241 | ]
242 | },
243 | "metadata": {},
244 | "execution_count": 8
245 | }
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "source": [
251 | "img 2 9 5 7 7\n",
252 | "clu 0 7 9 4 6"
253 | ],
254 | "metadata": {
255 | "id": "3LqCg6r6rR72"
256 | },
257 | "execution_count": null,
258 | "outputs": []
259 | },
260 | {
261 | "cell_type": "code",
262 | "source": [
263 | "print(kmeans.predict(X[293].reshape(1,-1) ))\n",
264 | "plt.imshow(X[293].reshape(28,28) )"
265 | ],
266 | "metadata": {
267 | "colab": {
268 | "base_uri": "https://localhost:8080/",
269 | "height": 300
270 | },
271 | "id": "7m23hOAFp7lp",
272 | "outputId": "dc077b72-3a32-43af-aa58-a0c1270b3373"
273 | },
274 | "execution_count": null,
275 | "outputs": [
276 | {
277 | "output_type": "stream",
278 | "name": "stdout",
279 | "text": [
280 | "[5]\n"
281 | ]
282 | },
283 | {
284 | "output_type": "execute_result",
285 | "data": {
286 | "text/plain": [
287 | ""
288 | ]
289 | },
290 | "metadata": {},
291 | "execution_count": 15
292 | },
293 | {
294 | "output_type": "display_data",
295 | "data": {
296 | "text/plain": [
297 | ""
298 | ],
299 | "image/png": "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\n"
300 | },
301 | "metadata": {
302 | "needs_background": "light"
303 | }
304 | }
305 | ]
306 | },
307 | {
308 | "cell_type": "code",
309 | "source": [
310 | "kmeans.__dict__"
311 | ],
312 | "metadata": {
313 | "id": "_tJB77gnxCRI"
314 | },
315 | "execution_count": null,
316 | "outputs": []
317 | },
318 | {
319 | "cell_type": "code",
320 | "source": [
321 | "print(kmeans.labels_)"
322 | ],
323 | "metadata": {
324 | "id": "LXXxWZCpQFJJ"
325 | },
326 | "execution_count": null,
327 | "outputs": []
328 | },
329 | {
330 | "cell_type": "code",
331 | "source": [
332 | "common_label = list()\n",
333 | "for i in range(10):\n",
334 | " common_label.append(np.zeros(10,dtype=int))\n",
335 | "\n",
336 | "print(common_label)"
337 | ],
338 | "metadata": {
339 | "id": "u3oQkXSK2mA9"
340 | },
341 | "execution_count": null,
342 | "outputs": []
343 | },
344 | {
345 | "cell_type": "code",
346 | "source": [
347 | "for data_img, data_label in zip(x_train, y_train):\n",
348 | " img = data_img.reshape(1,-1)/255\n",
349 | " res = kmeans.predict(img)\n",
350 | " #print(data_label, res)\n",
351 | " common_label[data_label][res] += 1"
352 | ],
353 | "metadata": {
354 | "id": "exhctaREzSPO"
355 | },
356 | "execution_count": null,
357 | "outputs": []
358 | },
359 | {
360 | "cell_type": "code",
361 | "source": [
362 | "common_label"
363 | ],
364 | "metadata": {
365 | "id": "rcjE7guxsJHX"
366 | },
367 | "execution_count": null,
368 | "outputs": []
369 | },
370 | {
371 | "cell_type": "code",
372 | "source": [
373 | "equivalencias = list()\n",
374 | "for i in range(10):\n",
375 | " equivalencias.append(common_label[i].argmax())"
376 | ],
377 | "metadata": {
378 | "id": "_QfJWNIq5Q_6"
379 | },
380 | "execution_count": null,
381 | "outputs": []
382 | },
383 | {
384 | "cell_type": "code",
385 | "source": [
386 | "equivalencias"
387 | ],
388 | "metadata": {
389 | "id": "3sP3uoF75wVV"
390 | },
391 | "execution_count": null,
392 | "outputs": []
393 | },
394 | {
395 | "cell_type": "code",
396 | "source": [
397 | "# test the infer_cluster_labels() and infer_data_labels() functions\n",
398 | "cluster_labels = infer_cluster_labels(kmeans, Y)\n",
399 | "X_clusters = kmeans.predict(X)\n",
400 | "predicted_labels = infer_data_labels(X_clusters, cluster_labels)\n",
401 | "print(predicted_labels[:20])\n",
402 | "print(Y[:20])"
403 | ],
404 | "metadata": {
405 | "id": "ueo5cjrYQFDq"
406 | },
407 | "execution_count": null,
408 | "outputs": []
409 | },
410 | {
411 | "cell_type": "code",
412 | "source": [],
413 | "metadata": {
414 | "id": "hMsE4T5bQ54Y"
415 | },
416 | "execution_count": null,
417 | "outputs": []
418 | },
419 | {
420 | "cell_type": "code",
421 | "source": [],
422 | "metadata": {
423 | "id": "BZt0DPpzQFAv"
424 | },
425 | "execution_count": null,
426 | "outputs": []
427 | },
428 | {
429 | "cell_type": "code",
430 | "source": [],
431 | "metadata": {
432 | "id": "BDCy9TT6PFD6"
433 | },
434 | "execution_count": null,
435 | "outputs": []
436 | },
437 | {
438 | "cell_type": "code",
439 | "source": [],
440 | "metadata": {
441 | "id": "eTAIOEhOPFBI"
442 | },
443 | "execution_count": null,
444 | "outputs": []
445 | },
446 | {
447 | "cell_type": "markdown",
448 | "source": [
449 | "# ejemplo de sklearn doc\n",
450 | "https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_digits.html"
451 | ],
452 | "metadata": {
453 | "id": "od3oEarpPFvW"
454 | }
455 | },
456 | {
457 | "cell_type": "code",
458 | "source": [],
459 | "metadata": {
460 | "id": "arpsIcc6PE4t"
461 | },
462 | "execution_count": null,
463 | "outputs": []
464 | },
465 | {
466 | "cell_type": "code",
467 | "execution_count": null,
468 | "metadata": {
469 | "id": "nIqwjSbUAQUq"
470 | },
471 | "outputs": [],
472 | "source": [
473 | "import numpy as np\n",
474 | "from sklearn.datasets import load_digits\n",
475 | "\n",
476 | "data, labels = load_digits(return_X_y=True)\n",
477 | "(n_samples, n_features), n_digits = data.shape, np.unique(labels).size\n",
478 | "\n",
479 | "print(f\"# digits: {n_digits}; # samples: {n_samples}; # features {n_features}\")"
480 | ]
481 | },
482 | {
483 | "cell_type": "code",
484 | "source": [
485 | "from time import time\n",
486 | "from sklearn import metrics\n",
487 | "from sklearn.pipeline import make_pipeline\n",
488 | "from sklearn.preprocessing import StandardScaler\n",
489 | "\n",
490 | "\n",
491 | "def bench_k_means(kmeans, name, data, labels):\n",
492 | " \"\"\"Benchmark to evaluate the KMeans initialization methods.\n",
493 | "\n",
494 | " Parameters\n",
495 | " ----------\n",
496 | " kmeans : KMeans instance\n",
497 | " A :class:`~sklearn.cluster.KMeans` instance with the initialization\n",
498 | " already set.\n",
499 | " name : str\n",
500 | " Name given to the strategy. It will be used to show the results in a\n",
501 | " table.\n",
502 | " data : ndarray of shape (n_samples, n_features)\n",
503 | " The data to cluster.\n",
504 | " labels : ndarray of shape (n_samples,)\n",
505 | " The labels used to compute the clustering metrics which requires some\n",
506 | " supervision.\n",
507 | " \"\"\"\n",
508 | " t0 = time()\n",
509 | " estimator = make_pipeline(StandardScaler(), kmeans).fit(data)\n",
510 | " fit_time = time() - t0\n",
511 | " results = [name, fit_time, estimator[-1].inertia_]\n",
512 | "\n",
513 | " # Define the metrics which require only the true labels and estimator\n",
514 | " # labels\n",
515 | " clustering_metrics = [\n",
516 | " metrics.homogeneity_score,\n",
517 | " metrics.completeness_score,\n",
518 | " metrics.v_measure_score,\n",
519 | " metrics.adjusted_rand_score,\n",
520 | " metrics.adjusted_mutual_info_score,\n",
521 | " ]\n",
522 | " results += [m(labels, estimator[-1].labels_) for m in clustering_metrics]\n",
523 | "\n",
524 | " # The silhouette score requires the full dataset\n",
525 | " results += [\n",
526 | " metrics.silhouette_score(\n",
527 | " data,\n",
528 | " estimator[-1].labels_,\n",
529 | " metric=\"euclidean\",\n",
530 | " sample_size=300,\n",
531 | " )\n",
532 | " ]\n",
533 | "\n",
534 | " # Show the results\n",
535 | " formatter_result = (\n",
536 | " \"{:9s}\\t{:.3f}s\\t{:.0f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\"\n",
537 | " )\n",
538 | " print(formatter_result.format(*results))"
539 | ],
540 | "metadata": {
541 | "id": "r6c-iFivO4PE"
542 | },
543 | "execution_count": null,
544 | "outputs": []
545 | },
546 | {
547 | "cell_type": "code",
548 | "source": [
549 | "from sklearn.cluster import KMeans\n",
550 | "from sklearn.decomposition import PCA\n",
551 | "\n",
552 | "print(82 * \"_\")\n",
553 | "print(\"init\\t\\ttime\\tinertia\\thomo\\tcompl\\tv-meas\\tARI\\tAMI\\tsilhouette\")\n",
554 | "\n",
555 | "kmeans = KMeans(init=\"k-means++\", n_clusters=n_digits, n_init=4, random_state=0)\n",
556 | "bench_k_means(kmeans=kmeans, name=\"k-means++\", data=data, labels=labels)\n",
557 | "\n",
558 | "kmeans = KMeans(init=\"random\", n_clusters=n_digits, n_init=4, random_state=0)\n",
559 | "bench_k_means(kmeans=kmeans, name=\"random\", data=data, labels=labels)\n",
560 | "\n",
561 | "pca = PCA(n_components=n_digits).fit(data)\n",
562 | "kmeans = KMeans(init=pca.components_, n_clusters=n_digits, n_init=1)\n",
563 | "bench_k_means(kmeans=kmeans, name=\"PCA-based\", data=data, labels=labels)\n",
564 | "\n",
565 | "print(82 * \"_\")"
566 | ],
567 | "metadata": {
568 | "id": "CAUDrcr1O9sT"
569 | },
570 | "execution_count": null,
571 | "outputs": []
572 | },
573 | {
574 | "cell_type": "code",
575 | "source": [
576 | "import matplotlib.pyplot as plt\n",
577 | "\n",
578 | "reduced_data = PCA(n_components=2).fit_transform(data)\n",
579 | "kmeans = KMeans(init=\"k-means++\", n_clusters=n_digits, n_init=4)\n",
580 | "kmeans.fit(reduced_data)\n",
581 | "\n",
582 | "# Step size of the mesh. Decrease to increase the quality of the VQ.\n",
583 | "h = 0.02 # point in the mesh [x_min, x_max]x[y_min, y_max].\n",
584 | "\n",
585 | "# Plot the decision boundary. For that, we will assign a color to each\n",
586 | "x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1\n",
587 | "y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1\n",
588 | "xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))\n",
589 | "\n",
590 | "# Obtain labels for each point in mesh. Use last trained model.\n",
591 | "Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])\n",
592 | "\n",
593 | "# Put the result into a color plot\n",
594 | "Z = Z.reshape(xx.shape)\n",
595 | "plt.figure(1)\n",
596 | "plt.clf()\n",
597 | "plt.imshow(\n",
598 | " Z,\n",
599 | " interpolation=\"nearest\",\n",
600 | " extent=(xx.min(), xx.max(), yy.min(), yy.max()),\n",
601 | " cmap=plt.cm.Paired,\n",
602 | " aspect=\"auto\",\n",
603 | " origin=\"lower\",\n",
604 | ")\n",
605 | "\n",
606 | "plt.plot(reduced_data[:, 0], reduced_data[:, 1], \"k.\", markersize=2)\n",
607 | "# Plot the centroids as a white X\n",
608 | "centroids = kmeans.cluster_centers_\n",
609 | "plt.scatter(\n",
610 | " centroids[:, 0],\n",
611 | " centroids[:, 1],\n",
612 | " marker=\"x\",\n",
613 | " s=169,\n",
614 | " linewidths=3,\n",
615 | " color=\"w\",\n",
616 | " zorder=10,\n",
617 | ")\n",
618 | "plt.title(\n",
619 | " \"K-means clustering on the digits dataset (PCA-reduced data)\\n\"\n",
620 | " \"Centroids are marked with white cross\"\n",
621 | ")\n",
622 | "plt.xlim(x_min, x_max)\n",
623 | "plt.ylim(y_min, y_max)\n",
624 | "plt.xticks(())\n",
625 | "plt.yticks(())\n",
626 | "plt.show()\n"
627 | ],
628 | "metadata": {
629 | "id": "1LRQamlVPA8G"
630 | },
631 | "execution_count": null,
632 | "outputs": []
633 | }
634 | ]
635 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IntroAI
--------------------------------------------------------------------------------