1 00:00:00,000 --> 00:00:10,670 [MÚSICA DE FONDO] 2 00:00:10,670 --> 00:00:12,240 PONENTE: OK. 3 00:00:12,240 --> 00:00:13,590 Entonces, ¿qué es la programación dinámica? 4 00:00:13,590 --> 00:00:17,190 Por lo general, me gustaría pedirles que aportaran ideas 5 00:00:17,190 --> 00:00:18,130 para que pudiéramos discutirlas, 6 00:00:18,130 --> 00:00:21,510 pero en este caso en particular, el punto que quiero resaltar 7 00:00:21,510 --> 00:00:24,150 es que, ya sea que sepan la respuesta, o que estén equivocados, 8 00:00:24,150 --> 00:00:26,790 9 00:00:26,790 --> 00:00:33,544 la programación dinámica se diseñó para ser compatible con las palabras de moda. 10 00:00:33,544 --> 00:00:35,710 Es algo que inventó Richard Bellman 11 00:00:35,710 --> 00:00:38,250 y se le ocurrió este nombre. 12 00:00:38,250 --> 00:00:46,290 Y es en realidad, de acuerdo con su autobiografía, 13 00:00:46,290 --> 00:00:49,740 el problema era que Rand era un contratista de defensa, 14 00:00:49,740 --> 00:00:54,270 entonces él trabajaba en Rand, trabajaba con algoritmos de computadora, 15 00:00:54,270 --> 00:01:00,330 y Rand trabajó para la Fuerza Aérea, aún todavía trabaja para ella, 16 00:01:00,330 --> 00:01:03,690 era parte del gran complejo industrial militar 17 00:01:03,690 --> 00:01:09,030 y eso significaba que su presupuesto dependía del Secretario de Defensa. 18 00:01:09,030 --> 00:01:12,390 Y si al Secretario de Defensa no le gustaba lo que estaba haciendo, 19 00:01:12,390 --> 00:01:15,450 o al Congreso no le gustaba lo que estaba haciendo, y se enteraban, 20 00:01:15,450 --> 00:01:16,616 sería el final todo. 21 00:01:16,616 --> 00:01:18,820 22 00:01:18,820 --> 00:01:25,470 Aparentemente, según Bellman, el Secretario de Defensa de ese tiempo 23 00:01:25,470 --> 00:01:28,740 sentía una aversión patológica por la investigación. 24 00:01:28,740 --> 00:01:35,010 La forma en que lo describió es que se enfurecía y se ponía rojo 25 00:01:35,010 --> 00:01:38,100 si mencionaban la palabra investigación en su presencia. 26 00:01:38,100 --> 00:01:42,062 Y realmente no le gustaba si decían algo como matemáticas. 27 00:01:42,062 --> 00:01:45,270 Entonces Bellman quería asegurarse de que si lo que estaba haciendo aparecía 28 00:01:45,270 --> 00:01:49,290 en un informe del Congreso o si aterrizaba un informe en el Departamento 29 00:01:49,290 --> 00:01:52,230 de Defensa, o en el escritorio del Secretario de Defensa, 30 00:01:52,230 --> 00:01:55,260 no habría algo objetable. 31 00:01:55,260 --> 00:01:58,530 Se le ocurrió el término programación, que en el mundo de las matemáticas, 32 00:01:58,530 --> 00:02:03,150 significa optimización, encontrar la mejor respuesta a un problema. 33 00:02:03,150 --> 00:02:06,900 Y el término dinámico, y la idea de dinámico era este 34 00:02:06,900 --> 00:02:10,620 adjetivo que de alguna manera expresa que las cosas están cambiando, 35 00:02:10,620 --> 00:02:15,840 pero sobre todo, que no tiene connotaciones negativas. 36 00:02:15,840 --> 00:02:17,010 La dinámica simplemente suena bien. 37 00:02:17,010 --> 00:02:19,650 38 00:02:19,650 --> 00:02:21,630 Así que de ahí viene el nombre. 39 00:02:21,630 --> 00:02:24,900 Entonces, la programación dinámica básicamente es un nombre 40 00:02:24,900 --> 00:02:28,620 que nadie podría objetar, y por lo tanto 41 00:02:28,620 --> 00:02:32,270 nadie cancelaría el proyecto. 42 00:02:32,270 --> 00:02:36,760 43 00:02:36,760 --> 00:02:46,190 Hay un término que es mucho más descriptivo de lo que está pasando, 44 00:02:46,190 --> 00:02:48,850 que es una tabla de búsqueda. 45 00:02:48,850 --> 00:02:52,270 Entonces, la programación dinámica es, a fin de cuentas, 46 00:02:52,270 --> 00:02:56,710 una forma de ver ciertos tipos de problemas 47 00:02:56,710 --> 00:02:58,570 con estructuras de datos vinculados, listas vinculadas, 48 00:02:58,570 --> 00:03:03,370 tries, tablas hash, todo eso que cae en la categoría de una estructura de datos 49 00:03:03,370 --> 00:03:05,290 y que utilizamos cuando tenemos datos y queremos 50 00:03:05,290 --> 00:03:08,140 mapear las conexiones entre ellos. 51 00:03:08,140 --> 00:03:11,110 Y entonces hay toda una categoría de estructuras de datos diferentes 52 00:03:11,110 --> 00:03:16,480 que implican el uso de punteros para mapear las conexiones entre las cosas. 53 00:03:16,480 --> 00:03:20,230 La programación dinámica es una categoría de algoritmos 54 00:03:20,230 --> 00:03:23,830 donde decimos, en mi problema, cuando quiero resolverlo, 55 00:03:23,830 --> 00:03:28,780 termino haciendo la misma pregunta una y otra vez como parte de la solución. 56 00:03:28,780 --> 00:03:31,700 La misma pregunta con los mismos parámetros, si quieren verlo así. 57 00:03:31,700 --> 00:03:36,730 Y entonces, en lugar de hacer todo el mismo trabajo una y otra vez, 58 00:03:36,730 --> 00:03:40,741 me permite recordar la respuesta después de resolverlo una vez, 59 00:03:40,741 --> 00:03:42,490 y la siguiente vez que haga la misma pregunta, 60 00:03:42,490 --> 00:03:44,950 Voy a ir a buscar cuál fue la respuesta. 61 00:03:44,950 --> 00:03:49,180 Esa es la idea de la programación dinámica. 62 00:03:49,180 --> 00:03:53,170 y la de una tabla de búsqueda. 63 00:03:53,170 --> 00:03:55,900 Ya hemos usado antes tablas de búsqueda. 64 00:03:55,900 --> 00:04:13,210 Por ejemplo, si volvemos al comienzo de la clase, 65 00:04:13,210 --> 00:04:16,100 Aquí hay un bucle for. 66 00:04:16,100 --> 00:04:23,360 for(int i = 0, i < strlen(str); ... 67 00:04:23,360 --> 00:04:24,910 i++). 68 00:04:24,910 --> 00:04:25,410 este 69 00:04:25,410 --> 00:04:27,480 Es un bucle, el bucle que hay a través de cada carácter 70 00:04:27,480 --> 00:04:30,550 de esta cuerda, str, uno por uno. 71 00:04:30,550 --> 00:04:33,570 Pero el problema es que, cada vez que pasamos por el bucle, 72 00:04:33,570 --> 00:04:36,180 se recalcula la longitud de esta cadena. 73 00:04:36,180 --> 00:04:38,840 Y calcular la longitud de la cadena en C 74 00:04:38,840 --> 00:04:42,240 toma algo de tiempo porque se tiene que caminar por toda la cadena hasta que 75 00:04:42,240 --> 00:04:45,750 se alcanza ese carácter nulo al final. 76 00:04:45,750 --> 00:04:49,470 Ahora, volviendo al comienzo de la clase, 77 00:04:49,470 --> 00:04:55,260 recuerden que hablamos de si sería mejor desde una perspectiva de rendimiento 78 00:04:55,260 --> 00:04:59,010 no seguir recalculando la longitud de la cadena. 79 00:04:59,010 --> 00:05:12,820 En cambio, ¿por qué no decir algo como int length = strlen (str), 80 00:05:12,820 --> 00:05:23,380 guardar ese valor en una variable, y solo buscar ese valor cada vez que 81 00:05:23,380 --> 00:05:27,330 pasa por el bucle y comprueba si hemos alcanzado el último valor de i? 82 00:05:27,330 --> 00:05:31,900 83 00:05:31,900 --> 00:05:35,905 Allí pueden pensar en la longitud como una tabla de búsqueda que almacena un valor. 84 00:05:35,905 --> 00:05:38,860 85 00:05:38,860 --> 00:05:42,080 Hay un ejemplo que ya hemos visto. 86 00:05:42,080 --> 00:05:43,924 Vamos a ir a las tablas de búsqueda que almacenan 87 00:05:43,924 --> 00:05:45,340 la respuesta a más de una cosa. 88 00:05:45,340 --> 00:05:48,040 89 00:05:48,040 --> 00:05:53,740 Y hoy veremos algunos ejemplos diferentes de problemas 90 00:05:53,740 --> 00:05:56,950 que pueden resolver usando la programación dinámica. 91 00:05:56,950 --> 00:06:00,910 Así que estos son problemas que pueden resolver de manera 92 00:06:00,910 --> 00:06:04,360 que se haga la misma pregunta una y otra vez 93 00:06:04,360 --> 00:06:07,960 y simplemente busque la respuesta en una tabla o en un arreglo. 94 00:06:07,960 --> 00:06:11,440 95 00:06:11,440 --> 00:06:16,280 Y el primer problema de este tipo es relativo al corte de una barra. 96 00:06:16,280 --> 00:06:20,890 La idea es que tengo una barra hecha de algo valioso, 97 00:06:20,890 --> 00:06:28,660 así que tal vez sea una Tootsie Roll o plutonio, 98 00:06:28,660 --> 00:06:31,960 hay una gran variedad de cosas que vienen en forma de cilindro largo 99 00:06:31,960 --> 00:06:35,620 y quiero cortarla en trozos más pequeños para venderlos. 100 00:06:35,620 --> 00:06:39,550 Y lo que saben es que son piezas o barras de diferentes longitudes, 101 00:06:39,550 --> 00:06:42,310 que se venden en distintos precios. 102 00:06:42,310 --> 00:06:45,430 Y la pregunta es, ¿cómo debería cortar esa cosa larga 103 00:06:45,430 --> 00:06:50,080 en partes más pequeñas para maximizar el dinero que obtengo al venderlas? 104 00:06:50,080 --> 00:06:54,880 105 00:06:54,880 --> 00:06:59,865 Entonces, si sé, que una barra de una pulgada de largo se vende en $1 106 00:06:59,865 --> 00:07:02,740 y que una barra de dos pulgadas de largo resulta ser mucho más valiosa, 107 00:07:02,740 --> 00:07:05,500 que puedo venderla en $5. 108 00:07:05,500 --> 00:07:08,259 Y que cuando tiene tres pulgadas de largo, puedo venderla en $8. 109 00:07:08,259 --> 00:07:11,050 Ahora hay mucha más demanda de cosas que tienen tres pulgadas de largo 110 00:07:11,050 --> 00:07:12,781 que cosas que tienen cuatro pulgadas de largo. 111 00:07:12,781 --> 00:07:14,530 Entonces si tiene cuatro pulgadas de largo, puedo venderlo 112 00:07:14,530 --> 00:07:16,780 en $9, que es un poco más, pero no mucho más. 113 00:07:16,780 --> 00:07:19,780 114 00:07:19,780 --> 00:07:21,020 Y luego viene la pregunta. 115 00:07:21,020 --> 00:07:23,290 Tengo una barra de longitud 10, 116 00:07:23,290 --> 00:07:27,970 ¿cómo debería cortarla en 1, 2, 3 y 4 para maximizar el beneficio? 117 00:07:27,970 --> 00:07:30,050 Y hay diferentes maneras en las que puedo hacer esto. 118 00:07:30,050 --> 00:07:35,140 Podría cortarla en 10 barras pequeñas de una pulgada, y vender cada una en $1 119 00:07:35,140 --> 00:07:38,140 y ganaría $10. 120 00:07:38,140 --> 00:07:46,000 Podría cortarla en cinco barras de dos pulgadas y obtendría 5 por 5, igual a $25. 121 00:07:46,000 --> 00:07:48,580 Eso es mucho más dinero. 122 00:07:48,580 --> 00:07:53,650 Siendo el capitalista sinvergüenza que soy, es probablemente que elija eso. 123 00:07:53,650 --> 00:07:56,530 124 00:07:56,530 --> 00:07:59,920 Y hay algunas opciones intermedias que podrían hacerme ganar dinero. 125 00:07:59,920 --> 00:08:03,490 La pregunta es, cómo descubrir rápidamente 126 00:08:03,490 --> 00:08:08,380 en cuantos pedazos debo cortar la barra para maximizar mi ganancia 127 00:08:08,380 --> 00:08:10,780 y asegurarme de que sea el máximo precio en que pueda venderlo 128 00:08:10,780 --> 00:08:14,860 porque no había otra forma de cortarla que fuera mejor. 129 00:08:14,860 --> 00:08:18,190 130 00:08:18,190 --> 00:08:20,970 Y una forma de pensar en el problema es, 131 00:08:20,970 --> 00:08:26,080 si tengo una barra de 10 pulgadas y puedo cortarla en trozos de una pulgada, 132 00:08:26,080 --> 00:08:35,760 hay 1, 2, 3, 4, 5, 6, 7, 8, 9 posibles lugares donde podría cortar la barra. 133 00:08:35,760 --> 00:08:38,970 Y en cualquiera de esos lugares podría decidir hacer un corte 134 00:08:38,970 --> 00:08:40,620 o no hacer un corte. 135 00:08:40,620 --> 00:08:44,100 Y eso afectaría el resultado final. 136 00:08:44,100 --> 00:08:45,640 Entonces son 9 bits 137 00:08:45,640 --> 00:08:46,710 ya sea que corte o no. 138 00:08:46,710 --> 00:08:49,510 Son un 1 o un 0. 139 00:08:49,510 --> 00:08:52,560 Así que en términos de las posibles combinaciones 140 00:08:52,560 --> 00:08:58,890 de cómo podría cortarla con cada número de 9 posibles bits 141 00:08:58,890 --> 00:09:03,880 en binario, que tienen 2 a la 9 valores posibles, es igual a 512. 142 00:09:03,880 --> 00:09:10,410 Entonces podría probar 512 posibles maneras diferentes de cortar esta barra. 143 00:09:10,410 --> 00:09:14,990 Y puedo descubrir cuál es la mejor. 144 00:09:14,990 --> 00:09:17,580 145 00:09:17,580 --> 00:09:22,200 Y luego podría intentar con una barra que tenga 20 pulgadas de largo 146 00:09:22,200 --> 00:09:25,140 y descubrir que hay 19 posibles lugares para decidir dónde cortarla o no, 147 00:09:25,140 --> 00:09:28,420 y hay 2 a la 19 posibilidades, 148 00:09:28,420 --> 00:09:34,430 que aproximadamente son 500,000. 149 00:09:34,430 --> 00:09:38,850 2 a la 10 son cerca de 1000, 2 a la 20 son casi un millón, 2 a la 19 150 00:09:38,850 --> 00:09:43,910 es casi de un millón dividido por 2, lo cual es igual a 500,000. 151 00:09:43,910 --> 00:09:49,580 Entonces, en general, si dijéramos que esta barra mide n pulgadas de largo 152 00:09:49,580 --> 00:09:53,810 y que hay n lugares, o n-1 lugares en los que pueda tomar una decisión 153 00:09:53,810 --> 00:09:59,990 para cortarla, hay aproximadamente 2 a la n posibles combinaciones 154 00:09:59,990 --> 00:10:02,420 de hacer combinaciones de cortes. 155 00:10:02,420 --> 00:10:05,120 Y eso es un montón de cosas por probar. 156 00:10:05,120 --> 00:10:09,770 Al mismo tiempo, podemos ver cómo se divide en barras 157 00:10:09,770 --> 00:10:13,590 de 1, 1, 5, 5 y 9 pulgadas de largo 158 00:10:13,590 --> 00:10:19,010 no es la única combinación de cortes que me daría eso. 159 00:10:19,010 --> 00:10:25,670 Hay otras combinaciones que también me lo darían, dos de 1, dos de 5 y 160 00:10:25,670 --> 00:10:27,590 perdón, una de 4 pulgadas de largo. 161 00:10:27,590 --> 00:10:31,150 Dos de 1, dos de 2 y una de 4. 162 00:10:31,150 --> 00:10:34,760 Luego podría probar una de 4 y luego dos de 2 y dos de 1, 163 00:10:34,760 --> 00:10:36,364 y obtendría el mismo valor. 164 00:10:36,364 --> 00:10:38,405 Así que hay muchas maneras posibles en las que podríamos cortarla 165 00:10:38,405 --> 00:10:41,090 166 00:10:41,090 --> 00:10:46,185 y nos daría el mismo resultado en términos del valor. 167 00:10:46,185 --> 00:10:48,060 Entonces tal vez quiera reorganizar el problema 168 00:10:48,060 --> 00:10:52,790 de modo que no tenga que probar todo, porque me doy cuenta que muchas veces 169 00:10:52,790 --> 00:10:54,390 estoy recalculando lo mismo. 170 00:10:54,390 --> 00:10:58,560 171 00:10:58,560 --> 00:11:01,120 Y una forma de hacerlo, 172 00:11:01,120 --> 00:11:04,410 y aquí es donde entra el concepto de programación dinámica o tabla 173 00:11:04,410 --> 00:11:05,640 de búsqueda, 174 00:11:05,640 --> 00:11:15,040 es decir, déjame decidir primero dónde haré el corte que sea más a la izquierda. 175 00:11:15,040 --> 00:11:17,950 Entonces, en lugar de decidir si voy a cortarlo 1 pulgada o no, 176 00:11:17,950 --> 00:11:21,300 voy a cortarlo 2 pulgadas o no, voy a cortarlo 3 pulgadas o no, 177 00:11:21,300 --> 00:11:25,080 Voy a decidir ¿cuál es el primer lugar que voy a cortar? 178 00:11:25,080 --> 00:11:27,840 Eso podría ser a 1 pulgada, a 2 pulgadas, a 3 pulgadas, a 4 pulgadas 179 00:11:27,840 --> 00:11:31,530 o a 5, 6, 7, 8 o a 9 pulgadas, 180 00:11:31,530 --> 00:11:33,870 o podría decidir que no voy a cortar en absoluto, 181 00:11:33,870 --> 00:11:37,650 Voy a dejar la barra completa. 182 00:11:37,650 --> 00:11:42,420 En la barra de longitud 10, hay 10 lugares posibles para hacer el primer corte. 183 00:11:42,420 --> 00:11:49,290 Y lo que voy a decidir es si divido la barra en dos, 184 00:11:49,290 --> 00:11:53,430 la parte de la izquierda que no voy a cortar de nuevo. 185 00:11:53,430 --> 00:11:57,450 No voy a cortar esta parte 2 186 00:11:57,450 --> 00:11:58,120 o la parte 3. 187 00:11:58,120 --> 00:11:59,260 Estoy tomando esa decisión. 188 00:11:59,260 --> 00:12:02,820 Esta es la primera pieza que voy a vender. 189 00:12:02,820 --> 00:12:06,150 Entonces, el valor total que puedo obtener será 190 00:12:06,150 --> 00:12:13,410 aquello en lo que pueda vender la pieza de la izquierda por $1, $5, $8 o $9, 191 00:12:13,410 --> 00:12:18,600 más lo que pueda conseguir por la parte correcta si la corto en trozos más pequeños 192 00:12:18,600 --> 00:12:19,560 la mejor manera posible 193 00:12:19,560 --> 00:12:23,140 194 00:12:23,140 --> 00:12:24,950 Entonces, no volveré a cortar la parte de la izquierda. 195 00:12:24,950 --> 00:12:30,180 Puedo buscar en la tabla cuál es el valor de una barra de esta longitud. 196 00:12:30,180 --> 00:12:33,870 Pero también necesito descubrir, para la parte de la derecha, 197 00:12:33,870 --> 00:12:35,630 ¿cuál es la mejor manera de cortarla. 198 00:12:35,630 --> 00:12:42,090 199 00:12:42,090 --> 00:12:46,320 E incluso, si calculamos todas las posibilidades, 200 00:12:46,320 --> 00:12:49,290 terminaremos con las mismas 2 a la n, 201 00:12:49,290 --> 00:12:53,230 excepto que podemos empezar a ver algunas cosas en común. 202 00:12:53,230 --> 00:13:00,750 Por ejemplo, si deciden cortar una barra de longitud 2, 203 00:13:00,750 --> 00:13:05,010 tienen ocho sobrantes, y quieren encontrar la mejor manera de cortarla. 204 00:13:05,010 --> 00:13:10,980 Ahora, si solo cortaron una pulgada primero, ese fue su primer corte, 205 00:13:10,980 --> 00:13:15,300 y luego hicieron otro corte donde cortaron otra pulgada, 206 00:13:15,300 --> 00:13:19,090 de repente tienen la mejor manera de cortar una barra de longitud ocho. 207 00:13:19,090 --> 00:13:22,430 208 00:13:22,430 --> 00:13:28,900 Entonces, entre las posibles formas para cortar esta cosa de longitud 9, 209 00:13:28,900 --> 00:13:32,660 una posibilidad es, una vez más, quitar una pulgada para venderla, 210 00:13:32,660 --> 00:13:35,630 y nos quedan ocho pulgadas. 211 00:13:35,630 --> 00:13:38,450 Si desde el principio tomamos dos pulgadas de distancia, 212 00:13:38,450 --> 00:13:40,010 también nos quedarían ocho pulgadas. 213 00:13:40,010 --> 00:13:42,650 214 00:13:42,650 --> 00:13:46,220 Y nos hacemos la misma pregunta en ambas ocasiones. 215 00:13:46,220 --> 00:13:51,110 Dijimos, tengo algunas cosas que corté y que voy a vender, 216 00:13:51,110 --> 00:13:52,900 y ahora me queda una barra de ocho pulgadas. 217 00:13:52,900 --> 00:13:54,560 ¿Cómo debo cortarla? 218 00:13:54,560 --> 00:13:57,980 No tiene sentido descifrar eso dos veces. 219 00:13:57,980 --> 00:14:00,920 Podríamos tener una pequeña matriz donde almacenáramos, 220 00:14:00,920 --> 00:14:03,260 ¿cuál es la mejor manera de cortar una barra de longitud 8? 221 00:14:03,260 --> 00:14:06,337 ¿cuál es la mejor manera de cortar una barra de longitud 9, 7, 6, 5 o 4? 222 00:14:06,337 --> 00:14:10,820 Y para cada una de ellas, simplemente vemos la matriz y decimos: 223 00:14:10,820 --> 00:14:13,310 ¿Ya pusimos un valor allí? 224 00:14:13,310 --> 00:14:14,690 Si es así, simplemente lo usamos. 225 00:14:14,690 --> 00:14:15,700 No lo recalculamos 226 00:14:15,700 --> 00:14:22,530 227 00:14:22,530 --> 00:14:27,570 Y el resultado es que, si comienzan a observarlo, 228 00:14:27,570 --> 00:14:32,460 tenemos 10 opciones para nuestro primer corte, y luego, en promedio, 229 00:14:32,460 --> 00:14:35,640 tenemos como nueve opciones para nuestro segundo corte, 230 00:14:35,640 --> 00:14:39,630 y hasta ocho opciones para nuestro tercer corte. 231 00:14:39,630 --> 00:14:43,830 Y así para cada una de las 10 opciones posibles la primera vez, 232 00:14:43,830 --> 00:14:47,430 tenemos nueve opciones, para nuestro segundo corte tenemos hasta 90. 233 00:14:47,430 --> 00:14:53,640 234 00:14:53,640 --> 00:14:55,410 Pero esto nos vuelve exponenciales. 235 00:14:55,410 --> 00:14:58,260 El problema es que muchos de estos cortes terminan siendo los mismos. 236 00:14:58,260 --> 00:15:00,210 Y entonces acabamos diciendo, solo tengo que lidiar 237 00:15:00,210 --> 00:15:04,170 con 10 opciones como primer corte para la barra de longitud 10 238 00:15:04,170 --> 00:15:09,480 y 9 opciones como primer corte para la barra de longitud 9, 239 00:15:09,480 --> 00:15:13,295 y 8 opciones como primer corte para la barra de longitud 8, 240 00:15:13,295 --> 00:15:15,670 porque después de eso tendré que hacer algo más corto. 241 00:15:15,670 --> 00:15:19,350 Con el tiempo lo averiguaré. 242 00:15:19,350 --> 00:15:21,780 Y terminan con algo como n al cuadrado. 243 00:15:21,780 --> 00:15:25,830 Entonces, para barras de longitud 10, tendría cerca de 10 veces 10 opciones 244 00:15:25,830 --> 00:15:29,070 por lo que realmente tengo que trabajar. 245 00:15:29,070 --> 00:15:35,400 Y así disminuimos a n al cuadrado, en comparación con n al cubo. 246 00:15:35,400 --> 00:15:38,340 Otra forma de hacerlo es decir, comenzaré con una barra de longitud 1. 247 00:15:38,340 --> 00:15:42,390 No tengo opciones para cortarla, así que sé la respuesta 248 00:15:42,390 --> 00:15:43,920 por cómo voy a vender eso. 249 00:15:43,920 --> 00:15:49,170 Para una barra de longitud 2, puedo sacar el costo para una barra de longitud 1, 250 00:15:49,170 --> 00:15:56,700 y hacer un corte, y luego tener una barra de longitud 1 sobrante. 251 00:15:56,700 --> 00:15:59,370 Puedo buscar cuánto cuesta. 252 00:15:59,370 --> 00:16:02,480 Y almacenaré cuál de esos fue el mejor valor para la barra de longitud 2. 253 00:16:02,480 --> 00:16:06,480 Diré, para la barra de longitud 2, puedo obtener $5, y la forma de hacerlo 254 00:16:06,480 --> 00:16:07,170 es no cortarla. 255 00:16:07,170 --> 00:16:09,720 256 00:16:09,720 --> 00:16:14,400 Y para una barra de longitud tres, podría decidir cortarla después de 1 pulgada, 257 00:16:14,400 --> 00:16:16,110 y tendría 2 pulgadas sobrantes. 258 00:16:16,110 --> 00:16:19,110 Entonces diremos, bueno, lo mejor que podemos hacer con una barra de 2 pulgadas 259 00:16:19,110 --> 00:16:21,750 es obtener $5 por eso, está muy bien. 260 00:16:21,750 --> 00:16:27,740 Si es de 3 pulgadas, podemos obtener $6 haciendo un corte después de una pulgada. 261 00:16:27,740 --> 00:16:31,909 Si el corte es después de 2 pulgadas, son $5 por vender una barra de longitud 2, 262 00:16:31,909 --> 00:16:34,200 y luego vemos hacia arriba, ¿qué hacemos con una barra de longitud 1? 263 00:16:34,200 --> 00:16:38,190 y la respuesta es que lo vendemos por $1, eso nos da $6. 264 00:16:38,190 --> 00:16:42,120 Luego vemos, ¿y qué pasa si solo vendemos una barra de longitud 3? 265 00:16:42,120 --> 00:16:43,470 Ganamos $8. 266 00:16:43,470 --> 00:16:46,890 Así que registraré... genial, para barras de longitud 3, no lo cortaremos, 267 00:16:46,890 --> 00:16:48,870 solo la venderemos. 268 00:16:48,870 --> 00:16:53,580 Para una barra de longitud 4, la cortamos después de 1 pulgada. 269 00:16:53,580 --> 00:16:57,510 Veamos, ah, para una barra de longitud 1, la vendemos en $1, 270 00:16:57,510 --> 00:17:03,240 pero, ¿qué hacemos con una barra de longitud 3? 271 00:17:03,240 --> 00:17:06,119 Solo la vendemos. 272 00:17:06,119 --> 00:17:07,410 Está hecho. 273 00:17:07,410 --> 00:17:11,220 Descubrí que eso nos da $9. 274 00:17:11,220 --> 00:17:13,560 ¿Qué pasa si la cortamos a 2 pulgadas? 275 00:17:13,560 --> 00:17:17,430 Bueno, tenemos una barra de dos pulgadas que venderemos en $5 276 00:17:17,430 --> 00:17:21,790 y luego veamos cómo recuperar la mitad derecha que mide 2 pulgadas de largo. 277 00:17:21,790 --> 00:17:23,280 No nos molestemos. 278 00:17:23,280 --> 00:17:26,520 Mi tabla dice simplemente, quédatela. 279 00:17:26,520 --> 00:17:33,750 Y después de haber probado todo eso, sabemos que cortar 4 en 2 y 2 280 00:17:33,750 --> 00:17:36,540 es la mejor opción que tenemos. 281 00:17:36,540 --> 00:17:41,180 282 00:17:41,180 --> 00:17:44,810 Entonces, lo que sucederá es que, a medida que construimos esto, 283 00:17:44,810 --> 00:17:49,550 a la larga llegaremos a donde queríamos con la barra de longitud 10. 284 00:17:49,550 --> 00:17:52,370 Por cada corte que hagamos, podemos simplemente 285 00:17:52,370 --> 00:17:54,350 ver hacia la mitad izquierda y saben que diremos 286 00:17:54,350 --> 00:17:57,380 solo una cosa, pueden buscar en una tabla la mitad derecha 287 00:17:57,380 --> 00:18:00,440 y decir, ¿cuál es el valor máximo que puedo obtener por esto? 288 00:18:00,440 --> 00:18:03,500 Y la tabla dirá: puedes obtener tantos dólares, 289 00:18:03,500 --> 00:18:05,274 y aquí es donde hacemos el primer corte. 290 00:18:05,274 --> 00:18:07,190 Luego nos sobra una pieza más corta 291 00:18:07,190 --> 00:18:09,148 y podemos buscar dónde hacer el siguiente corte. 292 00:18:09,148 --> 00:18:16,910 293 00:18:16,910 --> 00:18:17,510 ¿Preguntas? 294 00:18:17,510 --> 00:18:25,102 295 00:18:25,102 --> 00:18:27,060 Entonces pasemos a otros ejemplos. 296 00:18:27,060 --> 00:18:30,940 El próximo lo veremos muy rápidamente, 297 00:18:30,940 --> 00:18:33,750 al igual que el que le sigue, entraremos en más detalles 298 00:18:33,750 --> 00:18:35,130 incluso en el que cortamos las barras. 299 00:18:35,130 --> 00:18:37,671 Y dibujaremos esa tabla, completando algunos de los valores. 300 00:18:37,671 --> 00:18:41,400 301 00:18:41,400 --> 00:18:44,214 Si recuerdan la red que vimos la semana pasada, 302 00:18:44,214 --> 00:18:47,130 teníamos todo tipo de computadoras que estaban conectadas juntas, por ejemplo, 303 00:18:47,130 --> 00:18:51,300 mi computadora, al menos cuando estoy en mi oficina, 304 00:18:51,300 --> 00:18:55,860 probablemente esté conectada a todo el departamento, a través de un servidor, 305 00:18:55,860 --> 00:18:58,020 o tal vez solo a través del servidor de la Universidad de Yale. 306 00:18:58,020 --> 00:19:00,330 Natalie también tiene una computadora conectada 307 00:19:00,330 --> 00:19:03,600 y dado que nuestras oficinas están cerca, es posible que tengan una conexión 308 00:19:03,600 --> 00:19:06,030 directa entre ellas. 309 00:19:06,030 --> 00:19:11,040 Ahora, David y Doug, en la oficina de CS50 en Harvard, o sus computadoras, 310 00:19:11,040 --> 00:19:13,180 también pueden estar directamente conectados entre sí, 311 00:19:13,180 --> 00:19:16,860 para que puedan enviar mensajes de ida y vuelta directamente, 312 00:19:16,860 --> 00:19:20,650 y también están conectados al servidor de Harvard. 313 00:19:20,650 --> 00:19:27,360 Pero si quiero enviar un mensaje a David, necesitaré, 314 00:19:27,360 --> 00:19:29,950 y podría ser una solicitud HTTP, por ejemplo, 315 00:19:29,950 --> 00:19:33,510 si está ejecutando un servidor web en su computadora 316 00:19:33,510 --> 00:19:36,360 necesitaría encontrar una manera de saltar de computadora a computadora. 317 00:19:36,360 --> 00:19:38,280 No puedo hablar directamente con la computadora de David, 318 00:19:38,280 --> 00:19:41,250 porque no hay cables entre ellas. 319 00:19:41,250 --> 00:19:45,870 Necesito encontrar una computadora para decir, tengo un mensaje para David, 320 00:19:45,870 --> 00:19:47,520 ¿sabes cómo entregarlo? 321 00:19:47,520 --> 00:19:50,315 Y dirá, sí, puedo hacer eso por ti. 322 00:19:50,315 --> 00:19:52,440 Y luego lo transmitirá a otra computadora, 323 00:19:52,440 --> 00:19:54,810 diciendo que eso es para David, y lo seguirán 324 00:19:54,810 --> 00:19:58,680 pasando de servidor en servidor, hasta que lleguen a uno que esté 325 00:19:58,680 --> 00:20:01,770 conectado a la computadora de David. 326 00:20:01,770 --> 00:20:07,569 Y el problema de cómo encontrar a quién pasar ese mensaje se llama enrutamiento. 327 00:20:07,569 --> 00:20:09,360 Y es uno de los problemas en las redes. 328 00:20:09,360 --> 00:20:12,240 Es particularmente difícil porque en las redes, 329 00:20:12,240 --> 00:20:14,790 tenemos que lidiar con otras personas 330 00:20:14,790 --> 00:20:19,530 Cuando escriben alguno de sus programas en la laptop, 331 00:20:19,530 --> 00:20:22,530 si algo sale mal, probablemente fue culpa de ustedes, 332 00:20:22,530 --> 00:20:25,689 y probablemente puedas arreglarlo. 333 00:20:25,689 --> 00:20:27,480 Si estamos hablando de una red, 334 00:20:27,480 --> 00:20:29,970 es posible que alguien haya apagado las luces en otro lugar, 335 00:20:29,970 --> 00:20:33,360 o desenchufó su computadora sin previo aviso. 336 00:20:33,360 --> 00:20:36,252 Eso está completamente fuera de nuestro control. 337 00:20:36,252 --> 00:20:37,710 Pero aun así tenemos que lidiar con eso. 338 00:20:37,710 --> 00:20:41,310 339 00:20:41,310 --> 00:20:44,000 Entonces, ¿cómo llegamos desde mi computadora a la computadora de David? 340 00:20:44,000 --> 00:20:45,791 es algo de lo que tenemos que estar pendientes 341 00:20:45,791 --> 00:20:52,640 y puede seguir cambiando, y para llegar allí, tenemos que encontrar... 342 00:20:52,640 --> 00:20:57,020 no solo cómo podríamos llegar a la computadora de David, 343 00:20:57,020 --> 00:21:02,210 sino, esencialmente, a quién pasar ese mensaje para llegar allí más rápido. 344 00:21:02,210 --> 00:21:05,440 Puede haber más de una forma de hacerlo. 345 00:21:05,440 --> 00:21:07,190 Y una forma será bastante rápida, 346 00:21:07,190 --> 00:21:09,564 y el otro camino pasará por China, Sierra Leona 347 00:21:09,564 --> 00:21:13,760 y por un cable submarino congestionado en África, que tiene enlaces de internet 348 00:21:13,760 --> 00:21:18,830 muy pobres, y tomará mucho tiempo para que el mensaje llegue a David. 349 00:21:18,830 --> 00:21:21,502 A menos que, por supuesto, alguien del MIT haya encontrado 350 00:21:21,502 --> 00:21:23,960 el cable que conecta a Harvard con Yale y lo haya cortado solo por diversión, 351 00:21:23,960 --> 00:21:28,340 en cuyo caso podría quedarme estancado en la ruta más larga por un tiempo, 352 00:21:28,340 --> 00:21:34,229 porque algo que está fuera de mi control se rompió. 353 00:21:34,229 --> 00:21:36,020 Y la pregunta de la que quiero hablar hoy es, 354 00:21:36,020 --> 00:21:41,219 ¿cómo sabes a quién pasarle ese mensaje? 355 00:21:41,219 --> 00:21:43,760 Y este es otro sitio donde la programación dinámica 356 00:21:43,760 --> 00:21:44,635 es realmente útil. 357 00:21:44,635 --> 00:21:48,000 358 00:21:48,000 --> 00:21:50,400 Entonces, la idea es que no solo necesito 359 00:21:50,400 --> 00:21:52,310 saber cómo llegar a la computadora de David, 360 00:21:52,310 --> 00:21:55,400 Necesito saber cómo llegar a todas partes en Internet. 361 00:21:55,400 --> 00:21:57,680 Y todas partes en Internet también necesita 362 00:21:57,680 --> 00:22:00,950 saber cómo llegar a todas partes en internet. 363 00:22:00,950 --> 00:22:04,550 Todo el mundo está tratando de resolver este problema, cómo encontrar la forma 364 00:22:04,550 --> 00:22:06,310 más rápida para llegar a cualquier otra computadora. 365 00:22:06,310 --> 00:22:08,870 366 00:22:08,870 --> 00:22:16,570 Y para empezar, solo estoy enchufado, ni siquiera sé con quién estoy conectado, 367 00:22:16,570 --> 00:22:18,200 y mucho menos sé quién más está por ahí. 368 00:22:18,200 --> 00:22:21,420 369 00:22:21,420 --> 00:22:27,290 Entonces, el proceso es, en lugar de que yo trate de fisgonear y explorar 370 00:22:27,290 --> 00:22:28,826 todo el internet, 371 00:22:28,826 --> 00:22:31,700 y que para cuando termine, alguien haya desenchufado su computadora 372 00:22:31,700 --> 00:22:35,250 y por lo tanto, el proceso necesite cambiar 373 00:22:35,250 --> 00:22:37,400 Quiero intentar y asegurarme de que todos 374 00:22:37,400 --> 00:22:42,330 trabajemos juntos y compartamos la mayor cantidad de información posible. 375 00:22:42,330 --> 00:22:48,800 Entonces, lo que haré es transmitir un mensaje a todos 376 00:22:48,800 --> 00:22:53,370 mis vecinos, diciendo ja, ja, ya llegué, soy Benedict, 377 00:22:53,370 --> 00:22:56,470 y ahora Natalie lo sabrá, y el servidor de Yale lo sabrá, 378 00:22:56,470 --> 00:23:01,550 ajá, la computadora de Benedict está conectada directamente a nosotros. 379 00:23:01,550 --> 00:23:06,075 si necesitamos enviar un mensaje a Benedict, podemos simplemente dárselo. 380 00:23:06,075 --> 00:23:08,450 Ahora, al mismo tiempo, todas las demás harán eso. 381 00:23:08,450 --> 00:23:10,550 Así que recibiré un mensaje de Natalie, diciendo ja, ja, 382 00:23:10,550 --> 00:23:13,840 aquí estoy, y conseguiré uno de Yale diciendo ja, ja, aquí estoy. 383 00:23:13,840 --> 00:23:17,060 384 00:23:17,060 --> 00:23:23,270 Y ahora sé que estoy conectado directamente con Natalie y Yale. 385 00:23:23,270 --> 00:23:27,060 Esto es lo que llamamos estar a un salto de distancia. 386 00:23:27,060 --> 00:23:31,236 Entonces, si necesito enviar un mensaje, necesito hacer un salto, 387 00:23:31,236 --> 00:23:33,110 al igual que un avión hace un salto de ciudad 388 00:23:33,110 --> 00:23:37,460 a ciudad, para llegar a la siguiente computadora. 389 00:23:37,460 --> 00:23:41,720 Y hasta donde yo sé, eso es todo lo que hay en el mundo. 390 00:23:41,720 --> 00:23:46,259 Pero todo el mundo hace esto, así que ahora todos conocen todas las computadoras 391 00:23:46,259 --> 00:23:47,300 que están adyacentes. 392 00:23:47,300 --> 00:23:49,980 393 00:23:49,980 --> 00:23:54,750 Lo siguiente es que todos podemos enviar esa información y decir, 394 00:23:54,750 --> 00:23:59,170 aquí estoy, y oh, por cierto, aquí está todo el mundo con el que estoy conectado. 395 00:23:59,170 --> 00:24:02,880 Entonces, si me dan un mensaje para cualquiera de esas personas, 396 00:24:02,880 --> 00:24:08,040 estoy diciendo a cualquiera que me pase un mensaje para Natalie, 397 00:24:08,040 --> 00:24:09,690 puedo llevárselo de un salto. 398 00:24:09,690 --> 00:24:14,340 399 00:24:14,340 --> 00:24:17,550 Entonces pueden calcular cuántos saltos les toma un salto más que eso 400 00:24:17,550 --> 00:24:18,830 si me pasan el mensaje 401 00:24:18,830 --> 00:24:21,960 402 00:24:21,960 --> 00:24:24,900 Después que compartimos eso, podemos actualizar nuestras listas. 403 00:24:24,900 --> 00:24:30,180 Lo que sucederá es que el servidor de Yale aprendió de mí, ja, ja, ja, 404 00:24:30,180 --> 00:24:33,270 Puedo darle el mensaje a Natalie por ti, solo dámelo y sin escala 405 00:24:33,270 --> 00:24:34,950 se lo daré a Natalie. 406 00:24:34,950 --> 00:24:38,580 Y el servidor de Yale dice, sí, pero yo solo puedo dárselo a Natalie, 407 00:24:38,580 --> 00:24:40,860 ¿por qué molestarme en hacerlo? 408 00:24:40,860 --> 00:24:45,420 El servidor de Yale seguirá en su lista. Sé cómo llegar a Natalie en dos saltos. 409 00:24:45,420 --> 00:24:47,850 no me importa. 410 00:24:47,850 --> 00:24:50,760 Puedo llegar allí de un salto para dárselo directamente a Natalie. 411 00:24:50,760 --> 00:24:54,180 412 00:24:54,180 --> 00:25:01,420 Aprendí que Yale puede alcanzar al servidor de Qwest de un salto. 413 00:25:01,420 --> 00:25:08,670 Si necesito pasarle un mensaje a Qwest, le daría el mensaje a Yale 414 00:25:08,670 --> 00:25:11,430 y le pediría que se lo dé a Qwest, esa es 415 00:25:11,430 --> 00:25:12,990 la manera más rápida que conozco para llegar ahí. 416 00:25:12,990 --> 00:25:15,520 417 00:25:15,520 --> 00:25:18,360 En cada paso, todo el mundo envía un mensaje bastante corto 418 00:25:18,360 --> 00:25:20,730 a todos sus vecinos. 419 00:25:20,730 --> 00:25:23,504 Toma una cantidad de tiempo fija. 420 00:25:23,504 --> 00:25:25,920 Acumulamos esta información y siempre mantenemos 421 00:25:25,920 --> 00:25:29,310 el seguimiento de, ¿cuál fue el más corto? 422 00:25:29,310 --> 00:25:32,252 ¿cuál tomó el menor número de saltos para llegar a un servidor? 423 00:25:32,252 --> 00:25:34,210 ¿y a quién le daremos el mensaje al llegar ahí? 424 00:25:34,210 --> 00:25:40,240 425 00:25:40,240 --> 00:25:42,069 Siempre que le dé el mensaje a Yale, 426 00:25:42,069 --> 00:25:44,860 Yale se preocupará de cómo dárselo a Qwest, me prometió que solo 427 00:25:44,860 --> 00:25:46,600 tomaría un salto. 428 00:25:46,600 --> 00:25:50,680 Si hago esto de nuevo, podría llegar a Google en tres saltos. 429 00:25:50,680 --> 00:25:53,057 Puedo llegar a Harvard en tres saltos. 430 00:25:53,057 --> 00:25:56,140 Lo único importante es que llegaría en tres saltos y la manera en que le 431 00:25:56,140 --> 00:26:00,010 daría el mensaje al servidor de Yale. 432 00:26:00,010 --> 00:26:04,510 Incluso el servidor de Yale no sabe cómo hablar directamente con el de Harvard 433 00:26:04,510 --> 00:26:07,120 o con el servidor de Google. 434 00:26:07,120 --> 00:26:10,220 Solo sabe pasar el mensaje al servidor de Qwest. 435 00:26:10,220 --> 00:26:13,390 Por cierto, Qwest, posee muchas de las grandes fibras que 436 00:26:13,390 --> 00:26:16,420 conectan grandes centros de datos y otras cosas. 437 00:26:16,420 --> 00:26:18,940 Al trazar lo que sucede, si intento conectarme 438 00:26:18,940 --> 00:26:22,270 desde mi oficina al servidor de Google, atraviesa el servidor del 439 00:26:22,270 --> 00:26:27,010 departamento CS, luego un servidor de Yale, luego va a Qwest, 440 00:26:27,010 --> 00:26:28,315 y luego va a Google. 441 00:26:28,315 --> 00:26:31,720 442 00:26:31,720 --> 00:26:35,170 Hay algunos otros, como Internet2, 443 00:26:35,170 --> 00:26:42,040 que conecta a muchas universidades y America Online 444 00:26:42,040 --> 00:26:48,040 que ​​tenía mucho de esto, no sé si alguna vez lo vendieron. 445 00:26:48,040 --> 00:26:50,290 Existen algunas compañías que poseen la mayoría de esos cables. 446 00:26:50,290 --> 00:26:54,440 447 00:26:54,440 --> 00:26:59,640 Finalmente, después de cuatro rondas, descubro que incluso llegaría con David 448 00:26:59,640 --> 00:27:03,050 y Doug, en cuatro saltos para darle el mensaje a Yale. 449 00:27:03,050 --> 00:27:04,910 Yale sabe que solo necesita darle 450 00:27:04,910 --> 00:27:11,240 ese mensaje a Qwest, que le da ese mensaje a Harvard, 451 00:27:11,240 --> 00:27:15,020 y luego Harvard sabe cómo pasar el mensaje. 452 00:27:15,020 --> 00:27:18,950 Así es, cómo los principales enrutadores de Internet 453 00:27:18,950 --> 00:27:22,100 comparten esta información. 454 00:27:22,100 --> 00:27:24,680 Nuestras computadoras, o mi computadora, lo que generalmente saben es que 455 00:27:24,680 --> 00:27:28,115 cualquier mensaje que necesito enviar lo envío del servidor al que estoy conectado, 456 00:27:28,115 --> 00:27:30,260 al punto de acceso inalámbrico. 457 00:27:30,260 --> 00:27:35,570 El punto de acceso inalámbrico se lo envía al servidor de Yale. 458 00:27:35,570 --> 00:27:38,690 Tal vez hay una muy pequeña, que sabe que las siguientes laptops se 459 00:27:38,690 --> 00:27:42,080 conectan directamente a mí, y que todo lo demás lo envié al servidor de Yale. 460 00:27:42,080 --> 00:27:49,280 Pero cuando llega al nivel de toda la Universidad de Yale 461 00:27:49,280 --> 00:27:55,670 puede iniciar el proceso de compartir esta información 462 00:27:55,670 --> 00:28:00,530 para saber si podría hablar con Qwest, si podría hablar con Internet2, 463 00:28:00,530 --> 00:28:05,090 si podría hablar con Comcast, hay muchas personas con las que podría hablar. 464 00:28:05,090 --> 00:28:07,040 ¿A cuál cable debería enviar este mensaje 465 00:28:07,040 --> 00:28:11,300 para asegurarme que llegará a donde va? 466 00:28:11,300 --> 00:28:17,360 Y el aspecto de programación dinámica de esto es, que en cada paso 467 00:28:17,360 --> 00:28:20,870 estoy reutilizando toda la información que se calculó antes 468 00:28:20,870 --> 00:28:22,640 para simplemente agregar otra capa en la parte superior. 469 00:28:22,640 --> 00:28:25,540 ¿Cómo llego a lugares en tres saltos? 470 00:28:25,540 --> 00:28:31,850 No estoy recalculando la ruta para ir de Yale a David, 471 00:28:31,850 --> 00:28:35,540 por así decirlo, cuando descubro que puedo llegar allí en cuatro saltos. 472 00:28:35,540 --> 00:28:40,310 Solo utilizo la información que tengo de que el servidor de Yale puede hacerlo. 473 00:28:40,310 --> 00:28:44,400 Y eso reduce la cantidad de trabajo que debo hacer. 474 00:28:44,400 --> 00:28:50,030 475 00:28:50,030 --> 00:28:51,262 ¿Alguna pregunta? 476 00:28:51,262 --> 00:29:02,350 477 00:29:02,350 --> 00:29:05,930 Ahora, la tercera categoría de algoritmo de la que quiero hablar, 478 00:29:05,930 --> 00:29:08,630 y voy a hablar sobre esto con un poco más de detalle, 479 00:29:08,630 --> 00:29:11,810 hablaré de algunas aplicaciones diferentes que tienen exactamente 480 00:29:11,810 --> 00:29:15,410 el mismo algoritmo, entonces, no solo es programación dinámica 481 00:29:15,410 --> 00:29:20,450 sino un algoritmo específico que puede resolver diferentes problemas. 482 00:29:20,450 --> 00:29:24,920 Y comenzaré con la alineación de la secuencia de ADN, 483 00:29:24,920 --> 00:29:29,420 también se utiliza para alinear secuencias de proteínas. 484 00:29:29,420 --> 00:29:32,810 Si se tiene una secuencia de ADN, esta se compone 485 00:29:32,810 --> 00:29:38,030 de una cadena de algo que se llaman bases, los cuales son productos químicos. 486 00:29:38,030 --> 00:29:38,790 Son moléculas. 487 00:29:38,790 --> 00:29:42,920 Y hay cuatro de ellas que se usan en el ADN, 488 00:29:42,920 --> 00:29:46,770 adenina, timina, guanina y citosina. 489 00:29:46,770 --> 00:29:50,180 Y por lo general abreviaremos cada una con una letra. 490 00:29:50,180 --> 00:29:53,000 491 00:29:53,000 --> 00:29:57,280 Entonces, si tuvieran que desenrollar una secuencia de ADN, 492 00:29:57,280 --> 00:30:00,940 y simplemente escriben la lista de estas bases de estas moléculas 493 00:30:00,940 --> 00:30:03,790 que están conectadas en una larga cadena, esencialmente 494 00:30:03,790 --> 00:30:07,370 obtendrían una cadena compuesta de cuatro letras. 495 00:30:07,370 --> 00:30:14,770 Entonces es una cadena con alguna combinación de los caracteres A, C, G y T. 496 00:30:14,770 --> 00:30:22,690 Ahora bien, es posible que sepa de memoria todo el genoma de un ratón 497 00:30:22,690 --> 00:30:25,360 y sepa lo que hace cada gen. 498 00:30:25,360 --> 00:30:28,570 O que al menos sepa lo que algunos de ellos hacen. 499 00:30:28,570 --> 00:30:35,200 Con el tiempo divergimos de los ratones y varias mutaciones pasaron a nuestro ADN, 500 00:30:35,200 --> 00:30:38,440 porque cada vez que se copia, a veces se cometen errores, 501 00:30:38,440 --> 00:30:41,290 y de alguna manera acabamos siendo, en vez de un ratón proto, 502 00:30:41,290 --> 00:30:43,600 un ser un humano moderno. 503 00:30:43,600 --> 00:30:47,080 Y ese mismo ratón proto terminó siendo un ratón moderno. 504 00:30:47,080 --> 00:30:49,370 a través de diferentes mutaciones. 505 00:30:49,370 --> 00:30:54,190 Entonces, si empiezo a secuenciar mi ADN, podría encontrar 506 00:30:54,190 --> 00:30:57,190 un fragmento que corresponde a un gen particular 507 00:30:57,190 --> 00:31:01,120 y no sé lo que hace, pero me gustaría averiguarlo. 508 00:31:01,120 --> 00:31:06,640 Una forma de hacerlo sería tratar de hacer coincidir y encontrar 509 00:31:06,640 --> 00:31:12,070 el mejor lugar posible para que coincida con el gen del ADN del ratón, 510 00:31:12,070 --> 00:31:14,262 ¿coincide con el mejor? 511 00:31:14,262 --> 00:31:17,470 Teniendo en cuenta que podría haber gaps, un gen podría haber desaparecido, 512 00:31:17,470 --> 00:31:21,550 otro haber reaparecido o ser agregado, y algunas veces una de estas bases 513 00:31:21,550 --> 00:31:24,314 podrían haber sido reemplazadas por otras diferentes. 514 00:31:24,314 --> 00:31:25,480 Entonces podríamos tener una disparidad 515 00:31:25,480 --> 00:31:27,355 y podrían suceder diferentes cosas 516 00:31:27,355 --> 00:31:31,282 durante el proceso, en el ratón no será un gen idéntico perfecto 517 00:31:31,282 --> 00:31:34,000 al del ser humano, será más o menos lo mismo. 518 00:31:34,000 --> 00:31:37,000 Y podría usar eso para decir cuál es la mejor combinación 519 00:31:37,000 --> 00:31:43,030 y luego usar aquello para predecir lo que codifica este gen, 520 00:31:43,030 --> 00:31:46,070 o cuál es la función de la proteína que codifica. 521 00:31:46,070 --> 00:31:49,210 Podemos hacer lo mismo con las proteínas, porque están hechas de aminoácidos. 522 00:31:49,210 --> 00:31:53,740 Podemos observar esa cadena y buscar cosas similares entre una proteína 523 00:31:53,740 --> 00:31:56,466 y una base de datos de proteínas donde sabemos lo que hacen 524 00:31:56,466 --> 00:31:58,090 para ver si podemos predecir la función. 525 00:31:58,090 --> 00:32:01,900 526 00:32:01,900 --> 00:32:05,740 Pero el problema es que hay muchas maneras diferentes de hacerlo. 527 00:32:05,740 --> 00:32:11,150 528 00:32:11,150 --> 00:32:24,160 A continuación escribiré en la pizarra estos que tenemos, AAC, AGT, TACC. 529 00:32:24,160 --> 00:32:28,190 530 00:32:28,190 --> 00:32:32,210 Ahora, intentaré encontrar la peor coincidencia posible. 531 00:32:32,210 --> 00:32:39,250 532 00:32:39,250 --> 00:32:39,750 TAAGGTCA. 533 00:32:39,750 --> 00:32:56,000 534 00:32:56,000 --> 00:33:00,960 Entonces, hay diferentes formas posibles para alinear estas cadenas. 535 00:33:00,960 --> 00:33:04,350 No tienen la misma longitud, así que necesitaré algunos gaps. 536 00:33:04,350 --> 00:33:07,530 Hay diferentes lugares donde podría intentar ponerlas y ver 537 00:33:07,530 --> 00:33:09,780 cómo se alinean los caracteres. 538 00:33:09,780 --> 00:33:12,330 Y la regla va a ser... 539 00:33:12,330 --> 00:33:16,200 y se basa, de hecho, en cuán común 540 00:33:16,200 --> 00:33:20,190 es para que ocurra una mutación donde una base 541 00:33:20,190 --> 00:33:23,850 cambia a otra, en lugar de que una base se borre o se agregue 542 00:33:23,850 --> 00:33:25,710 en mutaciones genéticas. 543 00:33:25,710 --> 00:33:29,490 Resulta que es casi dos veces más probable que una base simplemente 544 00:33:29,490 --> 00:33:36,060 cambie a otra base, a que una base desaparezca o aparezca completamente 545 00:33:36,060 --> 00:33:37,470 de la nada 546 00:33:37,470 --> 00:33:38,640 durante la mutación. 547 00:33:38,640 --> 00:33:41,480 Entonces diremos que cuando alineamos las cadenas, 548 00:33:41,480 --> 00:33:44,280 cada vez que tengamos una disparidad entre dos caracteres, 549 00:33:44,280 --> 00:33:46,124 de modo que dos bases no sean lo mismo, 550 00:33:46,124 --> 00:33:47,790 vamos a tener una penalización de 1. 551 00:33:47,790 --> 00:33:50,640 552 00:33:50,640 --> 00:33:53,010 Y tenemos un costo de uno. 553 00:33:53,010 --> 00:33:57,480 Eso es lo que pagamos por forzar a las cadenas para que coincidan así. 554 00:33:57,480 --> 00:34:08,020 Y cada vez que tenemos un gap donde, digamos, la C de la primer cadena o 555 00:34:08,020 --> 00:34:11,320 secuencia de ADN no coincide en nada con la segunda, 556 00:34:11,320 --> 00:34:16,090 de modo que eso corresponde a una base que se inserta o elimina, 557 00:34:16,090 --> 00:34:19,630 le asignaremos una penalización o un costo de 2. 558 00:34:19,630 --> 00:34:22,810 Así que preferimos tener dos mutaciones, 559 00:34:22,810 --> 00:34:26,090 dos cosas cuya base se convirtió en otra cosa, 560 00:34:26,090 --> 00:34:29,170 eso parece tan probable como tener algo que simplemente se agregó o se eliminó. 561 00:34:29,170 --> 00:34:31,687 562 00:34:31,687 --> 00:34:33,520 Y luego puedo sumar todos esos costos 563 00:34:33,520 --> 00:34:38,690 y obtener el costo de esa forma particular de igualar las cadenas. 564 00:34:38,690 --> 00:34:43,270 Y busco la manera de lograrlo con el menor costo de coincidencia posible. 565 00:34:43,270 --> 00:34:47,530 A esto se le llama también edición de distancia, porque también 566 00:34:47,530 --> 00:34:50,165 mide el número de ediciones que tendría que aplicar a un texto, 567 00:34:50,165 --> 00:34:53,290 cuántos cambios tendría que hacer en un texto para cambiarlo de una cosa 568 00:34:53,290 --> 00:34:56,480 a otra. 569 00:34:56,480 --> 00:34:58,500 No solo tiene que ser estas cuatro letras. 570 00:34:58,500 --> 00:34:59,458 Esto podría ser cualquier cosa. 571 00:34:59,458 --> 00:35:03,170 572 00:35:03,170 --> 00:35:06,050 Pero lo que he escrito en la pizarra y que quiero que vean 573 00:35:06,050 --> 00:35:09,950 es la peor manera en la que podría hacer coincidir esto, es decir, 574 00:35:09,950 --> 00:35:16,010 ¿Qué pasa si acabo de eliminar todo el gen del ratón, 575 00:35:16,010 --> 00:35:21,470 y luego hice un montón de inserciones para producir el gen completo del humano? 576 00:35:21,470 --> 00:35:25,810 Entonces, cada uno de estos caracteres, decimos, coincide con un gap. 577 00:35:25,810 --> 00:35:27,120 Esa es una posibilidad. 578 00:35:27,120 --> 00:35:28,730 No es muy buena. 579 00:35:28,730 --> 00:35:32,090 Eso sería 2 + 2 + 2 + 2 + 2 + 2, bla, bla, bla, 580 00:35:32,090 --> 00:35:33,724 bla, bla, bla. 581 00:35:33,724 --> 00:35:34,640 Eso costaría mucho. 582 00:35:34,640 --> 00:35:38,390 Esa es una manera muy poco probable de que hubiésemos llegado de esto a esto, 583 00:35:38,390 --> 00:35:40,140 y estamos buscando la forma más probable. 584 00:35:40,140 --> 00:35:42,890 585 00:35:42,890 --> 00:35:47,720 Pero lo que dice es que realmente no tiene sentido insertar más 586 00:35:47,720 --> 00:35:51,290 gaps en el medio, porque esas cosas se alinean perfectamente, 587 00:35:51,290 --> 00:35:54,380 no cambiarán el puntaje de coincidencia. 588 00:35:54,380 --> 00:35:55,430 Eso es un poco tonto. 589 00:35:55,430 --> 00:35:57,620 Una vez que esto se haya ido por completo, también podría 590 00:35:57,620 --> 00:36:00,750 comenzar a agregar el nuevo. 591 00:36:00,750 --> 00:36:04,910 Así que la secuencia más larga posible donde tratamos de alinear los dos 592 00:36:04,910 --> 00:36:08,345 es la longitud de uno más la longitud del otro, que aquí es aproximadamente 18. 593 00:36:08,345 --> 00:36:11,000 594 00:36:11,000 --> 00:36:12,920 Y ahora, si observamos cada una de estas columnas, 595 00:36:12,920 --> 00:36:14,750 hicimos una especie de elección. 596 00:36:14,750 --> 00:36:18,560 De la misma manera con la barra pudimos elegir, ¿cortamos o no cortamos? 597 00:36:18,560 --> 00:36:22,980 Aquí tenemos una opción para hacer una eliminación 598 00:36:22,980 --> 00:36:25,790 así que tuvimos una letra en la primer cadena 599 00:36:25,790 --> 00:36:30,950 y haremos coincidir con un gap la segunda cadena, como si esta letra se borrara. 600 00:36:30,950 --> 00:36:35,180 O podríamos hacer una inserción, en cuyo caso es algo así como esta situación 601 00:36:35,180 --> 00:36:37,670 donde no teníamos nada y agregamos una letra. 602 00:36:37,670 --> 00:36:40,040 Podríamos hacer eso al comienzo de la cadena 603 00:36:40,040 --> 00:36:43,760 o podríamos tratar de hacer coincidir dos letras. 604 00:36:43,760 --> 00:36:49,180 Entonces aquí, en cada punto, podemos elegir entre tres opciones, 605 00:36:49,180 --> 00:36:53,450 una inserción, una eliminación o una coincidencia. 606 00:36:53,450 --> 00:36:57,830 Y si pudiéramos hacer esa elección de forma independiente, 607 00:36:57,830 --> 00:37:02,510 entre cada una de las letras, tendríamos 3 a la 17 combinaciones posibles 608 00:37:02,510 --> 00:37:05,390 de cosas para probar. 609 00:37:05,390 --> 00:37:06,567 Eso es demasiado. 610 00:37:06,567 --> 00:37:07,650 ¿Cuánto es del 3 a la 17? 611 00:37:07,650 --> 00:37:13,569 612 00:37:13,569 --> 00:37:15,360 ¿Alguien sabe la respuesta aproximada? 613 00:37:15,360 --> 00:37:19,510 614 00:37:19,510 --> 00:37:22,430 OK, el término técnico es, demasiado. 615 00:37:22,430 --> 00:37:23,206 Es un número n. 616 00:37:23,206 --> 00:37:24,455 Se define como 3 a la 17. 617 00:37:24,455 --> 00:37:28,480 618 00:37:28,480 --> 00:37:31,360 Entonces, de nuevo, no queremos seguir... 619 00:37:31,360 --> 00:37:34,810 no queremos probar todo. 620 00:37:34,810 --> 00:37:36,930 Lo que realmente queremos es esto. 621 00:37:36,930 --> 00:37:41,490 Los biólogos computacionales quieren descubrir, observar 622 00:37:41,490 --> 00:37:45,930 a través de una base de datos de genes o de proteínas 623 00:37:45,930 --> 00:37:50,370 y trata de hacer coincidir algo para descubrir qué podría hacer. 624 00:37:50,370 --> 00:37:53,340 Qué partes del genoma que acabamos de secuenciar 625 00:37:53,340 --> 00:37:56,550 o de la cadena de ADN que acabamos de secuenciar vale la pena poner a cero, 626 00:37:56,550 --> 00:38:01,223 y hacer más estudios al respecto, porque podrían codificar algo importante. 627 00:38:01,223 --> 00:38:04,540 628 00:38:04,540 --> 00:38:06,840 Resulta que también nos gusta hacer esto también en ocasiones, 629 00:38:06,840 --> 00:38:12,630 o al menos lo hacemos, cuando queremos revisar las tareas de dos personas 630 00:38:12,630 --> 00:38:13,980 y ver qué tan similares son. 631 00:38:13,980 --> 00:38:16,660 632 00:38:16,660 --> 00:38:23,010 Entonces, esencialmente, los detectores de plagio hacen eso. 633 00:38:23,010 --> 00:38:26,130 Tratan de calcular rápidamente cuántos cambios tendría que 634 00:38:26,130 --> 00:38:36,060 aplicar al programa de un estudiante para convertirlo en el programa de otro. 635 00:38:36,060 --> 00:38:40,740 Y una vez que lo hayamos calculado, queremos buscar y encontrar a los que, 636 00:38:40,740 --> 00:38:44,250 para la mayoría, tal vez les tomó mil ediciones, 637 00:38:44,250 --> 00:38:48,070 pero aquí tenemos a un par que hicieron solo dos. 638 00:38:48,070 --> 00:38:49,320 Y eso es algo sospechoso. 639 00:38:49,320 --> 00:38:56,780 640 00:38:56,780 --> 00:38:59,840 Voy a replantear el problema. 641 00:38:59,840 --> 00:39:02,930 Y será similar al del corte de barras, donde voy a decir, 642 00:39:02,930 --> 00:39:09,760 Imaginemos que ya sé cómo hacer coincidir la parte derecha de dos 643 00:39:09,760 --> 00:39:10,385 de las cadenas. 644 00:39:10,385 --> 00:39:13,170 645 00:39:13,170 --> 00:39:23,217 Entonces, si ya conozco la mejor manera de unir GTTACC a GTCA, 646 00:39:23,217 --> 00:39:25,550 y luego para descubrir la mejor manera de hacer coincidir todo 647 00:39:25,550 --> 00:39:29,150 solo tengo que descubrir cómo hacer la primera parte. 648 00:39:29,150 --> 00:39:31,160 Y esto es como decir, déjame determinar 649 00:39:31,160 --> 00:39:37,460 dónde voy a poner la primera letra de la primera palabra, 650 00:39:37,460 --> 00:39:41,600 dónde quiero poner el primer gap, digamos, o la primera inserción, 651 00:39:41,600 --> 00:39:43,670 y luego descubre el resto. 652 00:39:43,670 --> 00:39:46,533 Pero lo expreso yendo desde el final hasta el principio. 653 00:39:46,533 --> 00:39:51,122 654 00:39:51,122 --> 00:39:53,330 Y lo fraseo yendo al final del inicio 655 00:39:53,330 --> 00:39:57,410 tal como lo que he mostrado aquí, porque cuando 656 00:39:57,410 --> 00:40:00,230 calcule la tabla, terminará poniendo 657 00:40:00,230 --> 00:40:04,580 la respuesta en un lugar más lógico. 658 00:40:04,580 --> 00:40:11,210 Así que podemos decir, en la última posición de esta coincidencia 659 00:40:11,210 --> 00:40:15,260 vamos a tener una inserción, vamos a tener una eliminación 660 00:40:15,260 --> 00:40:19,160 o vamos a tratar de hacer coincidir dos caracteres 661 00:40:19,160 --> 00:40:21,980 Eso nos da tres posibilidades 662 00:40:21,980 --> 00:40:23,015 y cada uno tiene un costo. 663 00:40:23,015 --> 00:40:25,850 664 00:40:25,850 --> 00:40:31,190 Así que cualquiera que sea la mejor manera de alinear estas dos cadenas, 665 00:40:31,190 --> 00:40:36,990 lo último que sucederá será una de estas tres cosas 666 00:40:36,990 --> 00:40:42,750 esas son las únicas tres formas posibles para que ocurra la última parte 667 00:40:42,750 --> 00:40:43,402 de la coincidencia, 668 00:40:43,402 --> 00:40:45,360 tiene que ser una inserción, una eliminación o una coincidencia, 669 00:40:45,360 --> 00:40:46,950 porque son las únicas opciones. 670 00:40:46,950 --> 00:40:49,622 671 00:40:49,622 --> 00:40:51,330 Si conocemos los costos de ello, entonces 672 00:40:51,330 --> 00:40:57,270 podemos decir que el costo de hacer coincidir toda la cadena es el costo de 673 00:40:57,270 --> 00:41:04,230 cualquier elección más el mejor costo de edición de distancia, o mejor alineación, 674 00:41:04,230 --> 00:41:07,440 de lo que quede. 675 00:41:07,440 --> 00:41:12,450 Lo cual es ligeramente diferente en cada uno de estos tres casos. 676 00:41:12,450 --> 00:41:23,100 Excepto que si, por ejemplo, hacemos una eliminación y luego para esta elección 677 00:41:23,100 --> 00:41:28,080 donde tenemos TAAGGTCA en la parte inferior, la próxima vez 678 00:41:28,080 --> 00:41:32,730 tratamos de hacer una inserción, y luego a lo mejor de lo que quede, 679 00:41:32,730 --> 00:41:39,540 tendríamos una coincidencia de AACAGTTACC con TAAGGTC. 680 00:41:39,540 --> 00:41:44,790 Luego tendríamos que insertar A y después eliminar C. 681 00:41:44,790 --> 00:41:47,190 Perdón, terminaríamos con estas dos cadenas. 682 00:41:47,190 --> 00:41:49,140 Pero en lugar de que tratemos de hacer coincidir C con A, 683 00:41:49,140 --> 00:41:52,320 habríamos modelado una inserción y una eliminación. 684 00:41:52,320 --> 00:41:53,890 Nos quedaría lo mismo aquí. 685 00:41:53,890 --> 00:41:56,620 686 00:41:56,620 --> 00:41:59,740 Así que, a medida que construimos estas cosas, 687 00:41:59,740 --> 00:42:04,020 evitamos hallar la mejor coincidencia dos veces para el mismo par de cadenas . 688 00:42:04,020 --> 00:42:09,430 689 00:42:09,430 --> 00:42:15,430 Y, de manera realista, lo que va a pasar es que podemos comenzar con, bueno, 690 00:42:15,430 --> 00:42:19,390 ¿y si ambas cadenas estuvieran vacías? 691 00:42:19,390 --> 00:42:22,220 Entonces coincidirían perfectamente. 692 00:42:22,220 --> 00:42:24,980 No hay problema. 693 00:42:24,980 --> 00:42:29,890 ¿Qué pasa si al final quisiera 694 00:42:29,890 --> 00:42:35,980 que la cadena C o el carácter C fuera eliminado? 695 00:42:35,980 --> 00:42:44,310 Me gustaría tener algún tipo de coincidencia aquí 696 00:42:44,310 --> 00:42:52,170 donde lo último que sucede es que C se elimina, 697 00:42:52,170 --> 00:42:56,940 y el resto de ese TAA, bla, bla, bla, bla, está en algún lugar de aquí. 698 00:42:56,940 --> 00:43:00,990 Pero me preocuparé más tarde de dónde. 699 00:43:00,990 --> 00:43:12,100 Entonces, en ese caso, tenemos un costo de 2 y cuando terminamos, 700 00:43:12,100 --> 00:43:16,090 hubiéramos usado este carácter C, porque lo borramos. 701 00:43:16,090 --> 00:43:24,430 Y lo que nos queda después de eso es lo que está en la celda correspondiente, 702 00:43:24,430 --> 00:43:29,410 a la derecha en la tabla, que es el costo de igualar nada a nada. 703 00:43:29,410 --> 00:43:32,560 Del mismo modo, si dijéramos que lo último que queremos tener en la tabla 704 00:43:32,560 --> 00:43:39,040 es una coincidencia de CC a nada, el costo de eso 705 00:43:39,040 --> 00:43:46,980 es 2 para la coincidencia, la eliminación de C, más el costo de igualar nada, 706 00:43:46,980 --> 00:43:50,140 C a nada, lo cual era esta celda en la tabla. 707 00:43:50,140 --> 00:43:55,267 Así que tenemos 2 más el costo de 2, que aquí es 4. 708 00:43:55,267 --> 00:43:57,850 Entonces, en general, lo que sucederá, si observo la celda 709 00:43:57,850 --> 00:44:01,950 donde ahora está la manita... 710 00:44:01,950 --> 00:44:05,530 que justo desapareció, aquí, este es el costo, 711 00:44:05,530 --> 00:44:13,540 bueno, básicamente registraremos el costo de igualar GTTACC a GGTCA. 712 00:44:13,540 --> 00:44:16,451 713 00:44:16,451 --> 00:44:22,160 Y dirá... para obtener la mejor combinación entre estos, 714 00:44:22,160 --> 00:44:25,700 es decir, la menor edición de distancia, si quieren verlo así, 715 00:44:25,700 --> 00:44:28,930 aquí está lo que será el costo total y les dirá que deberían 716 00:44:28,930 --> 00:44:33,610 tratar de hacer coincidir esas dos G entre sí, o que deberían hacerlo como... 717 00:44:33,610 --> 00:44:36,970 que deberían tener una eliminación o una inserción 718 00:44:36,970 --> 00:44:39,700 Eso es lo que se almacenará en esta celda de la tabla. 719 00:44:39,700 --> 00:44:43,870 Y, finalmente, eso significa en la entrada 0, 0 de la matriz 720 00:44:43,870 --> 00:44:46,390 al inicio de la tabla, les dirá el costo 721 00:44:46,390 --> 00:44:50,030 de hacer coincidir AACAGTTACC a TAAGGTCA. 722 00:44:50,030 --> 00:44:53,125 723 00:44:53,125 --> 00:44:55,360 Les dirá cuál es el costo total y 724 00:44:55,360 --> 00:44:57,735 les dirá si deben comenzar con la inserción, 725 00:44:57,735 --> 00:44:59,260 la eliminación o una coincidencia. 726 00:44:59,260 --> 00:45:04,480 Y dependiendo de cuál, eso agotará los caracteres de una 727 00:45:04,480 --> 00:45:07,640 o de ambas cadenas, las cuales los moverán a una nueva celda en la tabla 728 00:45:07,640 --> 00:45:08,890 que les dirá qué hacer a continuación. 729 00:45:08,890 --> 00:45:13,800 730 00:45:13,800 --> 00:45:19,070 Así que una vez que está preparado puedo decir al final, bueno, 731 00:45:19,070 --> 00:45:25,882 si observo el final de cada cadena, tengo que hacer coincidir la letra C con la letra A. 732 00:45:25,882 --> 00:45:29,000 ¿Y cuál es la mejor manera de hacerlo? 733 00:45:29,000 --> 00:45:32,100 Bueno, tengo tres opciones. 734 00:45:32,100 --> 00:45:42,680 Una opción es que podría eliminar la C. Oh, hay un error aquí, 735 00:45:42,680 --> 00:45:45,170 debería leerse i + 1. 736 00:45:45,170 --> 00:45:48,110 Entonces podría decir, déjame ir sobre el costo de i + 1. 737 00:45:48,110 --> 00:45:53,330 Así que he usado C. Pero me quedaré en... 738 00:45:53,330 --> 00:45:58,510 perdón, i + 1 es esta fila, pero me quedaré en la columna j... 739 00:45:58,510 --> 00:46:02,435 así que me voy a pasar para acá, la cual dice que he agotado la A, 740 00:46:02,435 --> 00:46:08,670 así que esta A de aquí coincidió con un gap, el cual es como una inserción. 741 00:46:08,670 --> 00:46:12,124 Dice, en algún lugar al final de la tabla, 742 00:46:12,124 --> 00:46:14,290 voy a terminar con esa A de la segunda cadena. 743 00:46:14,290 --> 00:46:17,550 744 00:46:17,550 --> 00:46:20,120 Y, oh, aún tengo la C flotando alrededor. 745 00:46:20,120 --> 00:46:30,020 746 00:46:30,020 --> 00:46:31,800 Dejen vuelvo a utilizar la tiza blanca. 747 00:46:31,800 --> 00:46:37,260 748 00:46:37,260 --> 00:46:42,210 Pero el sobrante, aún tenemos una C aquí, 749 00:46:42,210 --> 00:46:45,840 porque estábamos tratando de hacer coincidir A a C, y hasta ahora 750 00:46:45,840 --> 00:46:50,760 no he tratado con esa C. Así que tendríamos 751 00:46:50,760 --> 00:46:53,260 el costo de emparejar A con un gap, el cual es 2, 752 00:46:53,260 --> 00:46:59,040 más cualquiera que sea el costo de igualar C a nada, el cual es 2. 753 00:46:59,040 --> 00:47:17,770 O podríamos decir qué pasaría si, en lugar de eso, hiciéramos C 754 00:47:17,770 --> 00:47:22,090 y borráramos C en lugar de insertar A, 755 00:47:22,090 --> 00:47:25,900 pero significa que todavía tenemos una A flotando por aquí, que aún no hemos usado. 756 00:47:25,900 --> 00:47:30,750 Esa fue una forma alternativa de comparar C y A. Entonces, tenemos un costo de 2, 757 00:47:30,750 --> 00:47:34,510 porque estamos haciendo una eliminación. 758 00:47:34,510 --> 00:47:40,930 Además, nos queda el costo de la celda que está 759 00:47:40,930 --> 00:47:45,940 a la derecha de la tabla, de hacer coincidir a la cadena A con nada, 760 00:47:45,940 --> 00:47:47,215 y eso sería un costo de 4. 761 00:47:47,215 --> 00:47:51,460 762 00:47:51,460 --> 00:48:06,200 O podríamos tratar de hacer coincidir C y A. Y cuando hacen coincidir C y A, 763 00:48:06,200 --> 00:48:08,930 el costo de esto es cero si las letras son las mismas y uno 764 00:48:08,930 --> 00:48:10,950 si son diferentes. 765 00:48:10,950 --> 00:48:15,350 Entonces, en este caso es uno, porque C y A no son la misma letra. 766 00:48:15,350 --> 00:48:19,350 Y nos quedan dos cadenas vacías, porque hemos agotado la C y la A. 767 00:48:19,350 --> 00:48:23,540 Así que terminamos con 1, más el costo de lo que esté sobre 1 768 00:48:23,540 --> 00:48:27,590 y abajo 1 en la tabla, el cual es 0. 769 00:48:27,590 --> 00:48:29,900 Entonces ese costo total es de 1. 770 00:48:29,900 --> 00:48:33,700 Y de esas tres posibilidades, simplemente tomamos la más pequeña. 771 00:48:33,700 --> 00:48:38,330 Decimos, ah, el más pequeño sería si fuera diagonal, si hiciera coincidir A y C. 772 00:48:38,330 --> 00:48:40,730 Entonces, eso es lo que registraré en la tabla. 773 00:48:40,730 --> 00:48:46,040 El costo total de igualar A a C es uno, y lo mejor que se puede hacer 774 00:48:46,040 --> 00:48:48,130 es tratar de hacer coincidir estos dos caracteres. 775 00:48:48,130 --> 00:48:50,180 Sería una disparidad. 776 00:48:50,180 --> 00:48:52,880 Y luego buscar en la tabla qué hacer con lo que quede. 777 00:48:52,880 --> 00:48:58,530 778 00:48:58,530 --> 00:49:03,016 Y ahora podría decir, bueno, ¿qué pasa si hago coincidir la cadena CC a A? 779 00:49:03,016 --> 00:49:06,550 Puedo hacer la misma pregunta. 780 00:49:06,550 --> 00:49:10,580 Podría decir que comenzaría por unir las letras C y A, 781 00:49:10,580 --> 00:49:14,230 y ahora tengo un C sobrante. 782 00:49:14,230 --> 00:49:17,820 Podría eliminar la primera C y ahora tengo una A y una C sobrantes. 783 00:49:17,820 --> 00:49:22,990 784 00:49:22,990 --> 00:49:25,732 Y sería de la siguiente manera. 785 00:49:25,732 --> 00:49:26,690 Lo siento, si hago coincidir ambos. 786 00:49:26,690 --> 00:49:27,773 Podría tener una C sobrante. 787 00:49:27,773 --> 00:49:31,930 Si borro... si solo comienzo con una C y hago una eliminación, 788 00:49:31,930 --> 00:49:34,300 termino con una C y una A sobrante. 789 00:49:34,300 --> 00:49:39,160 Si lo primero que hago es insertar la A, tengo una CC sobrante. 790 00:49:39,160 --> 00:49:41,920 Entonces, para cada uno de ellas tengo una penalización de 791 00:49:41,920 --> 00:49:45,610 2 por ir a la derecha, 2 por bajar, 1 por ir en diagonal, que agrego a lo que sea 792 00:49:45,610 --> 00:49:46,990 en esa tabla 793 00:49:46,990 --> 00:49:50,830 Descubrí que si trato de igualar A a CI tendré una penalización de 1, 794 00:49:50,830 --> 00:49:53,680 y tengo una C sobrante que debo eliminar, 795 00:49:53,680 --> 00:49:56,020 entonces hay un costo total de 3. 796 00:49:56,020 --> 00:49:57,940 Y esa era una buena opción como yo, así que 797 00:49:57,940 --> 00:49:59,481 eso es lo que puse en la tabla. 798 00:49:59,481 --> 00:50:02,940 799 00:50:02,940 --> 00:50:10,990 Y luego puedo tratar de averiguar para la cadena ACC a A, 800 00:50:10,990 --> 00:50:15,480 y solo funciona hacia atrás, a través de esta tabla y sube las filas 801 00:50:15,480 --> 00:50:17,610 hasta que todo esté completo 802 00:50:17,610 --> 00:50:21,930 Y lo bueno de esto es que, cada vez que veo la tabla, 803 00:50:21,930 --> 00:50:24,960 necesito tres piezas de información. 804 00:50:24,960 --> 00:50:28,890 Necesito la información que está en la columna, justo a mi derecha, 805 00:50:28,890 --> 00:50:31,500 necesito la información que está en la columna de la fila, 806 00:50:31,500 --> 00:50:33,120 justo debajo de mí, 807 00:50:33,120 --> 00:50:35,040 en la celda que está justo debajo de mí 808 00:50:35,040 --> 00:50:38,830 y necesito la información que está uno abajo y uno a la derecha. 809 00:50:38,830 --> 00:50:41,440 Y dado que estoy trabajando hacia atrás en la tabla, 810 00:50:41,440 --> 00:50:45,240 es agradable y fácil porque los datos ya están allí. 811 00:50:45,240 --> 00:50:49,680 Empecé a llenar la última fila en la última columna, 812 00:50:49,680 --> 00:50:53,250 los cuales son una especie de casos especiales, y ahora solo 813 00:50:53,250 --> 00:50:55,570 tengo algunos bucles que se ejecutan hacia atrás a través de esto. 814 00:50:55,570 --> 00:51:01,770 Y si una cadena tiene n letras de longitud, es decir, que n un número 815 00:51:01,770 --> 00:51:06,360 y la otra cadena es m, una m como en mnemotécnico, 816 00:51:06,360 --> 00:51:10,900 entonces el total es m veces n. 817 00:51:10,900 --> 00:51:13,230 Y veo que Doug se ríe del mnemotécnico. 818 00:51:13,230 --> 00:51:18,600 Tengo que atribuir ese chiste particular al profesor Mitzenmacher, de Harvard, 819 00:51:18,600 --> 00:51:21,120 según me lo contó mi compañero de cuarto, porque yo no estuve 820 00:51:21,120 --> 00:51:24,030 en esa clase, cuando hizo la broma. 821 00:51:24,030 --> 00:51:26,320 Pero me gustó. 822 00:51:26,320 --> 00:51:30,130 Entonces pueden llenar la tabla. 823 00:51:30,130 --> 00:51:35,070 Y ahora, en lugar de tener 3 a la n, esencialmente, cosas que 824 00:51:35,070 --> 00:51:38,430 tuvieron que probar, solo tienen n al cuadrado. 825 00:51:38,430 --> 00:51:40,820 Entonces son 18 letras 826 00:51:40,820 --> 00:51:43,920 18 al cuadrado es un poco menos que 20 al cuadrado. 827 00:51:43,920 --> 00:51:46,810 Y 20 al cuadrado es 400. 828 00:51:46,810 --> 00:51:53,850 Así que tenemos, como máximo, cerca de 400, pero en este caso 829 00:51:53,850 --> 00:51:57,514 ni siquiera es n + m al cuadrado, es n al cuadrado. 830 00:51:57,514 --> 00:51:58,680 Es como 10 al cuadrado. 831 00:51:58,680 --> 00:52:00,450 Es como 100. 832 00:52:00,450 --> 00:52:07,120 Entonces, tenemos cerca de 100 pasos diferentes para encontrar la respuesta. 833 00:52:07,120 --> 00:52:10,020 Si probamos todo, estaríamos haciendo el mismo trabajo 834 00:52:10,020 --> 00:52:12,600 una y otra y otra vez, y sería como 3 a la 20, 835 00:52:12,600 --> 00:52:15,430 y eso, una vez más, es un número realmente grande. 836 00:52:15,430 --> 00:52:18,410 2 a la 20 es un millón. 837 00:52:18,410 --> 00:52:22,740 Y del 2 al 3 es como-- 838 00:52:22,740 --> 00:52:31,710 3 es como 2 a la 1.2... digamos, aproximadamente un millón 839 00:52:31,710 --> 00:52:34,620 a la 1.2. 840 00:52:34,620 --> 00:52:36,660 Es cerca de 130 millones, y allí tienen. 841 00:52:36,660 --> 00:52:38,957 Sabía que había un sabio idiota en alguna parte de la sala. 842 00:52:38,957 --> 00:52:44,430 843 00:52:44,430 --> 00:52:46,680 Y de nuevo, cada una de estas celdas en la tabla 844 00:52:46,680 --> 00:52:49,230 nos dice esencialmente qué hacer. 845 00:52:49,230 --> 00:52:50,906 ¿Haz coincidir este primer par de letras? 846 00:52:50,906 --> 00:52:51,780 ¿Haz una eliminación? 847 00:52:51,780 --> 00:52:54,030 ¿O haz una inserción? 848 00:52:54,030 --> 00:52:58,409 Y a partir de eso, pueden averiguar cuánto queda de cada una de las cadenas. 849 00:52:58,409 --> 00:53:01,200 Y luego miran a la siguiente celda que corresponde de la tabla 850 00:53:01,200 --> 00:53:07,050 donde se hará el paso siguiente. 851 00:53:07,050 --> 00:53:09,980 Y para descubrir exactamente cómo coinciden estas cosas 852 00:53:09,980 --> 00:53:13,620 y cuál es el costo de hacerlas coincidir 853 00:53:13,620 --> 00:53:18,690 de la mejor manera posible, se trabaja la ruta a través de la tabla, 854 00:53:18,690 --> 00:53:21,240 en vez de tratar de almacenar toda esa información en cada celda, 855 00:53:21,240 --> 00:53:23,790 y almacenar la misma información una y otra vez, 856 00:53:23,790 --> 00:53:26,280 se almacena solo una parte de la respuesta en cada celda. 857 00:53:26,280 --> 00:53:29,270 858 00:53:29,270 --> 00:53:30,215 ¿Preguntas? 859 00:53:30,215 --> 00:53:32,830 860 00:53:32,830 --> 00:53:34,272 Sí. 861 00:53:34,272 --> 00:53:39,232 PÚBLICO: En el tiempo de ejecución dice que hay OMN, la M es una constante 862 00:53:39,232 --> 00:53:42,704 o es otra... 863 00:53:42,704 --> 00:53:44,562 ¿Qué es [INAUDIBLE]? 864 00:53:44,562 --> 00:53:47,020 PONENTE: Bien, en este tiempo de ejecución, donde dice OMN, 865 00:53:47,020 --> 00:53:48,500 ¿qué significa esto? 866 00:53:48,500 --> 00:53:51,050 Lo que estamos diciendo es que tenemos dos cadenas diferentes. 867 00:53:51,050 --> 00:53:57,050 Una de ellas tiene n caracteres de longitud, la otra tiene m. 868 00:53:57,050 --> 00:54:00,140 Entonces, en términos de la función de la entrada, 869 00:54:00,140 --> 00:54:02,250 solo estamos siendo un poco más precisos y decimos: 870 00:54:02,250 --> 00:54:06,050 tenemos dos palabras que tienen n letras de longitud. 871 00:54:06,050 --> 00:54:07,937 Y luego es una especie de n al cuadrado. 872 00:54:07,937 --> 00:54:09,770 Lo cual implica que tal vez son longitudes muy diferentes 873 00:54:09,770 --> 00:54:14,550 y que podemos ser un poco más precisos en cuanto a la cantidad de pasos que siguen. 874 00:54:14,550 --> 00:54:18,620 Pero la clave es que se ve una cosa por otra, 875 00:54:18,620 --> 00:54:21,590 es una especie de algo al cuadrado. 876 00:54:21,590 --> 00:54:25,940 A medida que se piensa, a medida que estas cadenas se hacen cada vez más largas, 877 00:54:25,940 --> 00:54:28,610 ¿Cuánto trabajo implica? 878 00:54:28,610 --> 00:54:32,090 Entonces no es tan malo. 879 00:54:32,090 --> 00:54:37,400 Y en realidad es muy viable aplicar esto en las secuencias de ADN 880 00:54:37,400 --> 00:54:41,420 que podrían ser unos cientos de pares base de longitud. 881 00:54:41,420 --> 00:54:44,540 Es viable hacer esto para un archivo fuente de la tarea 882 00:54:44,540 --> 00:54:49,340 y hacer trampa al revisar, quizás son unos cuantos miles de caracteres. 883 00:54:49,340 --> 00:54:54,110 No es gran cosa, a pesar de que tenemos 1000 estudiantes, 884 00:54:54,110 --> 00:54:58,340 y tenemos todas las entregas pasadas, entonces tenemos 10,000 presentaciones, 885 00:54:58,340 --> 00:55:03,410 así que tenemos aproximadamente un millón de pares de archivos, 886 00:55:03,410 --> 00:55:08,210 o algo así, y eso no es gran cosa para una computadora. 887 00:55:08,210 --> 00:55:11,630 Y cada uno de estos toma alrededor de un millón de pasos, 888 00:55:11,630 --> 00:55:14,919 porque tenemos 1000 caracteres por 1000 caracteres. 889 00:55:14,919 --> 00:55:15,710 Podemos manejarlo. 890 00:55:15,710 --> 00:55:20,170 891 00:55:20,170 --> 00:55:21,353 ¿Alguna otra pregunta? 892 00:55:21,353 --> 00:55:25,290 893 00:55:25,290 --> 00:55:25,790 Sí. 894 00:55:25,790 --> 00:55:29,740 PÚBLICO: ¿Se aplica la fuerza bruta para completar la tabla inicialmente? 895 00:55:29,740 --> 00:55:32,950 PONENTE: ¿Se aplica la fuerza bruta para completar la tabla inicialmente? 896 00:55:32,950 --> 00:55:36,250 Eso depende de cómo definas la fuerza bruta. 897 00:55:36,250 --> 00:55:40,360 Tienes que llenar todas las celdas de la tabla. 898 00:55:40,360 --> 00:55:44,630 Porque para encontrar la respuesta que está arriba a la izquierda, 899 00:55:44,630 --> 00:55:47,380 a pesar de que, a fin de cuentas, solo usará el valor de uno 900 00:55:47,380 --> 00:55:49,254 de estos tres, debes mirar los tres 901 00:55:49,254 --> 00:55:53,590 valores, el de la derecha y los dos de abajo. 902 00:55:53,590 --> 00:55:55,600 Entonces, para encontrar la respuesta final, 903 00:55:55,600 --> 00:55:58,420 tengo que llenar toda la tabla. 904 00:55:58,420 --> 00:56:02,500 Y hay m por n entradas en la tabla, que es donde se llega a este m por n 905 00:56:02,500 --> 00:56:05,350 n o n tipo cuadrado de cosas. 906 00:56:05,350 --> 00:56:08,140 Pero comparado con lo que podríamos pensar como fuerza bruta 907 00:56:08,140 --> 00:56:12,490 al tratar cada alineamiento posible de las dos cadenas, 908 00:56:12,490 --> 00:56:14,410 o cual implica muchas subalineaciones, muchas 909 00:56:14,410 --> 00:56:17,657 partes que se alinean de la misma manera, en muchos lugares diferentes, 910 00:56:17,657 --> 00:56:19,240 no estamos rehaciéndolos una y otra vez. 911 00:56:19,240 --> 00:56:22,990 Así que no estamos aplicando una fuerza bruta tan brutal que 912 00:56:22,990 --> 00:56:27,220 diríamos algo así como de 3 a 2000 pasos 913 00:56:27,220 --> 00:56:32,401 para comparar un solo par de archivos, y que luego debamos hacer un millón. 914 00:56:32,401 --> 00:56:33,400 Eso sería un problema. 915 00:56:33,400 --> 00:56:35,920 916 00:56:35,920 --> 00:56:37,048 ¿Alguna otra pregunta? 917 00:56:37,048 --> 00:56:45,350 918 00:56:45,350 --> 00:56:48,100 Así que de alguna manera incorporé dos aplicaciones en una 919 00:56:48,100 --> 00:56:50,350 justo ahí, con la edición de distancia. 920 00:56:50,350 --> 00:56:56,260 Una es de biología computacional, donde se trata una secuencia de ADN o proteína 921 00:56:56,260 --> 00:56:58,450 como una cadena. 922 00:56:58,450 --> 00:57:03,730 Y el otro es una especie de comparación de archivos sofisticados 923 00:57:03,730 --> 00:57:05,590 que pueden usar para buscar y reemplazar. 924 00:57:05,590 --> 00:57:07,840 Pueden usarla para revisar la ortografía o para descubrir 925 00:57:07,840 --> 00:57:09,640 la mejor palabra en el diccionario. 926 00:57:09,640 --> 00:57:12,490 No solo es la palabra allí, sino de las palabras 927 00:57:12,490 --> 00:57:16,720 que están en el diccionario, cuál es más probable que quiera 928 00:57:16,720 --> 00:57:21,620 escribir según algún modelo de frecuencia de los diferentes tipos 929 00:57:21,620 --> 00:57:22,120 de errores. 930 00:57:22,120 --> 00:57:25,300 931 00:57:25,300 --> 00:57:29,620 Y podría calcular la edición de distancia para cada palabra en el diccionario, 932 00:57:29,620 --> 00:57:34,090 a fin de proponer una lista de sugerencias. 933 00:57:34,090 --> 00:57:38,900 Pero hay otra aplicación de la que quiero hablar, 934 00:57:38,900 --> 00:57:40,960 que es el cosido de imágenes. 935 00:57:40,960 --> 00:57:43,210 Esto sucede cuando sacan su teléfono celular 936 00:57:43,210 --> 00:57:44,650 y construyen una imagen panorámica 937 00:57:44,650 --> 00:57:49,020 Entonces, barren alrededor con la cámara y toman un video 938 00:57:49,020 --> 00:57:55,240 o tal vez tomen una serie de imágenes cada uno o dos segundos, 939 00:57:55,240 --> 00:57:59,394 y luego los unen en una gran imagen. 940 00:57:59,394 --> 00:58:01,060 Y hay algunas partes en ese proceso. 941 00:58:01,060 --> 00:58:03,910 Una parte es que cada una de la imágenes que tomaron descubre 942 00:58:03,910 --> 00:58:06,880 cómo se movió su cámara entre cada una. 943 00:58:06,880 --> 00:58:10,390 Entonces puede transformar las imágenes como si 944 00:58:10,390 --> 00:58:14,090 se superpusieran en los lugares correctos. 945 00:58:14,090 --> 00:58:19,750 Pero incluso entonces, no se alinearán perfectamente, porque tal vez alguien 946 00:58:19,750 --> 00:58:22,960 caminó en ese instante en la escena, o resulta 947 00:58:22,960 --> 00:58:27,650 que si estaban caminando con su cámara así, 948 00:58:27,650 --> 00:58:31,540 en lugar de simplemente girar alrededor, se obtendría un efecto de paralaje 949 00:58:31,540 --> 00:58:34,990 donde las cosas que están más cerca de ustedes parecen moverse más rápido 950 00:58:34,990 --> 00:58:37,670 que las cosas que están más lejos. 951 00:58:37,670 --> 00:58:40,900 Entonces, ahora veo parte de la silla del medio. 952 00:58:40,900 --> 00:58:44,650 El lado derecho de la misma, para mí, está escondido detrás del trípode. 953 00:58:44,650 --> 00:58:49,660 Pero si camino hasta aquí, se vuelve visible y el lado izquierdo del asiento 954 00:58:49,660 --> 00:58:52,300 Queda oculto detrás del trípode. 955 00:58:52,300 --> 00:58:57,284 Así, con este panorama, tal vez no haya un modo perfecto de iluminar las imágenes, 956 00:58:57,284 --> 00:59:00,450 porque hay información visible diferente incluso en las áreas superpuestas. 957 00:59:00,450 --> 00:59:03,070 958 00:59:03,070 --> 00:59:08,200 Y para resolver ese problema, la clave es una vez que nos demos cuenta 959 00:59:08,200 --> 00:59:13,420 cómo se superponen las dos imágenes, queremos descubrir y formar parte 960 00:59:13,420 --> 00:59:17,590 de esa área superpuesta de una imagen y parte de ella 961 00:59:17,590 --> 00:59:19,624 de la otra imagen. 962 00:59:19,624 --> 00:59:21,040 Entonces hay una costura entre ambas. 963 00:59:21,040 --> 00:59:24,456 Y una costura es solo una línea de píxeles conectada. 964 00:59:24,456 --> 00:59:27,580 Todo en un lado proviene de la imagen A, todo en el otro lado 965 00:59:27,580 --> 00:59:33,070 proviene de la imagen B. Y la pregunta es, ¿a dónde debería ir esa costura? 966 00:59:33,070 --> 00:59:35,600 967 00:59:35,600 --> 00:59:40,850 Ahora, esa costura debería ir, idealmente, en algún lugar donde no la notemos. 968 00:59:40,850 --> 00:59:44,030 Cambiemos de una imagen a la otra en algún lugar 969 00:59:44,030 --> 00:59:47,000 donde sean realmente similares, y en algún lugar 970 00:59:47,000 --> 00:59:51,260 donde veamos que el paralaje del trípode se mueve, 971 00:59:51,260 --> 00:59:55,340 o donde alguien caminó en la escena. 972 00:59:55,340 --> 01:00:01,970 Intento hacer esta costura donde conecto las dos imágenes que rodean eso. 973 01:00:01,970 --> 01:00:08,780 Así que no se trata de una especie de salto donde las dos imágenes eran 974 01:00:08,780 --> 01:00:09,572 diferentes. 975 01:00:09,572 --> 01:00:12,170 976 01:00:12,170 --> 01:00:14,870 Bueno, la forma más sencilla de hacerlo es ver 977 01:00:14,870 --> 01:00:19,670 a un par en este rectángulo superpuesto, y digamos, dibujemos esta costura 978 01:00:19,670 --> 01:00:23,580 donde los píxeles sean realmente similares. 979 01:00:23,580 --> 01:00:26,900 Y podría hacerlo, por ejemplo, viendo la diferencia 980 01:00:26,900 --> 01:00:29,632 en el color del píxel entre ambos. 981 01:00:29,632 --> 01:00:32,840 En este caso, es agradable y fácil porque las imágenes son en blanco y negro 982 01:00:32,840 --> 01:00:36,920 así que solo tomo la diferencia en intensidad, 983 01:00:36,920 --> 01:00:40,340 que es un número entre 0 y 255, y voy a 984 01:00:40,340 --> 01:00:44,570 obtener un número diferente que esté entre 255 y 255 negativos, 985 01:00:44,570 --> 01:00:46,640 Así podría restar blanco de negro. 986 01:00:46,640 --> 01:00:49,070 Tomo el valor absoluto de eso. 987 01:00:49,070 --> 01:00:53,540 Si esto es 0, significa que el píxel era del mismo color en ambas imágenes. 988 01:00:53,540 --> 01:00:59,570 Si es realmente grande, significa que los colores fueron diferentes. 989 01:00:59,570 --> 01:01:05,750 Y ahora, podría decir que el costo de una costura 990 01:01:05,750 --> 01:01:14,600 a través de un píxel particular es esa diferencia en valores entre los píxeles 991 01:01:14,600 --> 01:01:15,290 de la imagen, 992 01:01:15,290 --> 01:01:17,752 la diferencia en intensidad. 993 01:01:17,752 --> 01:01:20,210 Y para la costura total, quiero averiguar a partir de ahí si, 994 01:01:20,210 --> 01:01:21,560 ¿debería ir a la derecha? 995 01:01:21,560 --> 01:01:23,520 ¿debería ir hacia abajo? 996 01:01:23,520 --> 01:01:26,390 ¿o debería ir hacia abajo y a la derecha? 997 01:01:26,390 --> 01:01:29,696 Lo que puedo hacer buscando en la tabla 998 01:01:29,696 --> 01:01:32,820 el costo de una costura que pasa por el píxel de la derecha o el píxel de abajo 999 01:01:32,820 --> 01:01:36,270 y a la derecha o el píxel de la izquierda. 1000 01:01:36,270 --> 01:01:42,230 Aquí está la tabla, solo es eso ahora, una celda en la tabla, 1001 01:01:42,230 --> 01:01:48,260 en lugar de decir el costo de hacer coincidir ACCC, por ejemplo, con TCA, 1002 01:01:48,260 --> 01:01:50,170 completando una celda en la tabla. 1003 01:01:50,170 --> 01:01:52,910 Con eso, voy a interpretar esa celda como el costo de 1004 01:01:52,910 --> 01:01:56,610 que la costura de la imagen se ejecute de aquí hasta la esquina inferior derecha. 1005 01:01:56,610 --> 01:02:00,200 1006 01:02:00,200 --> 01:02:03,200 Y en ese sentido, si ven las costuras de la imagen, 1007 01:02:03,200 --> 01:02:06,290 pueden ver esa matriz. 1008 01:02:06,290 --> 01:02:12,040 Es este rectángulo de píxeles superpuestos entre las dos imágenes. 1009 01:02:12,040 --> 01:02:20,290 Y el algoritmo para encontrar la costura óptima es idéntico a la edición de distancia. 1010 01:02:20,290 --> 01:02:22,100 Absolutamente idéntico. 1011 01:02:22,100 --> 01:02:25,490 La única diferencia... aunque dije que era absolutamente idéntica, 1012 01:02:25,490 --> 01:02:29,710 por supuesto, hay una diferencia, de lo contrario no sería divertido, 1013 01:02:29,710 --> 01:02:32,530 pero la diferencia y la razón por la que digo que el algoritmo es idéntico 1014 01:02:32,530 --> 01:02:38,440 es esta función de costo que decide cuál es el costo total de esta celda basada 1015 01:02:38,440 --> 01:02:41,260 en el costo de lo que está a la derecha, abajo y a la derecha 1016 01:02:41,260 --> 01:02:43,810 y abajo, es diferente. 1017 01:02:43,810 --> 01:02:46,660 Esa función de costo para editar la distancia fue un número 1018 01:02:46,660 --> 01:02:49,180 que depende de si coinciden o son dispares 1019 01:02:49,180 --> 01:02:55,030 o era una inserción o eliminación más el costo de lo que está a la derecha, 1020 01:02:55,030 --> 01:02:56,410 o abajo o diagonal. 1021 01:02:56,410 --> 01:02:58,720 Entonces, era una penalización diferente que 1022 01:02:58,720 --> 01:03:03,160 se pagaba por moverse a la derecha en esta tabla, o hacia abajo, o en diagonal. 1023 01:03:03,160 --> 01:03:08,140 Con esta costura de la imagen en este momento, en la forma en que lo definí, 1024 01:03:08,140 --> 01:03:09,220 el costo es el mismo. 1025 01:03:09,220 --> 01:03:12,520 La penalización que se paga por tener una costura atraviesa un píxel en particular 1026 01:03:12,520 --> 01:03:16,870 es lo mismo incluso si continúa hacia la derecha, en diagonal o hacia abajo. 1027 01:03:16,870 --> 01:03:19,940 es solo la diferencia en intensidad. 1028 01:03:19,940 --> 01:03:23,280 Entonces tomaríamos el mínimo de... 1029 01:03:23,280 --> 01:03:25,660 tomaríamos la diferencia en intensidad más el mínimo 1030 01:03:25,660 --> 01:03:31,480 de lo que está a la derecha, abajo, o en diagonal a la derecha. 1031 01:03:31,480 --> 01:03:36,580 Es una función de costo ligeramente diferente, pero es el mismo algoritmo. 1032 01:03:36,580 --> 01:03:40,210 Y hay formas de implementar esto donde esencialmente podemos 1033 01:03:40,210 --> 01:03:42,250 decir al algoritmo, OK, rellena esta tabla, 1034 01:03:42,250 --> 01:03:48,520 usa esta función de costo para que pueda usar exactamente el mismo código, 1035 01:03:48,520 --> 01:03:52,300 implementa esto una vez, edita la distancia 1036 01:03:52,300 --> 01:03:54,321 y también puedes hacer cosidos de imagen. 1037 01:03:54,321 --> 01:03:56,735 1038 01:03:56,735 --> 01:03:58,860 Y uno de los aspectos en donde los algoritmos 1039 01:03:58,860 --> 01:04:01,590 y la abstracción de la informática se vuelven algo 1040 01:04:01,590 --> 01:04:05,760 es muy interesante cuando comenzamos a ver dos problemas que parecen 1041 01:04:05,760 --> 01:04:09,992 no tener relación y resultan ser lo mismo. 1042 01:04:09,992 --> 01:04:11,700 Y es aún más divertido cuando podemos escribir 1043 01:04:11,700 --> 01:04:14,760 un programa que hace dos cosas completamente diferentes para nosotros 1044 01:04:14,760 --> 01:04:17,970 y ni siquiera tenemos que volver a implementarlo. 1045 01:04:17,970 --> 01:04:19,444 ¿Alguna pregunta? 1046 01:04:19,444 --> 01:04:27,680 1047 01:04:27,680 --> 01:04:33,650 Voy a finalizar entonces con una demostración de un algoritmo más 1048 01:04:33,650 --> 01:04:36,920 que utiliza la programación dinámica 1049 01:04:36,920 --> 01:04:41,840 y pueden encontrar varias demos en la web, este es solo uno de ellos. 1050 01:04:41,840 --> 01:04:43,280 llamado seam carving. 1051 01:04:43,280 --> 01:04:49,490 Esto es muy similar al cosido de imágenes, donde encontramos 1052 01:04:49,490 --> 01:04:53,870 esa costura yendo de la esquina superior izquierda a la esquina inferior derecha. 1053 01:04:53,870 --> 01:05:07,510 La idea aquí es que queremos cambiar el tamaño de la imagen de la derecha. 1054 01:05:07,510 --> 01:05:08,730 Y ya lo hicieron en la serie de problemas 3. 1055 01:05:08,730 --> 01:05:11,940 Cambiaron el tamaño de las imágenes, o en la serie de problemas 4, perdón. 1056 01:05:11,940 --> 01:05:13,440 Ahí cambiaron el tamaño de las imágenes. 1057 01:05:13,440 --> 01:05:17,310 Y si las hicieron más estrechas, quedaron algo aplastadas, 1058 01:05:17,310 --> 01:05:20,374 si las hicieron más anchas, se estiraron un poco, 1059 01:05:20,374 --> 01:05:21,540 y todo se veía mal 1060 01:05:21,540 --> 01:05:24,100 ¿No sería genial si pudiéramos cambiar el tamaño de la imagen, 1061 01:05:24,100 --> 01:05:25,350 pero que aun así se viera normal? 1062 01:05:25,350 --> 01:05:28,710 1063 01:05:28,710 --> 01:05:31,200 Entonces, la idea del algoritmo seam carving 1064 01:05:31,200 --> 01:05:34,650 es, esencialmente, cambiar el tamaño de la imagen. 1065 01:05:34,650 --> 01:05:38,680 En lugar de escalar cada píxel para que sea un poco más estrecho que antes, 1066 01:05:38,680 --> 01:05:43,710 solo tomamos una fila de píxeles y los eliminamos. 1067 01:05:43,710 --> 01:05:47,400 Entonces podríamos tomar esta fila de aquí, o esta columna de píxeles, 1068 01:05:47,400 --> 01:05:49,520 y eliminarlos, y tal vez nadie lo note. 1069 01:05:49,520 --> 01:05:52,420 1070 01:05:52,420 --> 01:05:55,030 El problema es que solo podemos hacer esto en una imagen cierto número de veces 1071 01:05:55,030 --> 01:05:58,150 antes de que alguien lo note. 1072 01:05:58,150 --> 01:06:03,350 Porque se obtiene algún tipo de salto, en donde se borra información útil. 1073 01:06:03,350 --> 01:06:12,680 Y una de las razones es que, por ejemplo, en esta columna de aquí, 1074 01:06:12,680 --> 01:06:15,860 en el agua, podrían salirse con la suya borrando un píxel. 1075 01:06:15,860 --> 01:06:19,417 en el cielo, podrían salirse con la suya borrando un píxel. 1076 01:06:19,417 --> 01:06:21,500 Pero en el globo, es mejor que no eliminen un píxel 1077 01:06:21,500 --> 01:06:23,041 porque sería bastante obvio. 1078 01:06:23,041 --> 01:06:26,690 El globo comenzaría a verse muy chistoso, muy rápidamente. 1079 01:06:26,690 --> 01:06:31,010 Entonces, en lugar de encontrar una línea recta de píxeles para eliminar, 1080 01:06:31,010 --> 01:06:34,460 vamos a encontrar una línea ondulada. 1081 01:06:34,460 --> 01:06:38,230 Aún seguimos eliminando un píxel de cada fila, 1082 01:06:38,230 --> 01:06:43,920 así que cada fila terminará siendo un píxel más pequeña de lo que era antes, 1083 01:06:43,920 --> 01:06:49,730 eso significa que la imagen seguirá siendo rectangular, pero tenemos una opción. 1084 01:06:49,730 --> 01:06:54,980 Si eliminamos un píxel en particular arriba en la imagen, en la siguiente fila 1085 01:06:54,980 --> 01:06:58,070 hacia abajo podríamos eliminar el píxel que está justo debajo de él, o el que está 1086 01:06:58,070 --> 01:07:01,690 a la izquierda o el de la derecha. 1087 01:07:01,690 --> 01:07:04,190 Así que esto también es bastante... tenemos estas tres opciones, 1088 01:07:04,190 --> 01:07:05,720 tal como lo hicimos antes, 1089 01:07:05,720 --> 01:07:08,060 con una función de costo ligeramente diferente. 1090 01:07:08,060 --> 01:07:12,210 Y luego tenemos... puedes comenzar eliminando cualquiera de los píxeles 1091 01:07:12,210 --> 01:07:12,710 de la parte superior. 1092 01:07:12,710 --> 01:07:15,540 Elegiremos el que tendrá el menor costo. 1093 01:07:15,540 --> 01:07:18,290 Y ese costo podría ser cuán diferentes son sus píxeles a los de su vecino 1094 01:07:18,290 --> 01:07:19,854 a la izquierda y a la derecha. 1095 01:07:19,854 --> 01:07:22,520 Entonces, si son más o menos del mismo color los de la izquierda 1096 01:07:22,520 --> 01:07:25,145 que los de la derecha, nadie se dará cuenta si lo eliminamos. 1097 01:07:25,145 --> 01:07:28,020 1098 01:07:28,020 --> 01:07:31,900 Y con tan solo un poco de trabajo extra, 1099 01:07:31,900 --> 01:07:35,670 pueden actualizar posteriormente esa información, esa tabla, 1100 01:07:35,670 --> 01:07:39,780 para reflejar el hecho de que eliminaron ese píxel de cada fila. 1101 01:07:39,780 --> 01:07:43,710 Pueden arreglar todas las costuras que 1102 01:07:43,710 --> 01:07:47,600 hayan afectado para averiguar, si tienen que aplastar 1103 01:07:47,600 --> 01:07:50,220 otro píxel, cuál sería este. 1104 01:07:50,220 --> 01:07:53,490 1105 01:07:53,490 --> 01:07:55,680 Y pueden comenzar a cambiar el tamaño de la imagen. 1106 01:07:55,680 --> 01:07:58,390 1107 01:07:58,390 --> 01:08:00,680 Y pueden ver que está borrando mucho cielo, 1108 01:08:00,680 --> 01:08:02,800 al igual que está borrando mucha agua. 1109 01:08:02,800 --> 01:08:06,910 Está siendo muy cuidadoso con la forma en que reduce estos arbustos. 1110 01:08:06,910 --> 01:08:09,910 Y los adelgaza mucho menos que lo que reduce otras cosas, 1111 01:08:09,910 --> 01:08:12,190 trata de hacerlo de manera sensata. 1112 01:08:12,190 --> 01:08:18,859 Lo acostumbramos ver se queda normal en su mayoría y el espacio vacío 1113 01:08:18,859 --> 01:08:20,470 está siendo aplastado 1114 01:08:20,470 --> 01:08:23,410 Pero ese espacio vacío está en diferentes lugares 1115 01:08:23,410 --> 01:08:25,510 dependiendo de dónde se encuentre en la imagen. 1116 01:08:25,510 --> 01:08:29,170 Y aquí abajo, por ejemplo, no tenemos mucho espacio vacío. 1117 01:08:29,170 --> 01:08:32,179 Es difícil eliminar el pasto sin que uno se dé cuenta, 1118 01:08:32,179 --> 01:08:35,470 porque se obtendrá media brizna de hierba y se verá raro. 1119 01:08:35,470 --> 01:08:38,420 Y hay mucha agua que se puede eliminar antes de que se vuelva obvio. 1120 01:08:38,420 --> 01:08:41,294 Entonces, en algún sitio, comenzamos a desinflar el reflejo del globo. 1121 01:08:41,294 --> 01:08:44,113 1122 01:08:44,113 --> 01:08:47,029 Así que se ve gracioso, pero mucho menos que si todo hubiera tenido 1123 01:08:47,029 --> 01:08:48,950 que aplastarse en la misma proporción. 1124 01:08:48,950 --> 01:08:57,321 1125 01:08:57,321 --> 01:09:00,029 Siempre y cuando guarden la información de lo que borraron, 1126 01:09:00,029 --> 01:09:02,840 podrán volver a expandirlo. 1127 01:09:02,840 --> 01:09:05,870 Y así, como pueden ver, incluso si lo aplastamos mucho, 1128 01:09:05,870 --> 01:09:11,080 este globo aún se verá entero, porque es 1129 01:09:11,080 --> 01:09:15,479 muy fácil eliminar píxeles en el cielo, y aun así parecerá 1130 01:09:15,479 --> 01:09:17,957 que no hay necesidad de encoger el globo. 1131 01:09:17,957 --> 01:09:21,040 El reflejo del globo... eso fue más difícil porque debemos equilibrarlo 1132 01:09:21,040 --> 01:09:23,140 cuando eliminemos cosas en el césped. 1133 01:09:23,140 --> 01:09:27,490 1134 01:09:27,490 --> 01:09:31,479 Por lo tanto, cuesta un poco de trabajo más allá de ese cosido de imagen 1135 01:09:31,479 --> 01:09:35,560 y del problema de edición de distancia para hacer este seam carving. 1136 01:09:35,560 --> 01:09:37,479 Y cuesta un poco más de trabajo 1137 01:09:37,479 --> 01:09:44,140 ser capaz de cambiar el tamaño tanto horizontal como vertical, y eso es genial. 1138 01:09:44,140 --> 01:09:47,560 Y esto es algo que se publicó hace diez años en la Conferencia ACM Siggraph, que 1139 01:09:47,560 --> 01:09:53,750 es una megaconferencia en computación gráfica que se celebra cada agosto, 1140 01:09:53,750 --> 01:09:54,340 quisiera añadir. 1141 01:09:54,340 --> 01:09:57,640 1142 01:09:57,640 --> 01:10:03,730 Puedo decirles la fecha exacta buscando la referencia, 1143 01:10:03,730 --> 01:10:04,500 2007. 1144 01:10:04,500 --> 01:10:07,000 Entonces sí, fue hace 10 años. 1145 01:10:07,000 --> 01:10:09,460 Y de hecho es un documento bastante corto 1146 01:10:09,460 --> 01:10:13,840 y muy fácil de entender, porque es un algoritmo bastante simple 1147 01:10:13,840 --> 01:10:16,585 y es una idea realmente genial. 1148 01:10:16,585 --> 01:10:18,460 Y entonces es uno de esos documentos raros que 1149 01:10:18,460 --> 01:10:20,530 pueden sentarse a leer y entender, 1150 01:10:20,530 --> 01:10:22,690 pueden ir a la conferencia y entender. 1151 01:10:22,690 --> 01:10:25,460 y después pueden ir a casa. 1152 01:10:25,460 --> 01:10:28,750 Y si tienen algo de experiencia en informática, 1153 01:10:28,750 --> 01:10:32,740 y particularmente en computación gráfica, pueden entenderlo. 1154 01:10:32,740 --> 01:10:36,040 Y pueden sentarse e implementarlo en una hora. 1155 01:10:36,040 --> 01:10:38,710 Y entonces obtienen estas demostraciones web que aparecieron. 1156 01:10:38,710 --> 01:10:40,937 Photoshop puede hacerlo. 1157 01:10:40,937 --> 01:10:43,270 Comenzó a aparecer rápidamente en todas partes, 1158 01:10:43,270 --> 01:10:45,790 porque fue una idea excelente. 1159 01:10:45,790 --> 01:10:47,215 Funcionó sorprendentemente bien. 1160 01:10:47,215 --> 01:10:50,110 1161 01:10:50,110 --> 01:10:52,360 Y lo hace a través de esta programación dinámica. 1162 01:10:52,360 --> 01:10:58,100 No recalculemos la información sobre cómo llegar desde un punto particular, 1163 01:10:58,100 --> 01:11:00,830 cómo eliminar una escena desde allí hasta la parte inferior. 1164 01:11:00,830 --> 01:11:03,910 Eso no se calcula para cada posibilidad. 1165 01:11:03,910 --> 01:11:07,090 De alguna manera se da cuenta, bueno, desde aquí lo mejor que puedes hacer 1166 01:11:07,090 --> 01:11:10,300 sería bajar o lo mejor sería bajar y salir. 1167 01:11:10,300 --> 01:11:12,508 Y ese píxel se preocupa por cómo continuar desde ese punto. 1168 01:11:12,508 --> 01:11:15,610 1169 01:11:15,610 --> 01:11:16,792 ¿Alguna pregunta? 1170 01:11:16,792 --> 01:11:21,720 1171 01:11:21,720 --> 01:11:23,610 OK, bueno, gracias a todos por venir. 1172 01:11:23,610 --> 01:11:26,380 Recuerden que mañana por la mañana habrá otra conferencia 1173 01:11:26,380 --> 01:11:27,400 transmitida desde Harvard. 1174 01:11:27,400 --> 01:11:31,450 Y si están en Harvard, pueden divertirse asistiendo. 1175 01:11:31,450 --> 01:11:33,585 Hablaremos de una introducción a Python, 1176 01:11:33,585 --> 01:11:35,460 que es otro lenguaje de programación como C. 1177 01:11:35,460 --> 01:11:40,080 Tiene una sintaxis ligeramente diferente, pero el mismo trato básico. 1178 01:11:40,080 --> 01:11:43,140 Tiende a acostumbrarse a cierto tipo de programas 1179 01:11:43,140 --> 01:11:46,280 en los cuales su sintaxis facilita un poco escribirlos. 1180 01:11:46,280 --> 01:11:50,940 Entonces obtendrán, en vez de una tarea de programación, 1181 01:11:50,940 --> 01:11:53,220 un tipo de ejercicio escrito mucho más divertido 1182 01:11:53,220 --> 01:11:54,930 para trabajar durante el fin de semana. 1183 01:11:54,930 --> 01:11:56,700 Recuerden su examen. 1184 01:11:56,700 --> 01:11:59,730 Se aplicará después de la conferencia de mañana 1185 01:11:59,730 --> 01:12:02,690 y tendrán tres días para ello. 1186 01:12:02,690 --> 01:12:08,036 La próxima semana en Yale no habrá secciones, debido a las vacaciones de otoño. 1187 01:12:08,036 --> 01:12:11,730 Entonces, no habrá secciones el martes o el miércoles. 1188 01:12:11,730 --> 01:12:13,107 Tendrán un descanso. 1189 01:12:13,107 --> 01:12:14,440 Eso les dará tiempo para recuperarse 1190 01:12:14,440 --> 01:12:16,800 y tiempo para dormir. 1191 01:12:16,800 --> 01:12:20,855 Y el próximo viernes, que es durante nuestras vacaciones de otoño, 1192 01:12:20,855 --> 01:12:22,980 habrá otra conferencia transmitida desde Harvard 1193 01:12:22,980 --> 01:12:25,890 donde se hablará más sobre Python. 1194 01:12:25,890 --> 01:12:28,350 Y se publicará la serie de problemas 6. 1195 01:12:28,350 --> 01:12:31,500 Es probable que vincule muchas cosas de las que hablamos esta semana 1196 01:12:31,500 --> 01:12:35,490 y de las que hablaremos la próxima, en una tarea de programación. 1197 01:12:35,490 --> 01:12:39,450 Y, por supuesto, tendrán 10 días para trabajar en ello. 1198 01:12:39,450 --> 01:12:42,630 Para que pueda verlo cuando terminen, pero no debe 1199 01:12:42,630 --> 01:12:44,190 arruinar el resto de sus vacaciones de otoño. 1200 01:12:44,190 --> 01:12:45,810 Lo prometo. 1201 01:12:45,810 --> 01:12:47,970 Y con eso nos despedimos, gracias de nuevo por venir. 1202 01:12:47,970 --> 01:12:49,970 Esto fue CS50.