Archivo de la etiqueta: Java

Tutorial Material Design en Android #4

Crear un Navigation Drawer para Android

Después de una pequeña pausa retomamos la serie de tutoriales de Material Design en Android, en el tutorial anterior aprendimos como agregar iconos (actions) a nuestra Toolbar, así que lo que sigue ahora es aprender cómo implementar el Navigation Drawer.

El Navigation Drawer en Android es un panel que podemos utilizar en nuestra app y que por lo general contiene un menú para movernos o “navegar” por las distintas secciones en la aplicación, la principal ventaja es que puede permanecer oculta la mayor parte del tiempo y desplegarse solo cuando el usuario lo necesite, de esa manera “economizamos” el espacio en la pantalla del teléfono, como en los tutoriales anteriores, si quieren aprender un poco más sobre la teoría siempre pueden consultar la documentación oficial de google Navigation Drawer

patterns_navdrawer_settings1

También vale la pena mencionar que hay básicamente 3 estilos de Navigation Drawer:

  • Navigation Drawer por debajo de la Toolbar oscurenciendola
  • Navigation Drawer por debajo de la Toolbar sin oscurecerla
  • Navigation Drawer por encima de la Toolbar

El estilo que queramos lograr dependerá de cómo escribamos el xml en nuestras views, y un poco de Java también

playstore_styledrawer_bellowdrawer_over_toolbar

Pues manos a la obra, o mejor dicho al código, vamos a nuestro archivo activity_main.xml y deberíamos de tener algo así.

activity_main

Vamos a modificar un poco nuestro código xml y agregaremos un par de elementos llamados DrawerLayout, FrameLayout y NavigationDrawer, viendo la siguiente imagen quedara más claro lo que vamos a hacer en nuestra activity.

drawer_layout_demon

Vamos a crear un elemento android.support.v4.widget.DrawerLayout y vamos a meter todo nuestro código existente dentro de esa etiqueta.

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.alevsk.materialdesignapp.MainActivity">

        <include
            android:id="@+id/app_bar"
            layout="@layout/app_bar" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/app_bar"
            android:text="@string/hello_world" />

    </RelativeLayout>
</android.support.v4.widget.DrawerLayout>

Lo siguiente es crear un Fragment y lo que hago normalmente para tener mi código más organizado es crear un nuevo Package en el proyecto llamado fragments y ahí empiezo a crearlos, para eso en su com.alevsk.materialdesignapp > botón secundario > new > Package y le ponen el nombre que deseen, yo le puse fragments para que sea descriptivo, después de eso procedemos a crear la nueva clase como se muestra en la siguiente imagen.

fragments

Nos aparecerá el siguiente cuadro de dialogo donde tendremos que elegir el nombre del nuevo menú NavigationDrawer (fragmento), le ponemos NavigationDrawerFragment o como ustedes quieran pero que sea descriptivo hacia el hecho de que será el menú de nuestra aplicación, asegúrense de marcar la opción de crear el layout xml y podemos desmarcar las dos opciones de abajo, el código que nos genere Android studio será más limpio y nosotros implementaremos los métodos que necesitamos desde 0, para terminar damos clic en el botón de Finish.

navigationdrawerfragment

Android Studio nos habrá generado dos archivos, NavigationDrawerFragment.java y fragment_navigation_drawer.xml

1

2

En nuestro fragment_navigation_drawer.xml vamos a modificar el elemento principal de Fragment a RelativeLayout quedando el código de la siguiente manera

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.alevsk.materialdesignapp.fragments.NavigationDrawerFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</RelativeLayout>

Hicimos este cambio ya que más adelante necesitaremos agregar elementos extras como un RecyclerView, a continuación vamos al archivo activity_main.xml y vamos a agregar nuestro NavigationDrawer usando un elemento fragment de la siguiente forma.

    <fragment
        android:id="@+id/fragment_navigation_drawer"
        android:name="com.alevsk.materialdesignapp.fragments.NavigationDrawerFragment"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:layout="@layout/fragment_navigation_drawer"
        tools:layout="@layout/fragment_navigation_drawer" />

El codigo final del activity_main.xml es el siguiente:
3

Lo que sigue es crear un objeto NavigationDrawer en nuestro MainActivity.java

NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);

