sábado, 30 de abril de 2016

Importancia de los puertos y direcciones de multidifusión en la comunicación no fiable de grupos de procesos.


En redes de datos, se le conoce como comunicación no fiable, aquella que no proporciona mecanismos de aseguramiento de la entrega y recuperación de errores. Este tipo de comunicación se implementa en aplicaciones donde la reducción de la latencia tiene mayor impacto que la tasa de pérdidas, por ejemplo, en la transmisión de audio.

Por otra parte, la comunicación a nivel de procesos, puede adquirir la forma de unidifusión y multidifusión. En esta última, un proceso puede enviar un mensaje a varios receptores a la vez. Para ello, dichos receptores deben estar adheridos a un grupo.

A nivel de la capa de red del modelo TCP/IP, la multidifusión cuenta con sus propias direcciones, que en versión IPv4 se ubican dentro del rango 224-239. Mediante estas direcciones es posible identificar un grupo para comunicación entre sus miembros.

El objetivo del siguiente programa será verificar el papel de dos elementos que intervienen en este tipo de comunicación: El puerto y la dirección.  Para ello utilizaremos dos programas.

Fuente.java: Envía un mensaje a una dirección de multicast (grupo) en un puerto específico. Su funcionamiento se resume en los siguientes pasos:

- Obtener dirección multicast
- Generar mensaje en forma de datagrama UDP
- Enviar mensaje al grupo y puerto designado

Destino.java: Este código se ejecuta en forma de dos procesos que se adhieren a una dirección de multicast y por tanto, reciben el mensaje enviado por la fuente. Su funcionamiento se resume en los siguientes pasos:

- Obtener dirección multicast
- Unirse al grupo del multicast
- Leer mensaje en forma de datagrama UDP

Las acciones anteriormente descritas se han colocado en un ciclo infinito tanto en fuente.java como en destino.java de tal forma que los procesos destinos no terminen hasta que reciban un mensaje como miembros del mismo grupo multicast.

Fuente.java
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

/**
 *
 * @author Joaquin Bolaños
 *
 * Envía un mensaje a una dirección de multidifusión utilizando un puerto UDP
 * El tipo de comunicación es no fiable.
 *
 * Dirección multicast del grupo: 230.2.2.5
 * Puerto UDP (socket): 1234
 *
 */

public class Emisor {
    public static void main(String[] args) {
        MulticastSocket puerto; // Clase para el socket multicast
        InetAddress grupo; // Clase para el grupo
        System.out.println("EMISOR");
       
        try{
            while(true)
            {
                // Estableciendo el grupo con una dirección multicast
                // y asociando el puerto UDP al socket multicast.
                grupo = InetAddress.getByName("230.2.2.5");
                puerto = new MulticastSocket(1234);
               
                String mensaje = "Mensaje para el grupo";
                DatagramPacket paquete = new DatagramPacket(mensaje.getBytes(), mensaje.length(), grupo, 1234);
                puerto.send(paquete);
            }
            puerto.close(); // Cierra la conexión.               
        }
        catch(Exception ex)
        {
            System.out.println("" + ex.getMessage());
        }
    }       
}


Destino.java
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

/**
 *
 * @author Joaquin Bolaños
 *
 * Envía un mensaje a una dirección de multidifusión utilizando un puerto UDP
 * El tipo de comunicación es no fiable.
 *
 * Dirección multicast del grupo: 230.2.2.5
 * Puerto UDP (socket): 1234
 *
 */


public class Receptor {
    public static void main(String[] args) {
        MulticastSocket puerto;
        InetAddress grupo;
        System.out.println("RECEPTOR");
       
        try
        {           
            while(true)
            {
                // Estableciendo el grupo con una dirección multicast
                // Asociando el puerto UDP al socket multicast.
                // Finalmente se une al grupo con el método joinGroup
                grupo = InetAddress.getByName("230.2.2.5");
                puerto = new MulticastSocket(1234);
                puerto.joinGroup(grupo);
               
                // Buffer para guardar el mensaje que llega al grupo.
                byte[] almacen = new byte[100];
               
                if (almacen.length != 0) // Si ha llegado un mensaje nuevo
                {
                    // Crea datagrama UDP para el mensaje
                    DatagramPacket recibido = new DatagramPacket(almacen, almacen.length);
                   
                    //Lee el mensaje que le llega.
                    puerto.receive(recibido);
                   
                    // Lo muestra en pantalla
                    System.out.println(new String(almacen));
                   
                    break;
                }
            }
            puerto.close(); // Cierra la conexión
        }
        catch (Exception ex)
        {
            System.out.println("" + ex.getMessage());
        }               
    }
}

