CUPÓN GRATIS PARA VIAJAR EN UBER - CODIGO PROMOCIONAL

COMO USAR EL CÓDIGO PROMOCIONAL DE UBER

Si aun no te has registrado en el servicio de UBER y quieres llevarte un viaje gratis, esta es tu oportunidad, lo único que debes hacer es registrarte a través del siguiente vínculo:  https://www.uber.com/invite/b2rc48pmue y luego colocar el código promocional     b2rc48pmue  .

PASOS PARA USAR UN CODIGO PROMOCIONAL EN UBER EN PERÚ U OTRO PAIS
  1. Ingresa a la aplicación de UBER
  2. Presiona sobre las tres barritas horizontales que aparecen en la esquina superior izquierda de tu aplicación.
  3. Selecciona la opción PROMOCIONES (Es la quinta siguiendo la siguiente secuencia : PAGO / VIAJES / AYUDA / VIAJES GRATIS / PROMOCIONES)
  4. Dentro de promociones encontraras una opción que diga AGREGA CÓDIGO PROMO y listo, eso es todo. Una vez ingresado y que hayas tomado el servicio, el taxi reconocerá tu código promocional, en ese caso es de 20 nuevos soles. Si el servicio fuera por un monto mayor, deberás pagar solo la diferencia de la tarifa, pero si el servicio es por un monto menor, debes saber que no hay vuelto o saldo a favor.
Debes tener en cuenta que los códigos no son acumulables, es decir, si tienes 3 viajes gratis de 10 soles cada uno, no puedes tomar un servicio por 30, porque el valor máximo por código o cupón promocional de UBER es por 20 nuevos soles.

Recuerda que una vez registrado, tu también puedes referir el servicio y ganar más códigos promocionales a tus amigos y familiares.

Algo importante que debes saber es que UBER usa tarifas dinámicas, por ende, puede suceder que en tramos cortos la tarifa sea muy elevada, ello debido a la alta demanda, si eso te sucede, espera un par de minutos y vuelve a cargar la aplicación y la tarifa cambiará. Como ejemplo te comentamos que siempre nos vamos de San Miguel a Pueblo Libre y viceversa por 7 soles o 7.50, sin embargo, en vísperas a las fiestas navideñas la tarifa estuvo en promedio 11 soles y el mismo 24 de diciembre las tarifas por momentos llegaban a los 22 soles. Ten paciencia y espera que la demanda baje un poco.

PASOS PARA INVITAR A MIS AMIGOS A REGISTRARSE EN UBER Y GANAR VIAJES GRATIS:

  1. Ingresa a la APP de UBER
  2. Presiona sobre las tres barritas horizontales que aparecen en la esquina superior izquierda de tu aplicación.
  3. Ubica la opción VIAJES GRATIS y selecciona la forma en la que deseas invitar a tus amigos, puede ser por correo electrónico, por mensaje de texto o en tus redes sociales favoritas. A mas invitaciones aceptadas, mas viajes gratis recibirás de UBER

Cuando compartas ya sea por redes sociales , correo electronico o mensaje de texto , a tus amigos les aparecerá un mensaje muy similar a este:

Quiero regalarte tres viajes gratis con el app de Uber (de hasta 10 PEN). Para aceptarlo, usa el código b2rc48pmue y regístrate. ¡Disfruta!

Si lo deseas, también puedes registrarte y obtener tu primer taxi gratis con UBER usando este código QR para hacer tu inscripción.




Encuentra más casos de estudio de marketing, administración y empresas exitosas en http://www.facebook.com/EBlogDeRaffo
Recuerda que también puedes seguirnos en twitter como @rtrucios


Te invitamos a compartir nuestros contenidos con tus colegas y así hacer crecer nuestra comunidad

Los 10 Errores Más Comunes En Diseño De Aplicaciones Móviles

BY KENT MUNDLE - TECHNICAL EDITOR @ TOPTAL (TRANSLATED BY MARISELA ORDAZ)