Si por alguna razón les da un error de compatibilidad asegúrense que en NavigationDrawerFragment.java en la sección de import (hasta arriba) el Fragment que esté utilizando sea android.support.v4.app.Fragment

Ya que estamos en este archivo vamos a crear de una vez un método llamado setUp que va a servir para inicializar los componentes de nuestro NavigationDrawer, también vamos a utilizar un nuevo objeto llamado ActionBarDrawerToogle cuya finalidad es la de manejar nuestro DrawerLayout y Toolbar de una manera más eficiente, así como encargarse de manejar el evento de abrir y cerrar el panel de navegación.

    public void setUp(DrawerLayout drawerLayout, Toolbar toolbar) {
        mDrawerLayout = drawerLayout;
        mToolbar = toolbar;
        mDrawerToggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar, R.string.open, R.string.close) {
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

Tip: R.string.open y R.string.close son necesarios para el constructor del ActionBarDrawerToggle ya que son los textos que aparecen al abrir y cerrar el panel, pueden definir esas cadenas en su archivo strings.xml que se encuentra en res/values

<string name="open">Abierto</string>
<string name="close">cerrado</string>

De nuevo, aquí mucho cuidado, asegúrense de que el Toolbar que estén importando sea android.support.v7.widget.Toolbar para efectos de compatibilidad, ya que si utilizan la clase por defecto les va a dar errores en los demás archivos.

Lo que acabamos de hacer en nuestro código es definir un nuevo ActionBarDrawerToggle, vinculamos el DrawerLayout y Toolbar que estamos recibiendo desde nuestro MainActivity y preparamos el listener (manejador de eventos) para cuando el usuario abra y cierre el panel de navegación.

En el MainActivity.java después de instanciar nuestro NavigationDrawer mandamos llamar el método

public class MainActivity extends ActionBarActivity {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.app_bar);
        setSupportActionBar(toolbar);

        NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
        drawerFragment.setUp((DrawerLayout)findViewById(R.id.drawer_layout),toolbar);
    }

La clase NavigationDrawerFragment quedo de la siguiente manera
NavigationDrawerFragment

En este punto, si corremos nuestra aplicación y deslizamos haciendo tap desde la izquierda podemos observar como la pantalla comienza a oscurecerse, si ponemos un poco más de atención podemos ver el texto de nuestro fragment encima de la app”Hello Blank Fragment“, ha funcionado! ahora solo nos queda poner un poco de estilo para hacer a aplicación más agradable a la vista.

navigation_drawer_feo

En nuestro archivo colors.xml (se encuentra en app/res/values/colors.xml) podemos definir nuevos colores, por ejemplo yo he definido uno nuevo llamado graypanel

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primaryColor">#E91E63</color>
    <color name="primaryColorDark">#C2185B</color>
    <color name="textColorPrimary">#FFFFFF</color>
    <color name="grayPanel">#EEEEEE</color>
    <color name="lightGray">#d6d6d6</color>
    <color name="colorAccent">#8BC34A</color>
</resources>

Y despues en nuestro fragment_navigation_drawer.xml definimos el color de fondo a nuestro RelativeLayout con android:background=”@color/grayPanel”

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/grayPanel"
    tools:context="com.alevsk.materialdesignapp.fragments.NavigationDrawerFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</RelativeLayout>

navigation_drawer_color

¿Un poco mejor cierto? pero todavía le falta bastante, por ejemplo no resulta obvio para el usuario saber que la aplicación tiene un menú lateral, lo que vamos a hacer es agregar el clásico icono de menú de lado izquierdo, para eso utilizaremos un método llamado syncState de nuestro objeto DrawerToggle.

Nos vamos a nuestro archivo NavigationDrawerFragment.java y agregamos el siguiente código después de haber hecho el mDrawerLayout.setDrawerListener(mDrawerToggle);

        mDrawerLayout.post(new Runnable() {
            @Override
            public void run() {
                mDrawerToggle.syncState();
            }
        });

Corremos la app de nuevo y automáticamente nos aparecerá un icono de menú.

menu_icon

Una vez abierto el menú de navegación rara notaran que si hacemos tap donde se supone que esta el botón de menú el panel se cierra, es bastante raro pues la aplicación no está respetando las “capas”, podemos corregir ese comportamiento bajando un poco el NavigationDrawer.