A continuación, se muestra la ejecución de un proceso fuente y dos procesos destino en los siguientes casos:

Caso 1: La dirección de multicast y el número de puerto coincide tanto en la fuente como en los destinos.

Resultado: Ambos procesos destino que pertenecen al mismo grupo reciben el mensaje

Emisor:

Proceso receptor 1:

Proceso receptor 2:


Caso 2: La dirección de multicast coincide tanto en la fuente como en los destinos; pero no el número de puerto.

Resultado: Aunque ambos procesos pertenecen al mismo grupo, el “buzón de entrada” no coincide, por lo que no leen el mensaje ni tampoco lo muestran.

Emisor:

Proceso receptor 1:
Proceso receptor 2:
 

Caso 3: El número de puerto coincide tanto en la fuente como en los destinos; pero no la dirección de multicast.

Resultado: Aunque ambos procesos leen del mismo “buzón” (puerto); pero no pertenecen al grupo al que se envía el mensaje; por lo que no lo leen y tampoco lo muestran.

Emisor:

Proceso receptor 1:
Proceso receptor 2:
 

Podemos comparar entonces a la dirección de multicast como una ciudad donde si el alcalde “emisor” envía un comunicado, dicho mensaje les compete a todos; pero para que lo lean, debe depositarlo en el buzón adecuado.


Concluimos por tanto que en la comunicación multicast no fiable tanto la dirección de multidifusión como el puerto son importantes para la comunicación. 


viernes, 29 de abril de 2016

Bubblesort con criterio de ordenamiento para arreglos bidimensionales (tablas)


El algoritmo de ordenamiento "bubblesort" se basa en un recorrido secuencial de los datos con intercambios simultáneos (swap) a partir de comparaciones. Para ello, utiliza una variable temporal para evitar que los datos se pierdan al momento del swap.

Para demostrar este algoritmo y analizar su eficiencia comúnmente se utiliza el ejemplo de un arreglo de números enteros de una dimensión. En el siguiente programa utilizaremos un arreglo de dos dimensiones. Nuestro objetivo será ver cómo se puede implementar este algoritmo para ordenar una tabla en base a una columna en específico. Dicha columna clave establecerá el orden de las filas y al momento de un swap se moverá no solo el dato que se compara, sino también toda la fila que depende de ese dato.


Si el arreglo está así:


Ordenado por la columna 1, de menor a mayor, queda así:



El programa está codificado en lenguaje Java:


Código:

import java.util.Random;
/**
 *
 * author Joaquin Bolaños
 *
 * Demostración de ordenamiento de un arreglo de dos dimensiones (tabla)
 * en base a una de sus columnas, utilizando el algoritmo bubblesort.
 *  * 
 */