El mercado de las aplicaciones móviles está saturado de competencia. Las tendencias cambian rápidamente, pero ningún nicho de mercado puede durar mucho tiempo sin que varios competidores entren en juego. Estas condiciones dan lugar a una alta tasa de fracaso en todos los ámbitos para el mercado de las aplicaciones móviles. Sólo el 20% de las aplicaciones descargadas ven regresar a los usuarios después del primer uso, mientras que sólo el 3% de las aplicaciones permanecen en uso después del primer mes.
Si cualquier parte de una aplicación no es deseable, o el proceso de entenderla es lento, los usuarios son más propensos a instalar una nueva, en lugar de esperar hasta el final con el producto imperfecto. El consumidor no pierde nada cuando se deshace de una aplicación - excepto los esfuerzos de los diseñadores y desarrolladores. Así que, ¿por qué fallan tantas aplicaciones? ¿Es un fenómeno predecible que los diseñadores de aplicaciones y desarrolladores deben aceptar? Para los clientes, ¿es aceptable ésta tasa de éxito? ¿Qué se necesita para llevar tus diseños al 3% de las aplicaciones prósperas?
Los errores más comunes van desde no mantener la constancia a lo largo de la vida útil de una aplicación, hasta atraer a los usuarios en primer lugar. ¿Cómo pueden ser diseñadas las aplicaciones con una simplicidad intuitiva, sin llegar a ser repetitivas y aburridas? ¿Cómo puede una aplicación ofrecer todos los detalles agradables, sin perder de vista un propósito mayor? La mayoría de las aplicaciones viven y mueren en los primeros días, así que aquí están los diez errores más comunes que los diseñadores pueden evitar.
Sólo el 3% de las aplicaciones móviles se mantienen en uso después de ser descargadas.
Sólo el 3% de las aplicaciones móviles se mantienen en uso después de ser descargadas.

Error Común # 1: Una Primer Mala Impresión

A menudo, el primer uso, o el primer día con una aplicación, es el período más crítico para atraer a un potencial usuario. La primera impresión es tan crítica que podría ser un punto de partida para el resto de éste top 10. Si algo no está bien, o parece confuso o aburrido, los usuarios potenciales pierden interés rápidamente; aunque, el equilibrio apropiado para la primera impresión es difícil de lograr. En algunos casos, un largo proceso de integración (onboarding), o un proceso para descubrir características necesarias pueden aburrir a los usuarios.
Sin embargo, una aplicación que sea tentadora instantáneamente puede pasar por alto la necesidad de un tutorial adecuado, y promover la confusión. Se debe encontrar el equilibrio entre una aplicación que es inmediatamente intuitiva, y que también introduzca a los usuarios a las características más divertidas y atractivas con rapidez. Ten en cuenta que cuando los usuarios llegan a tu aplicación, la están viendo por primera vez. Es importante tener un proceso de prueba adecuado para determinar cómo los demás perciben tu aplicación desde el principio. Lo que parece obvio para el equipo de diseño, puede que no lo sea para los recién llegados.

Integración Inadecuada

La integración o incorporación es el proceso paso a paso de la introducción de un usuario a tu aplicación. Aunque puede ser una buena manera de orientar a alguien de forma rápida, la integración también puede ser un proceso prolongado que se interpone en el camino de tus usuarios y su contenido. A menudo, estos tutoriales son demasiado largos, y es probable que los lean por encima.
A veces, los usuarios han visto que tu aplicación es utilizada en público o en algún otro lugar, de tal manera que llegan a entenderla de una vez y quieren usarla a la primera. Por lo tanto, permite una especie de estrategia de salida rápida para evitar por completo el bloqueo de la aplicación a partir de su primer uso. Para asegurarte que el proceso de incorporación es de hecho efectivo, debes tener en cuenta qué valores esto puede comunicar y cómo hacerlo. El proceso de integración debe demostrar el valor de la aplicación con el fin de enganchar un usuario, en lugar de sólo una explicación.

No Sobrecargues la Animación en el Inicio

Algunos diseñadores deciden dar una buena primera impresión con animaciones de entrada, que sean fascinantes y deslumbren a los nuevos usuarios. Sin embargo, ten en cuenta que cada vez que alguien quiere ejecutar la aplicación, va a tener que ver la misma cosa una y otra vez. Si la aplicación tiene una función diaria, entonces esto va a cansar a tus usuarios de forma rápida. Diez segundos del día de alguien para deslizar un logo por la pantalla y tal vez hacerlo girar un par de veces en realidad no vale la pena después de un tiempo.

Error Común # 2: Diseñar una Aplicación sin Propósito