Modificamos un poco nuestro archivo main_activity.xml, si se fijan bien ahora nuestro DrawerLayout esta debajo de nuestra app_bar, ambos elementos estan al mismo nivel y rodeados por un LinearLayout con orientación vertical.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="@color/lightGray"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/app_bar"
        layout="@layout/app_bar" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="@string/hello_blank_fragment" />
        </RelativeLayout>

        <fragment
            android:id="@+id/fragment_navigation_drawer"
            android:name="com.alevsk.materialdesignapp.fragments.NavigationDrawerFragment"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:layout="@layout/fragment_navigation_drawer"
            tools:layout="@layout/fragment_navigation_drawer" />
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

drawer_navigation

Y eso es todo por ahora, así es como se programa un NavigationDrawer desde 0 :), en el siguiente tutorial implementaremos las opciones en nuestro menú de navegación, para eso aprenderemos a utilizar los RecyclerViews.

He montado un repositorio en Github con el código de la aplicación que vamos desarrollando durante los tutoriales, si tienen alguna duda pueden consultarlo directamente de ahí o preguntarme en los comentarios https://github.com/Alevsk/Material-design-en-Android

salu2

Tutorial Material Design en Android #1

Los colores de la aplicación

En el tutorial anterior aprendimos a Crear un nuevo proyecto de Android Material Design, hicimos algunas configuraciones en el archivo AndroidManifest.xml y creamos algunos nuevos estilos en el archivo style.xml.

Pues en esta ocasión vamos aprender a personalizar los colores de nuestra app, tanto del ToolBar / ActionBar como del StatusBar y los demás elementos de la interfaz gráfica. Recomiendo revisen la documentación oficial más a fondo en el siguiente link

Pero en resumen dice lo que explicare a continuación, básicamente tenemos 5 elementos que podemos personalizar por default:

  • colorPrimary
  • colorPrimaryDark
  • colorAccent
  • textColorPrimary
  • windowBackground
  • navigationBarColor

En la siguiente imagen podemos observar a que parte de la interfaz corresponde cada elemento 🙂

ThemeColors

Ya se imaginan lo que sigue, les recomiendo las paletas de colores de google, por lo pronto elijamos la que sea y comencemos a configurar los valores en nuestra aplicación para ir viendo cómo va quedando.

Es una buena práctica separar los recursos que utilizara la aplicación en varios archivos por lo que dentro de la carpeta values vamos a crear un nuevo archivo colors.xml, si no recuerdan como crear un nuevo archivo de recursos regresen al primero tutorial donde creamos el archivo styles.xml.

Ya con el archivo colors.xml creado vamos a comenzar agregando los colores de nuestra elección, mi archivo quedo con el siguiente contenido.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primaryColor">#E91E63</color>
    <color name="primaryColorDark">#C2185B</color>
    <color name="colorAccent">#8BC34A</color>
</resources>

Y mis colores fueron:

color_pallete

Ahora en nuestro archivo styles.xml en donde hicimos la definición de nuestro Tema AppTheme.Base vamos a definir el uso de los colores que acabamos de crear 🙂 de la siguiente forma:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="AppTheme.Base">
        <!-- Customize your theme here. -->
    </style>

    <style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryColorDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

De la misma manera vamos a agregar esas definiciones de color de elementos en el otro archivo styles.xml (el que tenemos para dispositivos con api 21), quedando de la siguiente manera, noten que en estas definiciones estamos añadiendo el prefijo android:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:colorPrimary">@color/primaryColor</item>
        <item name="android:colorPrimaryDark">@color/primaryColorDark</item>
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <item name="android:colorAccent">@color/colorAccent</item>
    </style>

</resources>

Corremos la app en nuestro emulador favorito y observamos los resultados 🙂

material_app

En el siguiente tutorial vamos a aprender acerca del ToolBar y como personalizarla. salu2

BurpSuite para desarrolladores

BurpSuite es una herramienta muy popular en el mundo de la seguridad informática, se trata de una completa suite para hacer auditoria y explotación de aplicaciones web, entre sus muchas funcionalidades se encuentra el proxy, el escáner de vulnerabilidades y un repetidor de peticiones, entre muchas otras mas.

Una versión gratuita puede ser descargada del siguiente enlace
http://portswigger.net/burp/download.html.

¿Y ahora que? ¿Que tiene que ver una herramienta de seguridad informática en un trabajo de desarrollo de software?

Lo mejor de ambos mundos