public class BubleSort2D {   
    public static void main(String[] args) {
       
        int[][] arreglo = new int[10][2]; // La tabla tendra 10 filas y dos columnas
        int numero=0;
        Random aleatorio = new Random();
       
        // Generando datos para al tabla (enteros aleatorios):
        for (int i = 0; i<10 i="" o:p="">
        {
            for (int j=0; j<2 j="" o:p="">
            {
                numero = aleatorio.nextInt(10) + 1;
                arreglo[i][j] = numero;
            }
        }
       
        // Presentando el arreglo sin ordenar
        System.out.println("ARREGLO SIN ORDENAR:");
        for (int i = 0; i<10 i="" o:p="">
        {
            for (int j=0; j<2 j="" o:p="">
            {
                System.out.print("" + arreglo[i][j] + "-");               
            }
            System.out.println("");
        }
       
        // Ordenando el arreglo por la columna 1 utlizando bublesort:
        System.out.println("");
        System.out.println("ARREGLO ORDENADO POR LA COLUMNA 1:");
        int temporal1, temporal2;
        int menor = 0;

// Esta variable especifica en base a qué columna se va a ordenar el arreglo:
        int columnaBase = 0; 
       
        for (int i = 0; i<10 i="" o:p="">
        {
            menor = arreglo[i][columnaBase];
            for (int j = (i+1); j<10 j="" o:p="">
            {               
                if (arreglo[j][columnaBase] < menor)
                {                   
                    // Variables de almacenamiento temporal
                    // para evitar perder los datos al momento del swap:
                    temporal1 = arreglo[i][0];
                    temporal2 = arreglo[i][1];
                   
                    // Intercambios
                    arreglo[i][0] = arreglo[j][0];
                    arreglo[i][1] = arreglo[j][1];  
                    arreglo[j][0] = temporal1;
                    arreglo[j][1] = temporal2;
                    menor = arreglo[i][columnaBase];
                }
            }
        }
                                   
       
        // Presentando el arreglo ordenado por la columna 1
        for (int i = 0; i<10 i="" o:p="">
        {
            for (int j=0; j<2 j="" o:p="">
            {
                System.out.print("" + arreglo[i][j] + "-");               
            }
            System.out.println("");
        }                                     
    }   
}


Ejecución:



Del anterior código concluimos que al ejecutar el algoritmo bubblesort para ordenar un arreglo bidimensional (tabla) en base a una columna en específico:

- El número de intercambios a realizar no necesariamente es igual al número de filas de la tabla.

- El número de variables temporales a utilizar en este algoritmo será igual al número de columnas de la tabla.

- Aunque sólo se ordena en base a la columna clave, al momento de los intercambios se harán tantos swaps como columnas tenga la tabla.

jueves, 28 de abril de 2016

Java: Tabla de distancias euclideanas a punto de referencia en espacio n-dimensional

El siguiente código de Java genera una tabla de distancias en un espacio n-dimensional desde n puntos hacia un punto de referencia conocido. Esta técnica encuentra aplicación dentro de la generación de clústeres de datos donde se toma en cuenta la proximidad como criterio de agrupamiento.

Sean los puntos: A y B en un espacio n dimensional, las representaciones de cada punto se harán en base a sus coordenadas:

Para punto A: (a1, a2, a3, ... , an)
Para punto B: (b1, b2, b3, ..., bn)

La distancia entre los puntos A y B utilizando distancia euclideana:

D(A-B) = RAIZ_CUADRADA ( (a1 - b1)^2 + (a2 - b2)^2 + ... + (an - bn)^2 )

El programa es flexible en cuanto al número de dimensiones que tendrá el espacio y el número de puntos conocidos y está limitado a solo un punto de referencia.

Código:

import java.util.Scanner;

/**
 *
 * @author: Joaquín Bolaños
 * Genera una tabla de distancias desde un punto de referencia hacia puntos conocidos.
 * El número de dimensiones del espacio y el número de puntos conocidos se ajustan como
 * parámteros introducidos por el usuario.
 *
 * Para calcular las distancias se aplica la distancia de Euclides:
 * Sea puntoReferencia (x, y) un punto de referencia del espacio de dos dimensiones.
 * Sea puntoEspacio un punto del espacio conocido (a,b) del espacio de dos dimensiones.
 * La distancia entre puntoReferencia y puntoEspacio = raizcuadrada ((x-a)^2 + (y-b)^2)
 * Los parámetros del programa son:
 *
 * nDimensiones: Número de dimensiones del espacio (Dependiendo su valor, así será el número de coordenadas por *punto).
 * nPuntos: El número de puntos conocidos del espacio.
 *
 * Todas las distancias se calculan hacia un único punto de referencia, cuyas coordenadas
 * también introduce el usuario.
 *
 */

public class EuclidesDistancia {
    public static void main(String[] args) {      
        double coordenada = 0; // Almacena un valor de coordenada
        int nPuntos = 0;  // Número de puntos conocidos
        int nDimensiones = 0;  // Número de coordenadas por punto del espacio
        double sumaCuadrados = 0; // Acumulador de cuadrados para calcular distancia
        double distancia = 0; // Variable que guarda las distancias
     
        Scanner lector = new Scanner(System.in);
     
        // Introduciendo parámetros base
        System.out.print("¿De cuántas dimensiones es el espacio?: ");
        nDimensiones = lector.nextInt();
        System.out.print("Digite el número de puntos conocidos en el sistema de dos coordenadas:");
        nPuntos = lector.nextInt();
           
        // Generando las tablas en base a los parámetros base
     
        // tabla de puntos conocidos. En esta tabla también se guardan las distancias
        double[][] tabla = new double [nPuntos][nDimensiones+1];
     
        // coordenadas del punto de referencia
        double[][] referencia = new double [1][nDimensiones];
     
        // Captura de coordenadas del punto de referencia:
        System.out.println("CAPTURA DEL PUNTO DE REFERENCIA");
        for (int i=0; i        {
            System.out.print("Digite la coordenada " + (i + 1) + " del punto de referencia:");
            coordenada = lector.nextDouble();
            referencia[0][i] = coordenada;          
        }
        System.out.println("");
     
        // Captura de los puntos conocidos y de una sola vez se calcula y almacena la distancia respectiva:
        System.out.println("CAPTURA DE PUNTOS CONOCIDOS");
        for (int i=0; i        {
            for (int j=0; j            {              
                System.out.print("Digite la coordenada " + (j+1) + " del punto " + (i + 1) + ": ");
                coordenada = lector.nextDouble();
                sumaCuadrados = sumaCuadrados + (Math.pow((referencia[0][j] - coordenada),2));
                tabla[i][j] = coordenada;
            }
            distancia = Math.sqrt(sumaCuadrados);
            tabla[i][nDimensiones] = distancia;
            System.out.println("");        
            sumaCuadrados = 0;
        }
     
        // Se recorre y muestra el arreglo de los puntos conocidos junto con las distancias
        // respectivas de cada uno hacia el punto de referencia:
        System.out.println("");
        System.out.println("TABLA DE DISTANCIAS");
        System.out.println("Punto - CoordX - CoordY - Distancia");
        for (int i = 0; i        {
            System.out.print("" + (i+1));
            System.out.print(" - ");
            for (int j=0; j<=nDimensiones; j++)
            {
                System.out.print("" + tabla[i][j]);
                System.out.print(" - ");
            }
            System.out.println("");
        }
    }

}


Ejecución (para un espacio de tres dimensiones, con cuatro puntos conocidos):











lunes, 4 de abril de 2016

Comentario de libro: “La Revolución Positiva. Cinco Principios Básicos” (Edward de Bono)


La primera edición de este libro fue lanzada en 1994. El autor es un reconocido profesional en el campo de la psicología que ha desarrollado su producción en el área de la autogestión del pensamiento, del cual se han incluso generado cursos de adiestramiento orientados a esos fines.

Dentro de este bagaje de libros, el título que nos ocupa sale de este contexto enfocándose en una idea interesante: Plantear el desarrollo social a partir de las propias contribuciones como una “revolución” con todos los aspectos que por lo general se identifican con este término: revolucionarios, ideal, base filosófica, objetivo, metodología, propósito, ideario, símbolos, entre otros. El autor identifica la idea “tradicional” de revolución como negativa, a partir de que las mismas se enfocan más que todo en generar conflictos destructivos cuya finalidad es atacar a un rival específico representado por una entidad personal o ideológica (sistema de cosas). Se afirma que por tanto, el propósito de este tipo de revoluciones es limitado ya que al haber conseguido su objetivo (generalmente por la coerción), son incapaces de generar un desarrollo paulatino y consistente en la calidad de vida de los pueblos que experimentaron dichas revoluciones.  Cabe mencionar que dentro del contexto temporal de este libro hace apenas tres años antes la llamada históricamente “Guerra Fría” había concluido, lo cual sirvió al autor para evaluar el éxito o no de este tipo de revoluciones, sin tomar parte completamente por ninguna de ellas, ya que el propósito del texto es aportar ideas prácticas para una revolución que sin ser destructiva, propicie cambios que beneficien a todas las personas en un contexto personal, regional y mundial.

La revolución positiva que plantea Edward Bono carece de la figura de los rivales y se centra en cinco principios cuya finalidad es formar una conciencia de revolución colectiva que parta de la propia autoconciencia, de tal forma que el cambio general sucederá a partir de las contribuciones constantes y permanentes de cada uno de los individuos que hagan suyo el ideal del movimiento. En la revolución positiva tampoco existe la crítica ni la destrucción sino más bien el aporte y la construcción, dentro de un marco de respeto a todas las personas, que concilie las diferencias de personalidad, pensamiento, ideas propias, minimizando los conflictos y maximizando los logros. Estos cinco principios son los siguientes:

1. Efectividad: La efectividad es un principio indispensable, de tal forma que las acciones constructivas y las contribuciones siempre deberán ser efectivas. La efectividad implica proponerse un objetivo y cumplirlo. Esto no puede lograrse sin disciplina propia y sin un pensamiento adecuado que encauce las ideas de tal forma que se materialicen de la mejor manera posible.

2. Ser constructivo: A diferencia de las "revoluciones negativas", la revolución positiva se enfoca en aportar ideas y acciones (sobre todo estar últimas que edifiquen al crecimiento, superación y bienestar del entorno. Una importante consecuencia de esto es que la crítica destructiva y el conflicto dejan de tener relevancia como agente generador de cambios. La actitud constructiva también implica cambios en la percepción hacia los demás, siendo que el ventajismo y la competencia desleal se desvirtúan, estimulándose el sentido de pertenencia y de igualdad entre las personas.

3. Respeto: El respeto es el principio director de las relaciones para los revolucionarios positivos. El respeto implica sustituir la crítica por el aporte constructivo. El respeto es un principio óptimo para ser aplicado porque no depende de los sentimientos. Proporciona un marco dentro del cual las contribuciones pueden aceptarse y desarrollarse.

4. Autosuperación: Es la contribución que que realizan paraa sí mismos los revolucionarios positivos, la cual es importante para ampliar el espectro de sus contribuciones al entorno regional y mundial. Este aspecto tiene impacto sobre la forma como se plantea la misma cuestión educativa.

5. Contribución: La contribución es el resultado constante de la revolución positiva. Es decir, el objetivo de la misma es realizar contribuciones constantes que transformen el entorno personal, nacional y mundial. Todo participante de la revolución positiva debe buscar realizar contribuciones solo o trabajando en grupos.

El libro plantea además apartados interesantes como el papel de los actores sociales (juventud, gobierno, sector femenino, escuela, arte), el cambio de paradigma educativo (que hace recordar vagamente el enfoque por competencias), los medios de comunicación y lo que el autor llama (en una demostración de visión futurista), “la sociedad de la información”. Estos apartados plantean ideas que hoy en día podrían parecer obsoletas debido a los cambios sociales y de percepciones, aparte de la explosión de la conectividad mundial  y la globalización del conocimiento a través del Internet y las telecomunicaciones, aspectos que en el año de nacimiento de este libro, aún no tenían el alcance que hoy tienen.

Un breve apartado del libro se dedica a la descripción de la técnica de pensamiento de los “seis sombreros”. Se utilizará a continuación esta técnica para opinar brevemente las ideas anteriormente descritas:

Sombrero blanco: La revolución positiva es una forma de generar cambios positivos de impacto en el bienestar global a través de las contribuciones individuales.

Sombrero rojo: Estas ideas pueden originar un gran beneficio si se ponen en práctica; pero las ideas sobre conceptos como el amor, el papel de los sectores de la sociedad son discutibles. Prescinde por completo de la base religiosa como apoyo a sus ideas e incluso parece que la hiciera de lado.

Sombrero negro: Si no existe compromiso de la dirección y liderazgo, la revolución positiva puede convertirse en esfuerzos aislados con impacto limitado.

Sombrero amarillo: El compromiso que cada uno de las personas involucradas en este sistema adquiere elimina el egoísmo e impulsa el deseo de la propia superación a través de hacer bien a nuestro entorno utilizando los propios talentos naturales o adquiridos.

Sombrero verde: Para el mayor aprovechamiento del sistema se sugiere formarlo a consciencia grupal a través de ponerlo en práctica desde la educación básica e incluirlo en la agenda de formación y de difusión mediática. Aquí el papel de la educación mantiene un papel sumamente importante, lo cual no se logra en el corto plazo.

Sombrero azul: Se sugiere tomar en cuenta las ideas del sombrero rojo. Aunque el autor pretenda mantener una base laica, la comunidad creyente conoce que tras estas ideas “revolucionarias” existe ya una justificación religiosa importante que no se puede ignorar partiendo de la visión tridimensional del ser humano (cuerpo, mente y espíritu). Cabría preguntarse, ¿qué es el ser humano para la revolución positiva? (Recordemos que las revoluciones “tradicionales” también tienen su propia visión de lo que es el ser humano).
 
Conclusión:
El libro de Edward Bono plantea una forma diferente de plantear lo que hoy conocemos como “proactividad” y la idea de que el bienestar global depende de las acciones individuales. Estas ideas se han mantenido hasta el día de hoy y no necesariamente bajo la forma de una revolución visiblemente organizada. El planteamiento del texto se enfrenta al reto de trascender la práctica de sus ideas desde el enfoque autosuficiente, individual, personal o solitario a implementarlo como un colectivo. Dado que el ser humano es de naturaleza gregaria, la materialización de una revolución de este tipo implicaría siempre la existencia de un liderazgo apoyado por una entidad multiplicadora y gestora (como los medios de información y el estado mismo). Sin embargo, a baja escala (como en una compañía o en una pequeña familia o comunidad, las ideas de este libro pueden ser aplicables de una forma más sencilla con un proceso de concientización previa o como valores empresariales y lo más importante, cada persona bajo su propia decisión puede contribuir a su desarrollo personal, familiar y comunitario simplemente decidiéndose a orientar su propia vida bajo el sentido de la contribución de las ideas que plantea este libro cuyo espíritu ya habían planteado desde otra perspectiva los enfoques religiosos y morales (como el cristianismo, el budismo y el confucionismo), siglos atrás y que se mantienen hasta nuestros días.

Seguidores