Evita entrar en el proceso de diseño sin intenciones concisas. Las aplicaciones son a menudo diseñadas y desarrolladas con el fin de seguir las tendencias, en lugar de resolver un problema, llenar un nicho, u ofrecer un servicio distintivo. ¿Cuál es la ambición de la aplicación? Para el diseñador y su equipo, el sentido de propósito afectará cada paso de un proyecto. Esta sensibilidad guiará cada decisión de la marca o la comercialización de una aplicación, con el formato de wireframe, y un botón estético. Si el propósito es claro, cada pieza de la aplicación comunicará y funcionará como un todo coherente. Por lo tanto, asegúrate de que el equipo de diseño y desarrollo considere continuamente sus decisiones dentro de un objetivo mayor. A medida que avanza el proyecto, la ambición inicial puede cambiar. Esto está bien, siempre y cuando la visión siga siendo coherente.
Transmitir esta visión a tus usuarios potenciales significa que van a entender qué valor traerá la aplicación a sus vidas. Por lo tanto, esta visión es algo importante que se debe transmitir en la primera impresión. La pregunta es, ¿qué tan rápido puedes convencer a los usuarios de tu visión para la aplicación? Cómo se va a mejorar la vida de una persona, o proporcionar algún tipo de goce o comodidad. Si esta ambición es difundida eficazmente, entonces, siempre y cuando tu aplicación sea en realidad útil, llegará al 3%.
A menudo, unirse a un mercado pre-existente, o una aplicación del nicho de mercado, significa que hay aplicaciones que estudiar, mientras diseñas tu propia aplicación. Por lo tanto, ten cuidado de cómo eliges ‘dar nuevo propósito’ a lo que ya está en el mercado. Estudia el mercado de las aplicaciones existentes en lugar de solo revisar. Entonces, mejora a partir de productos existentes, en lugar de imitar sin pensar.

Error Común # 3: Desaprovechar el Diseño de Mapeo en UX

Ten cuidado de no pasar por alto una planificación cuidadosa de la arquitectura UX de una aplicación antes de comenzar un trabajo de diseño. Incluso antes de llegar a una etapa de wireframing, el flujo y la estructura de una aplicación deben ser mapeados.
Los diseñadores están, a menudo, demasiado emocionados como para producir la estética y detalles. Esto da lugar a una cultura de diseñadores que generalmente no aprecian el UX ni la lógica o la navegación necesaria dentro de una aplicación. Ve más despacio. Esboza el flujo de la aplicación primero antes de preocuparte demasiado por las pinceladas más finas. A menudo, las aplicaciones fallan por una falta general de flujo y organización, en lugar de datos imperfectos. Sin embargo, una vez que el proceso de diseño comienza siempre se debe mantener el objetivo principal en mente. Los detalles y estética deberían entonces evocar claramente el concepto primordial.

Error Común # 4: No Tomar en Cuenta el Presupuesto de Desarrollo de la Aplicación

Tan pronto como se dibuja la base de la aplicación, es un buen momento para obtener un presupuesto del equipo de desarrollo. De esta manera no se llega al final del proyecto y de repente se necesita empezar a eliminar características críticas. A medida que desarrollas tu carrera de diseño, siempre toma nota de los costos regulares de construcción de tus conceptos para que tu pensamiento de diseño corresponda con restricciones económicas. Los presupuestos deben ser las restricciones de diseño útiles dentro de las cuales se puede trabajar.
Muchas aplicaciones fallidas tratan de cargar demasiadas funciones desde su lanzamiento.
Muchas aplicaciones fallidas tratan de cargar demasiadas funciones desde su lanzamiento.

Error Común # 5: Sobrecarga de Características de Diseño

Con suerte, un riguroso wireframing marcará claramente la diferencia entre las funciones necesarias y las excesivas. La plataforma ya es la “navaja suiza” definitiva, por lo que tu aplicación no tiene que serlo. No sólo el sobrecargar una aplicación con características puede conducir a una probable experiencia de desorientación para el usuario, pero una aplicación sobresaturada también será difícil de comercializar. Si el uso de la aplicación es difícil de explicar de una manera concisa, lo más probable es que esta esté tratando de hacer demasiado. Disminuir características siempre es difícil, pero necesario. A menudo, la mejor estrategia podría ser la de ganar confianza desde el principio con una o algunas funciones, y más adelante en la vida de la aplicación se pueden “probar” las nuevas. De esta manera, las características adicionales son menos propensas a interferir con los cruciales primeros días de vida de una aplicación.

Error Común # 6: Descartar el Contexto de la Aplicación