Muchas veces cuando estamos desarrollando aplicaciones móviles complejas, es decir que requieren de algún mecanismo de comunicación con servicios web podemos llegar a retrasarnos y tener problemas debido a que no tenemos una manera clara y eficiente de saber que es lo que esta enviando y recibiendo en la app, el debugger de Android Studio siempre funciona y es de bastante utilidad pero no es una herramienta especializada para interceptar paquetes de red.

Lo que vamos a hacer es, una vez que hayamos instalado BurpSuit, ya sea para Windows, Linux o Mac, lo ejecutamos, como el ejecutable es un .jar requerimos Java para correrlo por lo que si no lo tenemos deberíamos también descargarlo e instalarlo.

burp_2

Ya en BurpSuite la opción que nos interesa es la de proxy, así que hacemos clic en la pestaña y después nos vamos a opciones, tendremos una interfaz similar a la siguiente.

burp_1

Por default BurpSuite solo esta escuchando conexiones de localhost (127.0.0.1) por lo que para interceptar peticiones de otros usuarios de nuestra red debemos agregar un nuevo listener, hacemos clic en el botón que dice Add y seleccionamos All interfaces, finalmente escribimos un puerto diferente al 8080 asignado por default al primer listener, por ejemplo 8085.

burp_3

Damos clic en el botón de OK y en la pestaña de Alerts, en los Logs BurpSuite nos indicara que el nuevo listener ya esta corriendo.

burp_4

Lo siguiente será obtener la dirección de ip asignada a nuestra maquina, eso depende de que sistema operativo estemos usando y no es difícil encontrarla, utilicen Google para investigar mas al respecto.

burp_5

Tomamos esa dirección y la guardamos, 192.168.43.204, ya que mas tarde la necesitaremos.

Ahora en nuestro dispositivo, para este ejemplo yo utilizo Android, pero hoy en dia cualquier Smartphone, ya sea Android, iOS, Windows Phone o BlackBerry tienen una opción para configurar proxy, en ese apartado debemos colocar la ip de nuestro servidor proxy junto con el puerto en el que escucha.

burp_8

Esperamos un par de segundos y comenzamos a interactuar con nuestra aplicación en desarrollo, si todo quedo bien configurado deberíamos comenzar a interceptar las peticiones de nuestra aplicación en BurpSuite.

burp_6

Ahora podemos ver los las cabeceras y los parámetros que estamos enviando y revisar que es lo que esta fallando en nuestra aplicación de manera mas cómoda.

burp_7

Para interceptar comunicaciones seguras con SSL en BurpSuite hacen falta un par de pasos de configuración extra, pero nada del otro mundo, se los dejo de tarea o tal vez publique un tutorial al respecto en un post futuro.

Nota: No olvides quitar la configuración del proxy en tu Smartphone una vez que termines las pruebas, ya que si apagas tu computadora te quedaras sin acceso a internet.

Tutorial Bing Search API 2.0 y PHP

Ha inicios del mes de agosto la gente de Microsoft mejoro (por no decir que modifico) la forma en que los desarrolladores interactuaban con la api, mejor conocida como bing api 2.0 ahora. Esto lógicamente causo bastantes problemas a las empresas y programadores independientes que no realizaron adoptaron los cambios en sus aplicaciones rápidamente, la mayor novedad que nos presenta ahora la api es que trabaja directamente con Windows Azure Marketplace.

Muchas personas pensaran que modificar sus aplicaciones para que vuelvan a funcionar va a ser una tarea muy tediosa, pero de hecho es bastante sencillo, a continuación he escrito una serie de pasos que te permitirá migrar una aplicación a bing api 2.0, mas concretamente utilizaremos la Bing search api 2.0

  • Registrarte en el Windows Azure Marketplace (usando tu cuenta de hotmail es suficiente)
  • Una vez registrado puedes acceder a la sección de datos del marketplace donde además de Bing Search Api (que es el servicio que utilizaremos en este tutorial) también podrás hacer uso de otros servicios como Microsoft Translator, etc. Lista de servicios de Bing

  • Al hacer clic en el servicio serás enviado a una vista donde se proporciona mas información acerca de la api así como una lista de precios por utilizar la api mensualmente, si crees que tu aplicación no tendrá mas de 5000 peticiones por mes a la api podrías utilizar el paquete gratuito al servicio (el ultimo precio que se muestra) de lo contrario te recomiendo adquirir algún otro paquete con las transacciones por mes que mas se ajusten a tus necesidades
  • Una vez suscrito al paquete de tu preferencia (hacer clic, aceptar términos, etc, etc.) en la sección de claves de cuenta podrás encontrar la key necesaria para poder conectarte al servicio y empezar a hacer uso de el. Así mismo en la sección de Mis datos encontraras un resumen de las aplicaciones que estas utilizando actualmente y el estado del numero de consultas restantes por mes, etc.