Aunque las condiciones de la mayoría de las oficinas de diseño prácticamente operan en un vacío, los diseñadores de aplicaciones deben estar al tanto de contextos más amplios. Aunque el propósito y la ambición son importantes, se vuelven irrelevantes si no se dirigen en el contexto adecuado. Recuerda que aunque tú y tu equipo de diseño conocen la aplicación muy bien, y les parezca evidente la interfaz del usuario, esto puede no ser el caso para los nuevos usuarios, o diferentes grupos demográficos.
Ten en cuenta el contexto inmediato o situación en la que se pretende utilizar la aplicación. Teniendo en cuenta la situación social, ¿cuánto tiempo puede la persona considerar utilizar la aplicación? ¿Qué otra cosa podría ser útil para ellos encontrar dada la circunstancia? Por ejemplo, la interfaz UBER sobresale ya que se utiliza con mucha rapidez. Esto significa que en su mayor parte, no hay mucho espacio para otro tipo de contenido. Esto es perfecto porque cuando un usuario está fuera con sus amigos y necesita reservar un viaje, su conversación es poco interrumpida en el proceso. UBER esconde una gran cantidad de contenido de soporte dentro de la aplicación, pero sólo aparece una vez que el escenario lo requiere.
¿Quién es el público objetivo de la aplicación? ¿Cómo podría el tipo de usuario influir cómo es el diseño de la aplicación? Tal vez, debes considerar que una aplicación específica para un usuario más joven puede ser capaz de tomar más libertades asumiendo un cierto nivel de intuición por parte del usuario. Considerando que muchas funciones pueden necesitar ser señaladas específicamente para un usuario menos conocedor de la tecnología. ¿Tu aplicación está destinada a ser visitada de forma rápida y por un corto período de tiempo? O, ¿es una aplicación con una gran cantidad de contenido que permite a los usuarios quedarse en ella un tiempo? ¿Cómo será el diseño para transmitir este tipo de uso?
Un buen diseño de aplicación debe considerar el contexto en el que se utiliza.
Un buen diseño de aplicación debe considerar el contexto en el que se utiliza.

Error Común # 7: La Subestimación del Cross-Platform

A menudo, las aplicaciones se desarrollan rápidamente como respuesta a los cambios del mercado o competidores que avanzan. Esto suele resultar en contenido web siendo arrastrado a la plataforma móvil. Un tema constante, lo que se podría pensar sería ampliamente entendido ahora, sucede tan a menudo que las aplicaciones y otros contenidos para móviles hacen transiciones pobres entre el escritorio, o plataformas móviles. Ya no es posible que el diseño móvil haga reducción gradual de contenido web sin consecuencias con la esperanza de conseguir rápido un negocio en el mercado móvil. La transición de web a móvil no sólo significa reducir todo, sino también ser capaz de trabajar con menos. Las funciones, navegación y el contenido deben ser transportados con mínima estrategia.
Otro problema común aparece cuando un equipo de desarrollo de aplicación aspira a lanzar un producto al mismo tiempo en todas las plataformas, y través de diferentes tiendas de aplicaciones. Esto a menudo resulta en una compatibilidad pobre, o en general, una aplicación con errores y sin pulir. La gimnasia que implica un equilibrio de múltiples plataformas puede ser demasiado para sumarse al lanzamiento de una aplicación. Sin embargo, a veces no hace daño llevarlo lentamente con un sistema operativo a la vez y corregir los problemas principales, antes de preocuparse por la compatibilidad entre plataformas.

Error Común # 8: El Diseño de la Aplicación es Demasiado Complicado

El famoso arquitecto Mies Van der Rohe dijo una vez: “Es mejor ser bueno que ser único”. Asegúrate de que tu diseño esté cumpliendo con lo acordado antes de empezar a romper la caja o agregar adornos. Cuando un diseñador se encuentra a sí mismo añadiendo detalles a fin de hacer una composición más atractiva o emocionante, estas opciones, es probable, que carezcan de mucho valor. Seguir preguntando a lo largo del proceso de diseño, ¿cuánto puedo quitar? En lugar de diseñar de forma aditiva, diseña de forma reductora. ¿Qué no se necesita? Este método está dirigido tanto hacia el contenido, el concepto y la función, como a la estética.
La complejidad excesiva es a menudo el resultado de un diseño que innecesariamente rompe convenciones. Varios símbolos e interfaces son estándar dentro de nuestro lenguaje visual y táctil. ¿Tu producto realmente podrá beneficiarse de la reelaboración de estos estándares? Iconos Estándar han demostrado ser universalmente intuitivos. Por lo tanto, a menudo son la forma más rápida de proporcionar indicaciones visuales sin llenar innecesariamente una pantalla. No dejes que tus detalles de diseño interrumpan el contenido real ni el funcionamiento de la aplicación. A menudo, a las aplicaciones no se les da suficiente espacio en blanco. La necesidad de espacio en blanco es un concepto gráfico que ha trascendido tanto lo digital como lo impreso, por lo que no debe subestimarse. Mantén un espacio entre los elementos en la pantalla, de modo que todo el trabajo que pusiste en la navegación y UX se pueda sentir.
El proceso de diseño de aplicaciones puede ser reductor, en lugar de aditivo
El proceso de diseño de aplicaciones puede ser reductor, en lugar de aditivo

Error Común # 9: Inconsistencias de Diseño

En cuanto a la simplicidad, si un diseño va a introducir nuevos estándares, deben ser por lo menos equilibrados en toda la aplicación. Cada nueva función o parte del contenido no necesariamente tiene que ser una oportunidad para introducir un nuevo concepto de diseño. ¿Los textos están formateados de manera uniforme? ¿Los elementos de la interfaz se comportan de manera predecible, pero agradable a lo largo de la aplicación?
La coherencia del diseño debe encontrar el equilibrio entre la existente dentro del lenguaje visual común, así como evitar estar estéticamente estancada. El equilibrio entre la consistencia intuitiva y el aburrimiento es una línea muy fina.

Error Común # 10: Desaprovechar App Beta Testings

Todos los diseñadores deben analizar el uso de sus aplicaciones con algún tipo de ciclo de retroalimentación con el fin de aprender lo que está y no está funcionando. Un error común en las pruebas es que un equipo haga sus pruebas beta con sus propios miembros. Es necesario traer ojos frescos con el fin de excavar realmente en los borradores de la aplicación.
Envía un anuncio buscando probadores beta y trabaja con un grupo selecto antes de anunciarlo al público. Esto puede ser una gran manera de limar detalles, editar características, y encontrar lo que falta. A pesar de que las pruebas beta pueden llevar mucho tiempo, puede ser una mejor alternativa que desarrollar una aplicación que fracase. Anticipa que las pruebas a menudo toman 8 semanas para algunos desarrolladores para poder hacerlo correctamente. Evita el uso de amigos o compañeros de trabajo como probadores, ya que no pueden criticar la aplicación con la honestidad que necesitas. El uso de los blogs de aplicación o páginas web para revisar tu aplicación es otra manera de probar la aplicación en un lugar público sin un lanzamiento completo. Si estás teniendo dificultades al disminuir características para tu aplicación, esta es una buena oportunidad para ver qué elementos importan o no.
El mercado de diseño de aplicaciones es un campo de batalla, por lo que el diseño de productos que son sólo adecuados simplemente no es suficiente. Encuentra una manera de conectar a los usuarios desde el principio - comunicar y demostrar los valores críticos y características tan pronto como sea posible. Para poder hacer esto, el equipo de diseño debe tener una visión coherente de lo que la aplicación desea lograr. Para establecer esta ambición, un proceso de story-boarding riguroso puede limar lo que es y no es imprescindible. Considera qué tipos de usuarios encajarían mejor con la aplicación. Y luego, refina y perfecciona hasta que absolutamente nada más puede ser eliminado del proyecto sin que éste se caiga a pedazos.

Fuente: 
https://www.toptal.com/designers/mobile/los-10-errores-m%C3%A1s-comunes-en-dise%C3%B1o-de-aplicaciones-m%C3%B3viles/es

¿Qué son los Algoritmos Genéticos?

BY EUGENE OSSIPOV - FREELANCE SOFTWARE ENGINEER @ TOPTAL (TRANSLATED BY MARISELA ORDAZ)
Fuente 
https://www.toptal.com/algorithms/algoritmos-gen%C3%A9ticos-b%C3%BAsqueda-y-optimizaci%C3%B3n-por-selecci%C3%B3n-natural/es
En los últimos años, ha habido un alboroto en relación con la Inteligencia Artificial (IA). Las grandes compañías como Google, Apple y Microsoft trabajan activamente en este tema. De hecho, la IA es solo paraguas que cubre muchas metas, acercamientos, herramientas y aplicaciones. Los Algoritmos Genéticos (AG) son solo una de las herramientas inteligentes que buscan a través de muchas soluciones posibles.
El AG es una búsqueda meta-heurística al igual que una técnica de optimización basada en principios presentes en la evolución natural. Pertenece a una clase más larga de algoritmos evolutivas.
El AG mantiene una población de cromosomas—un set de soluciones posibles para el problema. La idea es que la “evolución” encuentre una solución óptima para el problema después de un número de generaciones sucesivas—similar a una selección natural.
El AG imita tres procesos evolutivos: selección, entrecruzamiento cromosómico y mutación.
Tal como la selección natural, el concepto central de la selección AG es la adaptación. Los cromosomas que se adaptan mejor tienen una mayor oportunidad de sobrevivir. La adaptación es una función que mide la calidad de la solución representada por el cromosoma. En esencia, cada cromosoma dentro de la población representa los parámetros de entrada, como el volumen y precio de cambio, cada cromosoma, lógicamente, consistirá de dos elementos. Como los elementos están codificados dentro del cromosoma es otro tema.
Durante la selección, los cromosomas forman parejas de padres para la reproducción. Cada niño toma características de sus padres. Básicamente, el niño representa una recombinación de características de sus padres: Algunas de las características son tomadas de un padre y otras del otro padre. Adicionalmente a la recombinación, algunas de las características pueden mutar.
Ya que los cromosomas más adecuados producen más niños, cada generación subsecuente será más adecuada. En algún punto, una generación contendrá un cromosoma que representará una solución lo suficientemente buena para nuestro problema.
El AG es poderoso y ampliamente aplicable a problemas complejos. Hay una clase extensa de problemas de optimización que son un tanto difícil de resolver usando técnicas convencionales de optimización. Los algoritmos genéticos son algoritmos eficientes que poseen soluciones aproximadamente óptimas. Las ya bien conocidas aplicaciones incluyen programación, transporte, planificación de ruta, tecnologías de grupo, diseño de plano, entrenamiento de red neural y muchos otros.