Listo eso es todo lo que tienes que configurar para comenzar a hacer uso de la api de bing :), ahora para no dejar el articulo a medias les dejo un pequeño código en PHP que nos regresa los resultados encontrados de la query que le pasemos a la api.

<?php

  $api = 'https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Web?$format=json&$top=8&Query=';
  $accountKey = "LA KEY QUE APARECE EN LA SECCION DE CLAVES DE CUENTA";
  $context = stream_context_create(array(
    'http' => array(
        'request_fulluri' => true,
        'header'  => "Authorization: Basic " . base64_encode($accountKey . ":" . $accountKey)
    )
  ));

  $query = 'alevsk';
  $request = $api . '%27'.$query.'%27';

  $jsonResponse =  json_decode(file_get_contents($request, 0, $context));
  print_r($jsonResponse);
  
?>

El código es bastante sencillo pero creo que deja bastante claro cuales son los requerimientos mínimos para interactuar con la api como la autentificación, los sources y el formato de respuesta, si tienes mas dudas acerca de los parámetros que recibe la api puedes utilizar el generador de consultas que proporciona el sitio o también acceder a el utilizando el enlace de “Usar” (el que esta a la derecha en la imagen anterior).

El generador de consultas de bing api 2.0 se trata de una herramienta bastante útil ya que te permite configurar tus request de una manera muy amigable y al final en la parte superior te muestra como quedaría la petición (la URL) que deberías de hacer a la api para obtener los resultados mostrados abajo :).

Muy importante, aquí les dejo la documentacion completa de la api que podrán utilizar como referencia.

Con esto espero que haya quedado claro o por lo menos entendible la nueva manera de interactuar con la api de bing y como siempre digo, si hay dudas respecto al código pueden escribirlas en los comentarios y con gusto las resolveré.

salu2

Algoritmo genético hecho en Java


Ha pasado bastante tiempo desde que no publico algún código mío, esta vez quiero compartir con ustedes un algoritmo genético hecho en Java que tuve que hacer para mi clase de Sistemas Inteligentes 😀 en el modulo de computación evolutiva, para los que no sepan que es un algoritmo genético, por aca tienen mas información.

El problema resuelto fue el problema del viajante o TSP, nuestro problema consiste básicamente en que tenemos n ciudades, que están conectadas entre si, todas con todas (n*n caminos) y existen varios objetivos, en mi caso tengo que minimizar la distancia recorrida.

Los pasos de todo algoritmo genético deben de ser

  • Generar población
  • Seleccionar a los individuos mas aptos (Torneo, selección por ruleta, etc)
  • Cruzarlos (recombinacion)
  • Mutación

Esto se realiza durante n generaciones y el objetivo es que cada generación los individuos sean mejores que los anteriores (aunque no siempre es así xD). Ahora les muestro un ejemplo de como es que funciona, supongamos que generamos nuestra población inicial la cual consiste en un camino que tiene que tomar el viajante, tiene como restricción que no puede repetir ciudades por las que ha pasado antes y el recorrido termina en la ciudad de la que partimos, ejemplo:

Batemans-Bay-Outreach  Ashfield  Bateau-Bay  Bankstown  Armidale  Blackett  Bega  | Bathurst  Bidwill  | Bradbury Airds  Albury  Batemans-Bay-Outreach  120.68747174103011

Podemos ubicar las ciudades en un plano cartesiano y verlas como si fueran puntos, desde esa perspectiva es posible sacar la distancia total del recorrido aplicando distancia euclidiana entre los puntos.