Poniendo las Cosas en Práctica

El ejemplo que veremos puede ser considerado el “Hello World” de AG. Este ejemplo fue presentado inicialmente por J. Freeman en Simulating Neural Networks with Mathematica. Yo lo tomé de Genetic Algorithms and Engineering Design por Mitsuo Gen y Runwei Cheng.
El problema simulador del mundo intenta evolucionar una expresión con un algoritmo genético. Inicialmente, el algoritmo debe “adivinar” la frase “ser o no ser” de listas de letras generadas al azar.
“Ya que hay 26 letras posibles para cada una de las 13 locaciones [excluyendo espacios en blanco] en la lista, la posibilidad de que obtengamos la frase correcta puramente al azar es (1/26)^13=4.03038×10-19, lo cual es aproximadamente dos chances en un [trillón]” (Gen & Chong, 1997).
Vamos a definir el problema un poco más aquí al hacer la solución aún más difícil. Asumamos que no estamos limitados a la lengua inglesa, o una frase específica. Podemos terminar lidiando con cualquier alfabeto, o hasta cualquier set de símbolos. No tenemos conocimiento de la lengua. Ni siquiera sabemos si hay algún idioma.
Digamos que nuestro oponente pensó en una frase arbitraria, incluyendo espacios en blanco. Sabemos el largo de la frase y la cantidad de símbolos en el alfabeto. Ese es el único conocimiento que tenemos. Después de cada suposición, nuestro oponente nos dice cuántas letras se encuentran en su lugar.
Cada cromosoma es una secuencia de índices de los símbolos en el alfabeto. Si hablamos del alfabeto inglés, entonces ‘a’ será representada por 0, ‘b’ por 1, ‘c’ por 2, y así sucesivamente. Entonces, por ejemplo, la palabra “ser” será representada como [4, 1].
Vamos a demostrar todos los pasos a través de trozos de código Java, pero el conocimiento en Java no es un requerimiento para entender cada paso.

El Centro del Algoritmo Genético

Podemos empezar con la implementación general del algoritmo genético:
public void find() {
// Initialization
List<T> population = Stream.generate(supplier)
.limit(populationSize)
.collect(toList());
// Iteration
while (!termination.test(population)) {
// Selection
population = selection(population);
// Crossover
crossover(population);
// Mutation
mutation(population);
}
}
Este es un set de pasos simples que todo AG debería tener. En el paso inicial, generamos una población inicial de frases. El tamaño de la población está determinada por populationSize. Y como se genera esta frase depende de la implementación del supplier.
Dentro del paso de iteración, evolucionamos la población hasta que se dan las condiciones de término, dentro de la prueba de nudo while. Las condiciones de término pueden incluir el número de generaciones y la pareja perfecta de una de las frases en la población. El termination encapsula una implementación exacta.
Dentro de cada iteración, hacemos los típicos pasos de AG:
  1. Lleva a cabo una selección sobre la población en adecuación de cromosomas.
  2. Produce una nueva “generación” vía la operación de entrecruzamiento.
  3. Lleva a cabo una recombinación de algunas letras en algunas frases.
El centro del algoritmo es muy simple y de dominio agnóstico. Sería el mismo para todo los problemas. Lo que debes ajustar es la implementación de operadores genéticos. Luego, miraremos más de cerca a cada uno de los ya mencionados operadores AG.

Selección