Después de eso podemos realizar una selección, entre los métodos mas comunes están el de selección por ruleta o el de selección por torneo, en este ultimo tan solo tenemos que ordenar la lista de caminos de menor a mayor y en mi caso elegir n * 3 individuos que representaran a los padres de la siguiente generación, ahora, en este punto es importante saber cuales tenemos que elegir ya que en probabilidad es poco posible que si cruzamos los 2 individuos mejor adaptados de la generación salga uno aun mas adaptado, por el contrario podría “des evolucionar” el hijo, es por eso que yo recomiendo, si vemos la población como si estuviera ordenada en una pila, tomar de los de arriba (los mejores adaptados) y algunos de en medio.

En este punto ya tenemos a los que serán los padres, ahora debemos de cruzarlos, existen varias técnicas de cruza como recombinación en 1 punto, recombinación en 2 puntos, corte y empalme, Recombinación uniforme y uniforme media y Recombinación de cromosomas ordenados, mas información aqui.

En mi caso yo utilice recombinación en 2 puntos y después aplique un algoritmo de mi creación para corregir el camino en caso de que hubiera ciudades repetidas en el.

minCutPoint: 6 maxCutPoint: 9

Padres:

Batemans-Bay-Outreach  Ashfield  Bateau-Bay  Bankstown  Armidale  Blackett  Bega  | Bathurst  Bidwill  | Bradbury Airds  Albury  Batemans-Bay-Outreach  120.68747174103011
Airds  Bankstown  Albury  Armidale  Ashfield  Batemans-Bay-Outreach  Bathurst      | Bega  Bateau-Bay  | Bidwill  Bradbury  Blackett  Airds  122.0081148734119

Hijos sin verificar:
Batemans-Bay-Outreach  Ashfield  Bateau-Bay  Bankstown  Armidale  Blackett  Bega  | Bega  Bateau-Bay  | Bradbury  Airds  Albury  Batemans-Bay-Outreach  0.0
Airds  Bankstown  Albury  Armidale  Ashfield  Batemans-Bay-Outreach  Bathurst      | Bathurst  Bidwill  | Bidwill  Bradbury  Blackett  Airds  0.0

F1Extract = | Bathurst  Bidwill  |
F2Extract = | Bega  Bateau-Bay  |

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Cruza hijo 1:

Batemans-Bay-Outreach  Ashfield  Bateau-Bay  Bankstown  Armidale  Blackett  Bega      | Bega  Bateau-Bay  | Bradbury  Airds  Albury  Batemans-Bay-Outreach  0.0

Batemans-Bay-Outreach  Ashfield  Bateau-Bay  Bankstown  Armidale  Blackett  Bathurst  | Bega  Bateau-Bay  | Bradbury  Airds  Albury  Batemans-Bay-Outreach  0.0

Batemans-Bay-Outreach  Ashfield  Bidwill  Bankstown  Armidale  Blackett  Bathurst      | Bega  Bateau-Bay  | Bradbury  Airds  Albury  Batemans-Bay-Outreach  0.0

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Cruza hijo 2:

Airds  Bankstown  Albury  Armidale  Ashfield  Batemans-Bay-Outreach  Bathurst  | Bathurst  Bidwill  | Bidwill  Bradbury  Blackett  Airds  0.0

Airds  Bankstown  Albury  Armidale  Ashfield  Batemans-Bay-Outreach       Bega  | Bathurst  Bidwill  | Bidwill  Bradbury  Blackett  Airds  0.0

Airds  Bankstown  Albury  Armidale  Ashfield  Batemans-Bay-Outreach       Bega  | Bathurst  Bidwill  | Bateau-Bay  Bradbury  Blackett  Airds  0.0

Aqui lo que hago es generar aleatoriamente 2 puntos de corte (minCutPoint y maxCutPoint), las ciudades entre esos 2 puntos serán los cromosomas que se insertaran en los hijos, después de eso checamos cada uno de los alelos para verificar que no esta repetido, en caso de que asi sea, remplazo la ciudad repetida por la primera ciudad no repetida del conjunto de cromosomas original del padre, lo que me asegura que siempre tendre caminos validos 🙂

Y por ultimo pero no menos importante la mutación, esta parte es bastante sencilla, genero 2 puntos aleatorios e intercambio los cromosomas de lugar, si el camino resultante es mas optimo que el original entonces el individuo evolucionara, de lo contrario se quedara igual.

Este procedimiento se realiza n generaciones, y al final esperamos tener el camino mas optimo que el viajero podría tomar.

Les dejo mi codigo fuente, espero le sirva a alguien

salu2

PD cualquier duda postearla en comentarios, gracias