Como ya sabemos, la selección es un proceso hecho para encontrar sucesores para los cromosomas actuales—los cromosomas que sean más adecuados para nuestro problema. Durante la selección, necesitamos asegurar que los cromosomas con mejor adecuación tienen más chance de sobrevivir.
private List<T> selection(List<T> population) {
final double[] fitnesses = population.stream()
.mapToDouble(fitness)
.toArray();
final double totalFitness = DoubleStream.of(fitnesses).sum();
double sum = 0;
final double[] probabilities = new double[fitnesses.length];
for (int i = 0; i < fitnesses.length; i++) {
sum += fitnesses[i] / totalFitness;
probabilities[i] = sum; }
probabilities[probabilities.length - 1] = 1;
return range(0, probabilities.length).mapToObj(i -> {
int index = binarySearch(probabilities, random());
if (index < 0) {
index = -(index + 1);
}
return population.get(index);
}).collect(toList());
}
La idea de esta implementación es la siguiente: La población es representada como rasgos consecuentes en el eje numérico. La población completa está entre 0 y 1.
Demostración visual de cómo funciona el paso de la selección en nuestro algoritmo genético
El trozo de la serie que toma un cromosoma es proporcional a su adecuación. Esto da como resultado un cromosoma mucho más adecuado el cual toma un trozo más grande. Luego escogemos un número al azar entre 0 y 1 y encontramos una serie que incluye este número. Obviamente, las series más grandes tienen mejor oportunidad de ser seleccionados, por ende, los cromosomas más adecuados tienen mejor oportunidad de sobrevivir..
Ya que no conocemos detalles sobre la función de la adecuación, necesitamos normalizar los valores de adecuación. La función de adecuación es representada por fitness, la cual convierte a un cromosoma en un doble arbitrario que representa la adecuación del cromosoma.
En el código, encontramos una tarifa de adecuación para todos los cromosomas en la población y también encontramos la adecuación total. Dentro del nudo for, ejecutamos una suma acumulativa sobre probabilidades disminuidas por adecuación total. Matemáticamente, esto debería resultar en la variable final teniendo un valor de 1. Debido a la imprecisión del punto flotante, no podemos garantizar eso, así que lo ajustamos a 1 para estar seguros.
Finalmente, por una cantidad de tiempo igual al número de cromosomas entrantes, generamos un número al azar, encontramos una serie que incluya el número y luego seleccionamos el cromosoma correspondiente. Como debes haber notado, el mismo cromosoma puede ser seleccionado muchas veces.

Entrecruzamiento

Ahora necesitamos que los cromosomas se “reproduzcan.”
private void crossover(List<T> population) {
final int[] indexes = range(0, population.size())
.filter(i-> random() < crossoverProbability)
.toArray();
for (int i = 0; i < indexes.length / 2; i++) {
shuffle(Arrays.asList(indexes));
final int index1 = indexes[2 * i];
final int index2 = indexes[2 * i + 1];
final T value1 = population.get(index1);
final T value2 = population.get(index2);
population.set(index1, crossover.apply(value1, value2));
population.set(index2, crossover.apply(value2, value1));
}
}
Con la probabilidad predefinida como crossoverProbability, seleccionamos padres para la reproducción. Los padres que sean seleccionados son mezclados, permitiendo así que se de cualquier combinación. Tomamos parejas de padres y aplicamos el operador crossover. Aplicamos el operador dos veces para cada pareja porque necesitamos mantener el mismo tamaño de la población. Los niños reemplazan a los padres en la población.

Mutación

Finalmente, llevamos a cabo la recombinación de las características.
private void mutation(List<T> population) {
for (int i = 0; i < population.size(); i++) {
if (random() < mutationProbability) {
population.set(i, mutation.apply(population.get(i)));
} }
}
Con la probabilidad mutationProbability predefinida, llevamos a cabo la “mutación” en los cromosomas. La mutación como tal es definida como mutation.

Configuración de Algoritmo de Problema-Específico

Ahora echemos un vistazo a qué tipo de parámetros de problema específico necesitamos proveer para nuestra implementación genérica.
private BiFunction<T, T, T> crossover;
private double crossoverProbability;
private ToDoubleFunction<T> fitness;
private Function<T, T> mutation;
private double mutationProbability;
private int populationSize = 100;
private Supplier<T> supplier;
private Predicate<Collection<T>> termination;
Los parámetros, respectivamente, son: 1. Operador de entrecruzamiento 2. Probabilidad de entrecruzamiento 3. Función de adecuación 4. Operador de mutación 5. Probabilidad de mutación 6. Tamaño de la población 7. Proveedor de cromosomas para la población inicial 8. Función de término
Aquí está la configuración de nuestro problema:
new GeneticAlgorithm<char[]>()
.setCrossover(this::crossover)
.setCrossoverProbability(0.25)
.setFitness(this::fitness)
.setMutation(this::mutation)
.setMutationProbability(0.05)
.setPopulationSize(100)
.setSupplier(() -> supplier(expected.length))
.setTermination(this::termination)
.find()

Operador de Entrecruzamiento y Probabilidad

private char[] crossover(char[] value1, char[] value2) {
final int i = (int) round(random() * value1.length);
final char[] result = new char(value1.length);
System.arraycopy(value1, 0, result, 0, i);
System.arraycopy(value2, i, result, i, value2.length - i);
return result;
}
La probabilidad de entrecruzamiento es 0.25, así que esperamos que en promedio, 25 por ciento de los cromosomas sean seleccionados para el entrecruzamiento. Llevamos a cabo un simple procedimiento, para el entrecruzamiento de un par de cromosomas. Generamos un número al azar n para la selección [0..length], dónde length es el largo del cromosoma. Ahora unimos la pareja seleccionada tomando el primer símbolo n de uno de los cromosomas y el resto de los símbolos después del segundo.

Función Adecuada

private double fitness(char[] value) {
return range(0, value.length)
.filter(i -> value[i] == expected[i])
.count();
}
La función adecuada simplemente cuenta el número de combinaciones entre la frase clave y el cromosoma dado.

Operador de Mutación y Probabilidad

private char[] mutation(char[] value) {
final char[] result = Arrays.copyOf(value, value.length);
for (int i = 0; i < 2; i++) {
int letter = (int) round(random() * (ALPHABET.length - 1));
int location = (int) round(random() * (value.length - 1));
result[location] = ALPHABET[letter];
}
return result;
}
La operación de mutación se ejecuta independientemente en cada cromosoma. La probabilidad de mutación es de 0.05, así que esperamos que, en promedio cinco por ciento de la población sea mutada. Mutamos al escoger una posición de letra al azar y reemplazar su valor con una letra al azar del alfabeto. Lo hacemos dos veces por cada cromosoma mutado.

Proveedor

private char[] supplier(int length) {
final char[] result = new char(length);
for (int i = 0; i < length; i++) {
int letter = (int) round(random() * (ALPHABET.length - 1));
result[i] = ALPHABET[letter];
}
return result;
}
El proveedor genera frases al azar tomando letras del alfabeto igualmente al azar. Cada frase tiene un largo constante predefinido.

Función de Término

private boolean termination(Collection<char[]> chars) {
count++;
final Optional<char[]> result = chars.stream()
.filter(value -> round(fitness(value)) == expected.length)
.findAny();
if (result.isPresent()) {
System.out.println("Count: " + count);
System.out.println(result.get());
return true;
}
final boolean terminated = count == 3000;
if (terminated) {
chars.forEach(System.out::println);
}
return terminated;
}
La función término cuenta el número de llamadas y regresos true, si hay ya una pareja exacta, o si la cuenta de la generación llega a 3,000.

Ejecución

Ahora estamos listos para probar nuestro algoritmo. Si lo ejecutas varias veces, notarás que no todas las ejecuciones son exitosas. En cada oportunidad, el número de iteraciones será diferente. Esto se debe a una naturaleza de probabilidad del algoritmo. El algoritmo tiene varios puntos donde se puede mejorar. Puedes jugar con entrecruzamiento y probabilidades de mutación.
Bajar el número a una solución estable pero lenta. Un número más pequeño de cromosomas se verá afectado por operadores genéticos, por tanto, más iteraciones serán requeridas para la solución.
Aumentar los números acelerará el algoritmo, pero también hará que la solución sea inestable. Los cromosomas adecuados no solo serán preservados, pero también se verán afectados por los operadores genéticos. Por este motivo, perderán sus “buenos” genes.
Es importante encontrar un buen balance. Aumentar el número de iteraciones le dará al algoritmo más oportunidades para encontrar una solución pero, por otra parte, tomará más tiempo. También aplicar métodos diferentes de entrecruzamiento y mutación. Una buena selección de estos operadores mejorará drásticamente la calidad de la solución.

¿Qué sigue?

Hemos cubierto solo la punta del iceberg. Tomamos un ejemplo que tiene solo una entrada y ésta puede ser presentada, fácilmente, como un cromosoma. Los operadores genéticos son simples.
Es muy interesante tomar un problema de la vida real y aplicar el algoritmo genético a éste. Descubrirás diferentes acercamientos al codificar entradas de data reales, al igual que diferentes implementaciones de entrecruzamiento y mutación.
Si un problema puede ser expresado a través de un set de parámetros que tenemos que adivinar para optimizar una métrica, podemos establecer rápidamente un AG que podemos usar para resolverlo.
Uno de los problemas más interesantes es enseñar redes neuronales artificiales. Podemos establecer los parámetros optimizados para ser fuerzas sinapsis y para que la métrica adecuada sea el porcentaje de entradas por el cual nuestras redes neurales hayan dado la respuesta correcta. Después de eso, nos podemos relajar y dejar que nuestras redes neurales evolucionen en la solución ideal que deseamos. O al menos hasta que tengamos algo lo suficientemente bueno, porque la evolución toma tiempo.

Seguidores