domingo, 31 de enero de 2016

Clases y Objetos en JAVA



La programación orientada a objetos se enfoca en los elementos de un sistema, sus atributos y las interacciones que se producen entre ellos para diseñar aplicaciones informáticas. Los elementos abstractos del modelo orientado a objetos se denominan clases. 

Un programa orientado a objetos es, esencialmente, una colección de objetos que se crean, interaccionan entre sí y dejan de existir cuando ya no son útiles durante la ejecución de un programa. Una aplicación informática puede llegar a ser muy compleja. La complejidad es más manejable cuando se descompone y se organiza en partes pequeñas y simples, los objetos.

Un programa Java utiliza clases y objetos. Las clases representan un esquema simplificado de la casuística de una aplicación informática. Una clase es una representación abstracta de un conjunto de objetos que comparten los mismos atributos y comportamiento, es decir, una clase describe un tipo de objetos. Un objeto es una instancia de una clase, tiene una identidad propia y un estado. La identidad de un objeto se define por su identificador. El estado de un objeto se define por el valor de sus atributos.
El comportamiento de un objeto queda determinado por el comportamiento la clase a la que pertenece. Los objetos son unidades indivisibles y disponen de mecanismos de interacción llamados métodos.

Para entender el concepto de objeto es necesario saber que existe una relación directa entre los elementos que forman parte de una aplicación informática y los objetos. Normalmente, para identificar los elementos de una aplicación, debemos fijarnos en los sustantivos que utilizamos para describir los objetos reales del sistema. Para diseñar una aplicación orientada a objetos es necesario responder las siguientes preguntas:
  • ¿Cuáles son los elementos tangibles de un sistema?
  • ¿Cuáles son sus atributos?
  • ¿Cuáles son sus responsabilidades?
  • ¿Cómo se relacionan los elementos del sistema?
  • ¿Qué objeto debe “saber”...?
  • ¿Qué objeto debe “hacer”...?

Por ejemplo, si se desea diseñar un programa Java para gestionar las ventas de una tienda, entonces habría que identificar y describir las características elementos como: cliente, tipo de cliente, producto, pedido, tipo de entrega, forma de pago, unidades en existencia de los productos, etc. Los procesos de gestión de la tienda incluirían el registro de los clientes, el registro de los productos de la tienda, el proceso de compra del cliente y la realización de los pedidos, la entrada y salida de productos del almacén, etc.

Si en vez de una tienda se trata de una aplicación para dibujar figuras geométricas en dos dimensiones, entonces sería necesario identificar y describir las características de las figuras y su posición. En este caso habría figuras de tipo círculo, rectángulo, triángulo, etc. Las operaciones a realizar con las figuras incluirían dibujar, borrar, mover o rotar.


Clases

En su forma más simple, una clase se define por la palabra reservada class seguida del nombre de la clase. El nombre de la clase debe empezar por mayúscula. Si el nombre es compuesto, entonces cada palabra debe empezar por mayúscula. Circulo, Rectangulo, Triangulo y FiguraGeometrica son nombres válidos de clases.

Por ejemplo, la clase Circulo se define con tres atributos: el radio y las coordenadas x, y que definen la posición del centro del círculo.

/* Esta clase define los atributos de un círculo */
public class Circulo {
int x;
int y;
int radio;
}

Una vez que se ha declarado una clase, se pueden crear objetos a partir de ella. A la creación de un objeto se le denomina instanciación. Es por esto que se dice que un objeto es una instancia de una clase y el término instancia y objeto se utilizan indistintamente.

Para crear objetos, basta con declarar una variable de alguno de los tipos de figuras geométricas:

Circulo circulo1;
Circulo circulo2;

Para crear el objeto y asignar un espacio de memoria es necesario realizar la instanciación con el operador new.

circulo1 = new Circulo();
circulo2 = new Circulo();

Después de crear los objetos, circulo1 y circulo2 almacenan los valores predeterminados de la clase Circulo. A partir de este momento los objetos ya pueden ser referenciados por su nombre. Los nombres circulo1 y circulo2 son las referencias válidas para utilizar ambos objetos.



Espero haber ayudado en algo. Hasta la próxima oportunidad!

DESCARGAR PUBLICACIÓN










  

sábado, 30 de enero de 2016

Los elementos de un programa Java - 3 de 3



Expresiones

Una expresión permite realizar operaciones entre valores utilizando distintos operadores. Las expresiones son útiles para representar las fórmulas matemáticas que se utilizan para realizar cálculos.

En Java se pueden definir expresiones tan complejas como sea necesario. 
Por ejemplo, para convertir una temperatura de grados Fahrenheit a Centígrados se utiliza la fórmula:

C = ((F – 32) * 5) / 9

En este ejemplo C representa la temperatura en grados centígrados y F en grados Fahrenheit. La fórmula en Java, utilizando las variables centigrados y fahrenheit de tipo double.

centigrados = ((fahrenheit – 32.0) * 5.0)) / 9.0;

Toda la expresión se evalúa a un valor. El orden de los cálculos depende del orden de prioridad de los operadores: primero los operadores unarios, después los multiplicativos, de izquierda a derecha, después los operadores aditivos, de izquierda a derecha, después los operadores de relación y por último los operadores de asignación.

Por ejemplo, la expresión x = -3 + 2 * 4 – 12 / 6 + 5 se calcula en el orden siguiente:

Primero se aplica el operador unario (-) a 3 y se obtiene -3. A continuación se evalúan los operadores multiplicativos de izquierda a derecha. Se calcula el producto de 2 * 4 y se obtiene 8, después se divide 12 / 6 y se obtiene 2. 
Al finalizar estas operaciones la expresión queda x = -3 + 8 – 2 + 5. Por último, se evalúan los operadores aditivos de izquierda a derecha y se obtiene 8.

Cuando se desea modificar el orden de prioridad de los operadores es necesario utilizar paréntesis para indicar el orden de evaluación. Por ejemplo, al calcular el valor de y = -3 + 2 * (14 – 2) / 6 + 5 se obtiene 6.


Expresiones aritmético-lógicas

Una expresión aritmético-lógica devuelve un valor lógico verdadero o falso. 
En este tipo de expresiones se utilizan operadores aritméticos, operadores relacionales y de igualdad. Por ejemplo, una expresión lógica puede ser:

(10 – 2) > (5 – 3)

En este ejemplo la expresión aritmético-lógica es verdadera porque el lado derecho de la expresión es mayor que el lado izquierdo.

En una expresión aritmético-lógica se pueden combinar varias expresiones con operadores lógicos. La precedecencia de los operadores lógicos es menor que la de los operadores relacionales, por lo que primero se evalúan las desigualdades y después los operadores lógicos. El orden de prioridad de los operadores lógicos es el siguiente: primero la negación, después el Y lógico y por último el O lógico. La prioridad de los operadores de asignación es la menor de todas.

Por ejemplo, la expresión 3 + 5 < 5 * 2 || 3 > 8 && 7 > 6 – 2 se evalúa en el orden siguiente.

Primero se evalúan las expresiones aritméticas y se obtiene la expresión lógica 8 < 10 || 3 > 8 && 7 > 4. A continuación se evalúan los operadores relacionales y se obtiene true || false && true. Ahora se evalúa el operador Y lógico con los operandos false && true y se obtiene false.
Por último, se evalúa el operador O lógico con los operandos true || false y se obtiene true, el valor final de la expresión.

Los operadores lógicos && y || se evalúan por cortocircuito. Esto significa que al evaluar a && b, si a es falso, no es necesario evaluar b porque la expresión es falsa. De forma similar, al evaluar a || b, si a es verdadero, no es necesario evaluar b porque la expresión es verdadera.


Conversión de tipos

Muchas veces es necesario realizar conversiones de tipos cuando se evalúa una expresión aritmética. Por ejemplo, si después de realizar el cálculo de conversión de grados Fahrenheit a Centígrados se quiere almacenar el resultado en la variable de tipo entero temperatura, es necesario hacer una conversión de tipos. La fórmula en Java, utilizando las variables centigrados y fahrenheit de tipo double.

centigrados = ((fahrenheit – 32.0) * 5.0)) / 9.0;

Antes de asignar el valor resultante a la variable temperatura, que almacena un valor entero, es necesario convertir el valor de tipo double de la variable centigrados a int.

int temperatura = (int) centigrados;


Las palabras reservadas de Java

En todos los lenguajes de programación existen palabras con un significado especial. Estas palabras son reservadas y no se pueden utilizar como nombres de variables.


En realidad, las palabras false, null y true son literales. No son palabras reservadas del lenguaje, pero no se pueden utilizar como identificadores.


Espero haber ayudado en algo. Hasta la próxima oportunidad!

DESCARGAR PUBLICACIÓN










  

viernes, 29 de enero de 2016

Los elementos de un programa Java - 2 de 3



Tipos primitivos

Las variables de java pueden ser de un tipo primitivo de datos o una referencia a un objeto. Los tipos primitivos permiten representar valores básicos. Estos tipos se clasifican en números enteros, números reales, caracteres y valores booleanos.

Números enteros. Representan números enteros positivos y negativos con distintos rangos de valores, desde cientos a trillones. Los tipos enteros de Java son byte, int, short y long.

Números reales. Existen dos tipos de números reales en Java, float y double. La diferencia entre ellos está en el número de decimales que tienen capacidad para expresar y en sus rangos de valores. 

Caracteres. El tipo char permite representar cualquier carácter Unicode. 
Los caracteres Unicode contienen todos los caracteres del alfabeto de la lengua castellana.

Booleano. Se utiliza para representar los valores lógicos verdadero y falso.Solo tiene dos valores true y false.

La siguiente tabla resume los tipos primitivos de Java.



Literales

Se denomina literal a la manera en que se escriben los valores para cada uno de los tipos primitivos.

Números enteros. Un número entero en Java se puede escribir en decimal, octal o en hexadecimal. Cuando se utiliza el sistema octal es necesario poner el dígito 0 delante del número. Si se utiliza el sistema hexadecimal se debe poner 0x delante del número. Por ejemplo, el número decimal 10 se puede escribir 012 en octal y 0xA en hexadecimal. Los números enteros se supone que pertenecen al tipo int.

Números reales. Un número real en Java siempre debe tener un punto decimal o un exponente. Por ejemplo, el número 0.25 se puede expresar también como 2.5e-1. Los números reales se supone que pertenecen al tipo double.

Booleanos. Los valores lógicos solo pueden ser true y false. Se escriben siempre en minúsculas.

Caracteres. Los valores de tipo carácter representan un carácter Unicode.

Se escriben siempre entre comillas simples, por ejemplo 'a', 'A', '0', '9'. En Java un carácter se puede expresar por su código de la tabla Unicode en octal o en hexadecimal. Los caracteres que tienen una representación especial se indican en la siguiente tabla.


Textos. Un texto en Java pertenece a la clase String y se expresa como el texto entre comillas dobles. Un texto siempre debe aparecer en una sola línea. Para dividir un texto en varias líneas se debe utilizar el operador + para concatenar textos.

Un texto puede estar vacío o contener uno o más caracteres. Por ejemplo, “Hola Mundo” es un texto de 10 caracteres, mientras que “” es un texto vacío y tiene 0 caracteres. El texto “a” es diferente del carácter 'a' de tipo char.


Operadores

Cada tipo puede utilizar determinados operadores para realizar operaciones o cálculos.

Números enteros. Al realizar una operación entre dos números enteros, el resultado siempre es un número entero. Con los números enteros se pueden realizar operaciones unarias, aditivas, multiplicativas, de incremento y decremento, relacionales, de igualdad y de asignación.
  • Una operación unaria permite poner un signo delante: +5, -2.
  • Una operación aditiva se refiere a la suma y la resta: 2+3, 5-2.
  • Una operación multiplicativa multiplica o divide dos valores: 5*2, 5/2. El operador % calcula el resto de la división entera 5%2.
  • Un incremento o decremento aumenta o decrementa en 1 el valor de una variable: ++numero, numero++, --numero, numero--. Si el operador va antes de la variable, primero se realiza la operación y se modifica el valor de la variable. Si el operador va después de la variable, su valor se modifica al final.
  • Un operador relacional permiten comparar dos valores: >, <, >= y <=. 
  • El resultado de la comparación es un valor booleano que indica si la relación es verdadera o falsa.
  • Un operador de igualdad compara si dos valores son iguales o no. El operador == devuelve verdadero si los dos valores son iguales, el operador != devuelve verdadero si son diferentes. El resultado de la comparación es un valor booleano que indica si la igualdad o desigualdad es verdadera o falsa.
  • Un operador de asignación permite asignar un valor o el resultado de una operación a una variable: =, +=, -=, *=, /=, %=.

Números reales. Con los números reales se aplican los mismos operadores que con los números enteros. Si se realizan operaciones unarias, aditivas o multiplicativas, el resultado es un número real. También se pueden aplicar los operadores relacionales para comparar dos números reales.

Booleanos. Los operadores que se aplican a los valores lógicos son: negación, Y lógico, O lógico.
  • La negación (!) devuelve true si el operando es false.
  • El Y lógico (&&) devuelve false si uno de los operandos es false.
  • El O lógico (||) devuelve true si uno de los operandos es true.



Espero haber ayudado en algo. Hasta la próxima oportunidad!










  

jueves, 28 de enero de 2016

Los elementos de un programa Java - 1 de 3



A continuación se describe la definición léxica y sintáctica de los elementos de un programa Java: comentarios, identificadores, variables y valores, tipos primitivos, literales, operadores, expresiones y expresiones aritméticológicas.

Comentarios

En un programa Java hay tres tipos de comentarios. 

Comentario de bloque. Empieza por /* y termina por */. El compilador ignora todo el texto contenido dentro del comentario.

/*
* El programa HolaMundo se utiliza para aplicar los
* métodos System.out.print() y System.out.println()
*/

Comentario de documentación. Empieza por /** y termina por */. Java dispone de la herramienta javadoc para documentar automáticamente los programas. En un comentario de documentación normalmente se indica el autor y la versión del software.

/**
* Programa HolaMundo
* @author Fundamentos de Informática
* @version 1.0
* @see Referencias
*/

Comentario de línea. Empieza con //. El comentario comienza con estos caracteres y termina al final de la línea.

// El método System.out.println() salta la línea

El uso de comentarios hace más claro y legible un programa. En los comentarios se debe decir qué se hace, para qué y cuál es el fin de nuestro programa. Conviene utilizar comentarios siempre que merezca la pena hacer una aclaración sobre el programa.


Identificadores

El programador tiene libertad para elegir el nombre de las variables, los métodos y de otros elementos de un programa. Existen reglas muy estrictas sobre los nombres que se utilizan como identificadores de clases, de variables o de métodos.

Todo identificador debe empezar con una letra que puede estar seguida de más letras o dígitos. Una letra es cualquier símbolo del alfabeto y el carácter ‘_’. Un dígito es cualquier carácter entre ‘0’ y ‘9’. 
Los identificadores Hola, hola, numero, numeroPar, numeroImpar, numero_impar, numero_par, nombre, apellido1 y apellido2 son válidos. El identificador 1numero no es válido porque empieza con un dígito, no con una letra.

Cualquier identificador que empiece con una letra seguida de más letras o dígitos es válido siempre que no forme parte de las palabras reservadas del lenguaje Java. El lenguaje Java distingue entre letras mayúsculas y minúsculas, esto significa que los identificadores numeroPar y numeropar son distintos.

Existen unas normas básicas para los identificadores que se deben respetar.

  • Los nombres de variables y métodos empiezan con minúsculas. Si se trata de un nombre compuesto cada palabra debe empezar con mayúscula y no se debe utilizar el guión bajo para separar las palabras. Por ejemplo, los identificadores calcularSueldo, setNombre o getNombre son válidos.
  • Los nombres de clases empiezan siempre con mayúsculas. En los nombres compuestos, cada palabra comienza con mayúscula y no se debe utilizar el guión bajo para separar las palabras. Por ejemplo, HolaMundo, PerimetroCircunferencia, Alumno o Profesor son nombres válidos.
  • Los nombres de constantes se escriben en mayúsculas. Para nombres compuestos se utiliza el guión bajo para separar las palabras. Por ejemplo, PI, MINIMO, MAXIMO o TOTAL_ELEMENTOS son nombres válidos.


Variables y valores

Un programa Java utiliza variables para almacenar valores, realizar cálculos, modificar los valores almacenados, mostrarlos por la consola, almacenarlos en disco, enviarlos por la red, etc. Una variable almacena un único valor.

Una variable se define por un nombre, un tipo y el rango de valores que puede almacenar.

El nombre de una variable permite hacer referencia a ella. Este nombre debe cumplir las reglas aplicables a los identificadores. El tipo indica el formato de los valores que puede almacenar la variable: cadenas de caracteres, valores lógicos, números enteros, números reales o tipos de datos complejos. El rango indica los valores que puede tomar la variable.

Por ejemplo, una variable de tipo número entero, con nombre mesNacimiento puede almacenar valores positivos y negativos, lo que no tiene sentido cuando se trata de meses del año. El rango válido para esta variable sería de 1 a 12.

Para declarar una variable en Java se indica el tipo y su nombre. 

int mesNacimiento;

En este ejemplo se indica que la variable es de tipo entero (int) y su nombre es mesNacimiento. Una vez declarada una variable, se puede utilizar en cualquier parte del programa referenciándola por su nombre. 
Para almacenar un valor en una variable se utiliza el operador de asignación y a continuación se indica el valor, por ejemplo 2.

mesNacimiento = 2;

A partir de este momento la variable mesNacimiento almacena el valor 2 y cualquier referencia a ella utiliza este valor. Por ejemplo, si se imprime el valor de la variable por la consola, muestra el valor 2.

System.out.print(mesNacimiento);

Java permite declarar e inicializar una variable en una sola sentencia.

int diaNacimiento = 20;
int mesNacimiento = 3;

En este ejemplo se declaran las variables diaNacimiento con el valor 20 y mesNacimiento con valor 3.

Si se declara una constante, entonces se debe utilizar el delimitador final y es necesario indicar su valor. En la siguiente declaración se define el valor de la constante pi de tipo double para almacenar un número real.

final double PI = 3.1415926536;

Es conveniente utilizar nombres apropiados para las variables. El nombre de una variable debe indicar para qué sirve. El nombre de una variable debe explicarse por sí mismo para mejorar la legibilidad del programa.

Si se desea declarar más de una variable a la vez se deben separar las variables en la sentencia de la declaración.

int dia=20, mes=2, año=2020;

En este ejemplo se declaran las variables enteras dia, mes y año. La variable día se inicializa con el valor 20, mes con 2 y año con 2020. La siguiente declaración es equivalente a la anterior.

int dia=20;
int mes=2;
int año=2020;



Espero haber ayudado en algo. Hasta la próxima oportunidad!










  

miércoles, 27 de enero de 2016

System Center 2012 : Revisión Técnica - MVA - Microsoft Virtual Academy



Nota:
  • La solución de las siguientes preguntas pueden ayudarte a aprobar el módulo, siempre y cuando sean las mismas que me mostraron.
  • Dos asteriscos (**) significa Alternativa Correcta.
  • Alternativas sin marcar significa que me equivoque en la respuesta, por consiguiente depende únicamente de tu conocimiento. Si logras identificar la alternativa correcta compártela en este Sitio Web y si te tocan nuevas preguntas también. Gracias!

Aporte: Humberto Peña

1. ¿Cuáles son las ediciones que el nuevo Sistema Centro producto está disponible en 2012? (Seleccione todas las que apliquen)

**Datacenter
**Estándar
Prima
Empresa


2. ¿Qué componente de System Center 2012 ofrece el catálogo de servicios a los usuarios finales?

**Service Manager
Virtual Machine Manager
App Controller
Orchestrator


3. ¿La virtualización común permite que usted haga cuál de los siguientes?

**Entregar la portabilidad de aplicaciones a través de las nubes privadas y públicas.


4. ¿De qué manera Microsoft proporciona una base para la TI híbrida? (Seleccione todas las que apliquen)

Mediante el uso de las capacidades de administración de System Center.
**Con la nube privada de uso general del sistema operativo, Windows Server.
**Al permitir el consumo de la TI con Windows 7. 
A través de su plataforma de nube pública, Windows Azure.


5. ¿Cuáles son las capacidades necesarias para ofrecer TI como un servicio? (Seleccione todas las que apliquen)

**Prestación de servicios y automatización.
**Auto-servicio.


Otras Preguntas

1. ¿Con Operations Manager, System Center 2012 ofrece varias plataformas de vigilancia de los sistemas operativos invitados? (Seleccione todas las que apliquen)

**Linux (Según el aporte de Anónimo)
**Unix (Según el aporte de Anónimo)
IBM z / OS
**Sun Solaris (Según el aporte de Anónimo)


2. ¿Cuáles son los conceptos que están impulsando la computación en nube privada? (Seleccione todas las que apliquen)

Rendimiento
**Agilidad (Según el aporte de Anónimo)
**Ciencias económicas (Según el aporte de Anónimo)
**Enfoque (Según el aporte de Anónimo)


3. ¿Qué capacidad proporciona el componente de Virtual Machine Manager de System Center 2012? (Seleccione todas las que apliquen)

Gestione multiplataforma de configuración para servidores Linux y Unix.
Agrupa y abstrae sus recursos del centro de datos (tales como computación, red y almacenamiento) en una infraestructura de nube privada.
Integrar y ampliar sus conjuntos de herramientas existentes y crear flujos de trabajo flexibles (o runbooks) que se extienden a través de múltiples silos organizacionales y sistemas.
Asignar y delegar esta tela agrupada para su unidad de negocios de las organizaciones de TI de manera flexible, pero controlada, de forma.


4. ¿Qué es la automatización de procesos y el motor de integración de System Center 2012?

Configuration Manager
Service Manager
**Orchestrator (Según el aporte de Anónimo)
Virtual Machine Manager


5. ¿Cuáles son algunas de las tecnologías comunes que se utilizan para las TI híbridas? (Seleccione todas las que apliquen)
**Manejo (Según el aporte de Anónimo)
**Virtualización (Según el aporte de Anónimo)
**Identidad (Según el aporte de Anónimo)
Flujo de trabajo


6. ¿Cuál de estos componentes en System Center 2012 ayudará a hacer frente de manera más eficiente con la implementación y configuración de los recursos que le ayudan a ofrecer TI como un servicio? (Seleccione todas las que apliquen)

**Virtual Machine Manager (Según el aporte de Anónimo)
Resource Manager
App-V
**Configuration Manager (Según el aporte de Anónimo)


Espero haber ayudado en algo. Hasta la próxima oportunidad!








  

martes, 26 de enero de 2016

JAVA - Sentencias Básicas (Condicionales, Aritmeticas y Contadores) - 2 de 3

4. Dado un número entero que se introduce por teclado, determinar si es negativo o superior a 100.

EXPLICACION DEL PROGRAMA: el programa en principio define la clase aa4 que contiene la función principal main. Primero se lee un numero, que es introducido por teclado y se hacen comparaciones para verificar si es negativo, mayor a 100 o en el intervalo 0-100. Finalmente se despliega por pantalla la condición de dicho numero.

//Programa realizado por Freddy Valda
import java.io.*;
public class aa4
{
public static void main(String args[])throws IOException
{BufferedReader in;
in=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Introduzca un numero");
int a=Integer.parseInt(in.readLine());
if(a<0)
System.out.println("El numero es negativo");
else
if (a>100)
System.out.println("El numero es mayor a 100");
else
System.out.println("El numero esta en el intervalo de 0 a 100");
}}


5. Dado un número que se introduce por teclado, si es positivo verificar si se encuentra en el intervalo abierto 60 – 90, de lo contrario emitir un mensaje de error.

EXPLICACION DEL PROGRAMA: Este programa verifica si un numero ingresado por el teclado es positivo y si se encuentra en un intervalo predeterminado utilizando sentencias if.

//Programa realizado por Freddy Valda
import java.io.*;
public class a5
{
public static void main(String args[])throws IOException
{BufferedReader in;
in=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Introduzca un numero");
int a=Integer.parseInt(in.readLine());
if(a<61)
System.out.println("ERROR");
else
if (a>89)
System.out.println("ERROR");
else
System.out.println("El numero esta en el intervalo abierto 60-90");
}
}


6. Una fuente de datos registra varias edades, la edad 0 indica el final del ingreso de datos, realice un programa para determinar el promedio de las edades ingresadas y además el porcentaje de personas mayores a los 50 años.

EXPLICACIÓN DEL PROGRAMA: Este programa nos permite registrar varias edades con la información que una ves ingresada la edad 0 esta nos indica el final del ingreso de edades, calculando le promedio de las edades y además el porcentaje de edades mayores a los 50 años.

// Programa realizado por Sergio W. Ossio Marin
import java.io.*;
public class B_1
{
public static void main (String args []) throws IOException
{
BufferedReader in;
in = new BufferedReader (new InputStreamReader (System.in));
double m = 1, aux = 0, n = 0, o = 0;
System.out.println ("La edad 0 indica el final de ingreso de edades");
while (m != 0)
{
System.out.print ("Ingrese una edad ");
m = Integer.parseInt (in.readLine ());
n++;
aux = aux + m;
if (m > 50)
{
o++;
}
}
double s = (o * 100) / (n - 1);
double aux2 = aux / (n - 1);
System.out.println ("El promedio es " + aux2 );
System.out.println ("El porcentaje de personas mayores a los 50 a*os es de: " + s );}}


Espero haber ayudado en algo. Hasta la próxima oportunidad!








  

lunes, 25 de enero de 2016

JAVA - Sentencias Básicas (Condicionales, Aritmeticas y Contadores) - 1 de 3

En los siguientes ejercicios, se utilizan las sentencias condicionales if- else, además de sentencias aritméticas como % (modulo), comparativas (<,>,==,etc) y tambien se hace uso de contadores y sentinelas.

1. Dado un número entero y positivo que se introduce por teclado, determinar si es par o impar.

EXPLICACION DEL PROGRAMA: Este programa lee un numero introducido por teclado y verifica si el numero es par o impar, verificando si el modulo del numero entre 2 es 0 o no.

//programa realizado por Freddy Valda Sanchez
import java.io.*;
public class a1
{
public static void main(String args[])throws IOException
{BufferedReader in;
in=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Introduzca un numero entero y positivo");
int a=Integer.parseInt(in.readLine());
if(a%2==0)
System.out.println("El numero es par");
else
System.out.println("El numero es impar");
}
}

2. Dado un número entero que se introduce por teclado, determinar si es positivo, negativo o nulo.

EXPLICACION DEL PROGRAMA: El usuario ingresa un numero entero y el programa determina si es positivo, negativo o cero(nulo). Utiliza simples comparaciones y sale el mensaje correspondiente.

//Programa realizado por Andrés Prudencio R.
import java.io.*;
public class a2
{
public static void main (String args[])throws IOException
{
BufferedReader in;
in = new BufferedReader (new InputStreamReader (System.in));
System.out.println("Ingrese un numero entero: ");
int d = Integer.parseInt(in.readLine());
if (d==0)
System.out.print(" el numero es nulo ");
else
{if (d<0)
System.out.print("El numero es negativo");
else
System.out.print("El numero es positivo");}
}}

3. Dado un número entero que se introduce por teclado, determinar si se encuentra en el intervalo cerrado 51 - 100.

EXPLICACIÓN DEL PROGRAMA: Este programa nos permite Verificar que un número ingresado por teclado se encuentre en el intervalo cerrado [51,100]

// Programa realizado por Sergio W. Ossio Marin
import java.io.*;
public class A_3
{
public static void main (String args[])throws IOException
{
BufferedReader in;
in = new BufferedReader (new InputStreamReader (System.in));
int n;
System.out.println("Ingrese el numero a verificar: ");
n = Integer.parseInt(in.readLine());
if(n>=51&n<=100)
System.out.println("El numero se encuentra en el intervalo cerrado [51-100]");
else
System.out.println("El numero no se encuentra en el intervalo cerrado [51-100]");
}}



Espero haber ayudado en algo. Hasta la próxima oportunidad!








  

domingo, 24 de enero de 2016

Dibujar gráficos en HTML - 3 de 3



  • Sombras
Por supuesto, sombras son también una parte importante de Canvas API. Podemos generar sombras para cada trazado e incluso textos. La API provee cuatro propiedades para hacerlo:
  • shadowColor :Esta propiedad declara el color de la sombra usando sintaxis CSS.
  • shadowOffsetX :Esta propiedad recibe un número para determinar qué tan lejos la sombra estará ubicada del objeto (dirección horizontal).
  • shadowOffsetY :Esta propiedad recibe un número para determinar qué tan lejos la sombra estará ubicada del objeto (dirección vertical).
  • shadowBlur :Esta propiedad produce un efecto de difuminación para la sombra.


Código 7-17. Aplicando sombras.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
lienzo.shadowColor="rgba(0,0,0,0.5)";
lienzo.shadowOffsetX=4;
lienzo.shadowOffsetY=4;
lienzo.shadowBlur=5;
lienzo.font="bold 50px verdana, sans-serif";
lienzo.fillText("Mi mensaje ", 100,100);
}
window.addEventListener("load", iniciar, false);

La sombra creada en el Código 7-17 usa la función rgba() para obtener un color negro semitransparente. Es desplazada 4 pixeles del objeto y tiene un valor de difuminación de 5.
Hágalo usted mismo: Aplique sombras a otra figura en lugar de texto. Por ejemplo, pruebe generar sombras para figuras vacías y sólidas, usando rectángulos o círculos.

  • Transformaciones

LA API Canvas ofrece operaciones complejas que es posible aplicar sobre el lienzo para afectar los gráficos que luego son dibujados en él. Estas operaciones son realizadas utilizando cinco métodos de transformación diferentes, cada uno para un propósito específico. 
  • translate(x, y) :Este método de transformación es usado para mover el origen del lienzo. Cada lienzo comienza en el punto 0,0 localizado en la esquina superior izquierda, y los valores se incrementan en cualquier dirección dentro del lienzo. Valores negativos caen fuera del lienzo. A veces es bueno poder usar valores negativos para crear figuras complejas. El método translate() nos permite mover el punto 0,0 a una posición específica para usar el origen como referencia para nuestros dibujos o para aplicar otras transformaciones.
  • rotate(ángulo) :Este método de transformación rotará el lienzo alrededor del origen tantos ángulos como sean especificados.
  • scale(x, y) :Este método de transformación incrementa o disminuye las unidades de la grilla para reducir o ampliar todo lo que esté dibujado en el lienzo. La escala puede ser cambiada independientemente para el valor horizontal o vertical usando los atributos x e y. Los valores pueden ser negativos, produciendo un efecto de espejo. Por defecto los valores son iguales a 1.0.
  • transform(m1, m2, m3, m4, dx, dy) :El lienzo contiene una matriz de valores que especifican sus propiedades. El método transform() aplica una nueva matriz sobre la actual para modificar el lienzo.
  • setTransform(m1, m2, m3, m4, dx, dy) :Este método reinicializa la actual matriz de transformación y establece una nueva desde los valores provistos en sus atributos.


Código 7-18. Moviendo, rotando y escalando.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
lienzo.font="bold 20px verdana, sans-serif";
lienzo.fillText("PRUEBA",50,20);
lienzo.translate(50,70);
lienzo.rotate(Math.PI/180*45);
lienzo.fillText("PRUEBA",0,0);
lienzo.rotate(-Math.PI/180*45);
lienzo.translate(0,100);
lienzo.scale(2,2);
lienzo.fillText("PRUEBA",0,0);
}
window.addEventListener("load", iniciar, false);

No hay mejor forma de entender cómo funcionan las transformaciones que usarlas en nuestro código. En el Código 7-18, aplicamos los métodos translate(), rotate() y scale() al mismo texto. Primero dibujamos un texto en el lienzo con la configuración por defecto. El texto aparecerá en la posición 50,20 con un tamaño de 20 pixeles. Luego de esto, usando translate(), el origen del lienzo es movido a la posición 50,70 y el lienzo completo es rotado 45 grados con el método rotate(). Otro texto es dibujado en el nuevo origen, con una inclinación de 45 grados. Las transformaciones aplicadas se vuelven los valores por defecto, por lo tanto antes de aplicar el siguiente método scale() rotamos el lienzo 45 grados negativos para ubicarlo en su posición original. Realizamos una transformación más moviendo el origen otros 100 pixeles hacia abajo. Finalmente, la escala del lienzo es duplicada y un nuevo texto es dibujado al doble del tamaño de los anteriores.
Cada transformación es acumulativa. Si realizamos dos transformaciones usando scale(), por ejemplo, el segundo método realizará el escalado considerando el estado actual del lienzo. Una orden scale(2,2) luego de otra scale(2,2) cuadruplicará la escala del lienzo. Y para los métodos de transformación de la matriz, esta no es una excepción. Es por esto que contamos con dos métodos para realizar esta clase de transformaciones: transform() y setTransform().

Código 7-19. Transformaciones acumulativas sobre la matriz.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
lienzo.transform(3,0,0,1,0,0);
lienzo.font="bold 20px verdana, sans-serif";
lienzo.fillText("PRUEBA",20,20);
lienzo.transform(1,0,0,10,0,0);
lienzo.font="bold 20px verdana, sans-serif";
lienzo.fillText("PRUEBA",100,20);
}
window.addEventListener("load", iniciar, false);

Al igual que en el código anterior, en el Código 7-19 aplicamos varios métodos de transformación sobre el mismo texto para comparar efectos. Los valores por defecto de la matriz del lienzo son 1,0,0,1,0,0. Cambiando el primer valor a 3, en la primera transformación de nuestro ejemplo arriba, estiramos el lienzo horizontalmente. El texto dibujado luego de esta transformación será más ancho que en condiciones por defecto.
Con la siguiente transformación, el lienzo fue estirado verticalmente cambiando el cuarto valor a 10 y preservando los anteriores.
Un detalle importante a recordar es que las transformaciones son aplicadas sobre la matriz declarada en previas transformaciones, por lo que el segundo texto mostrado por el código del Código 7-19 será igual de ancho que el anterior (es estirado horizontal y verticalmente). Para reinicializar la matriz y declarar nuevos valores de transformación, podemos usar el método setTransform()
Hágalo usted mismo: Reemplace el último método transform() en el ejemplo por setTransform() y compruebe los resultados. Usando solo un texto, cambie cada valor en el método transform() para conocer la clase de transformación realizada en el lienzo por cada uno de ellos.

  • Restaurando el estado

La acumulación de transformaciones hace realmente difícil volver a anteriores estados. En el código del Código 7-18, por ejemplo, tuvimos que recordar el valor de rotación usado previamente para poder realizar una nueva rotación y volver el lienzo al estado original. 
Considerando situaciones como ésta, Canvas API provee dos métodos para grabar y recuperar el estado del lienzo. 
  • save() :Este método graba el estado del lienzo, incluyendo transformaciones ya aplicadas, valores de propiedades de estilo y la actual máscara (el área creada por el método clip(), si existe).
  • restore() :Este método recupera el último estado grabado.


Código 7-20. Grabando el estado del lienzo.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
lienzo.save();
lienzo.translate(50,70);
lienzo.font="bold 20px verdana, sans-serif";
lienzo.fillText("PRUEBA1",0,30);
lienzo.restore();
lienzo.fillText("PRUEBA2",0,30);
}
window.addEventListener("load", iniciar, false);

Si ejecuta el código del Código 7-20 en su navegador, verá el texto “PRUEBA1” en grandes letras al centro del lienzo, y el texto “PRUEBA2” en letras pequeñas, cercano al origen. Lo que hicimos fue grabar el estado por defecto del lienzo y luego establecer una nueva posición para el origen y estilos para el texto. El primer texto es dibujado con esta configuración, pero antes de dibujar el segundo texto el estado original es restaurado, por lo que este texto es mostrado con los estilos por defecto, no con los declarados para el primero.
No importa cuántas transformaciones hayamos realizado, luego de llamar al método restore() la configuración del lienzo será retornada exactamente a su estado anterior (el último grabado).

  • globalCompositeOperation

Cuando hablamos de trazados dijimos que existe una propiedad para determinar cómo una figura es posicionada y combinada con figuras dibujadas previamente en el lienzo. La propiedad es globalCompositeOperation y su valor por defecto es source-over, lo que significa que la nueva figura será dibujada sobre las que ya existen en el lienzo. La propiedad ofrece 11 valores más:
  • source-in :Solo la parte de la nueva figura que se sobrepone a las figuras previas es dibujada. El resto de la figura, e incluso el resto de las figuras previas, se vuelven transparentes.
  • source-out :Solo la parte de la nueva figura que no se sobrepone a las figuras previas es dibujada. El resto de la figura, e incluso el resto de las figuras previas, se vuelven transparentes.
  • source-atop :Solo la parte de la nueva figura que se superpone con las figuras previas es dibujada. Las figuras previas son preservadas, pero el resto de la nueva figura se vuelve transparente.
  • lighter :Ambas figuras son dibujadas (nueva y vieja), pero el color de las partes que se superponen es obtenido adicionando los valores de los colores de cada figura.
  • xor :Ambas figuras son dibujadas (nueva y vieja), pero las partes que se superponen se vuelven transparentes.
  • destination-over :Este es el opuesto del valor por defecto. Las nuevas figuras son dibujadas detrás de las viejas que ya se encuentran en el lienzo.
  • destination-in :Las partes de las figuras existentes en el lienzo que se superponen con la nueva figura son preservadas. El resto, incluyendo la nueva figura, se vuelven transparentes.
  • destination-out :Las partes de las figuras existentes en el lienzo que no se superponen con la nueva figura son preservadas. El resto, incluyendo la nueva figura, se vuelven transparentes.
  • destination-atop :Las figuras existentes y la nueva son preservadas solo en la parte en la que se superponen.

  • darker :Ambas figuras son dibujadas, pero el color de las partes que se superponen es determinado substrayendo los valores de los colores de cada figura.
  • copy :Solo la nueva figura es dibujada. Las ya existentes se vuelven transparentes.


Código 7-21. Probando la propiedad globalCompositeOperation.

function iniciar(){
var elemento=document.getElementById('lienzo');
lienzo=elemento.getContext('2d');
lienzo.fillStyle="#990000";
lienzo.fillRect(100,100,300,100);
lienzo.globalCompositeOperation="destination-atop";
lienzo.fillStyle="#AAAAFF";
lienzo.font="bold 80px verdana, sans-serif";
lienzo.textAlign="center";
lienzo.textBaseline="middle";
lienzo.fillText("PRUEBA",250,110);
}
window.addEventListener("load", iniciar, false);

Solo representaciones visuales de cada posible valor para la propiedad globalCompositeOperation le ayudarán a comprender cómo funcionan. Con este propósito, preparamos el código del Código 7-21. Cuando este código es ejecutado, un rectángulo rojo es dibujado en el medio del lienzo, pero gracias al valor destination-atop solo la parte del rectángulo que se superpone con el texto es dibujada.
Hágalo usted mismo: Reemplace el valor destination-atop con cualquiera de los demás valores posibles para esta propiedad y compruebe el resultado en su navegador. Pruebe el código en distintos navegadores.

Espero haber ayudado en algo. Hasta la próxima oportunidad!










  

jueves, 21 de enero de 2016

Algoritmos - 5 de 5



5.5.2 Algoritmos recursivos de prueba y error

Ejemplo 15. Método de Newton-Rapshon de manera recursiva

A continuación se va a rehacer el método de Newton-Raphson de manera recursiva. La manera en la que se plantea es haciendo llamadas sucesivas a la subrutina en la que se realizan las aproximaciones sucesivas pasando el nuevo valor de X que se quiere chequear.

Este valor irá estando cada vez más cerca de la solución f(x)=0 por lo que se añade una bifurcación al comiendo de la subrutina para chequear si se está suficientemente cerca de la solución. Esta bifurcación establece si debe realizarse una nueva llamada a la propia subrutina o bien si debe finalizar el programa.



Resulta imposible describir todos los algoritmos recursivos de prueba y error. De hecho, tampoco es la intención de este libro, sino que es más bien la de familiarizarse con la computación. Sin embargo un par de algoritmos van a ser descritos para desarrollar el conocimiento en esta disciplina. Un tipo de algoritmos dentro de los algoritmos recursivos de prueba y error son los algoritmos recursivos de búsqueda "hacia delante y hacia atrás". A continuación veremos el ejemplo del "viaje del caballo" y el "problema de las 8 reinas". Son dos jemplos situados en el entorno del juego del ajedrez.


Este juego ha sido objeto de estudio para buscar maneras de programar siguiendo el razonamiento que sigue la inteligencia humana ya que, la manera de pensar que se sigue en este juego es abordable siguiendo métodos mecanicistas. 


Ejemplo 16. El viaje del caballo

En ciertos casos se puede plantear un esquema recursivo de prueba y error donde las pruebas que realiza el ordenador construyen una serie caminos de búsqueda de soluciones. Estos caminos de búsqueda dan como resultado un árbol de subtareas, donde algunos caminos no llegan a la solución mientras que otros sí. En muchos problemas, este árbol crece muy rápidamente, normalmente de manera exponencial, con la subsiguiente carga computacional.



Vamos a introducirnos en la técnica descrita mediante el conocido ejemplo del "viaje del caballo". Dado un tablero de ajedrez de NxN casillas, un caballo situado en una determinada casilla debe recorrer todo el tablero -de acuerdo a los movimientos permitidos según el juego del ajedrez- visitando todas las casillas sin situarse dos veces en ninguna de ellas. De forma que el problema consiste en encontrar un camino, si es que existe alguno, que recorra todo el tablero siguiendo la ruta mas corta, y por lo tanto realizando N2-1 movimientos, siguiendo los movimientos del caballo de ajedrez.

Considerando que el caballo puede realizar 8 movimientos posibles, la manera lógica para resolver este problema es la de construir el camino mediante una sucesión de búsquedas parciales, siendo ésta la búsqueda parcial de una nueva casilla que puede ser visitada. En el caso de encontrarse una nueva casilla, se procede a buscar la siguiente (se avanza hacia delante) y, en caso de no encontrase, se vuelve a la casilla de la que se había partido (se avanza hacia atrás), para probar una nueva casilla que pueda ser visitada distinta a la que se acababa de probar.

De manera que el procedimiento consistirá en inicializar las variables necesarias y proceder a dar el primer paso. La resolución del problema la realizaremos para un tablero con un número cualquiera de casillas y comenzando en una fila (f) y columna (c) cualquiera.

Siendo Casillas, el número de casillas del tablero, las variables que se inicializan son:

Tablero: es una matriz llena de ceros con un número de celdas igual a CasillasxCasillas. Según vaya el caballo pasando por cada celda se llenará la celda en cuestión con el número que indica en qué paso ha accedido el caballo a ella.

a: es un vector de ocho elementos con los desplazamientos permitidos en las filas del tablero para un caballo de ajedrez.

b: es un vector de ocho elementos con los desplazamientos permitidos en las columnas del tablero para un caballo de ajedrez. Los vectores a y b están coordinados entre sí, de manera que a(1) y b(1) representan el desplazamiento en la fila y la columna para el primero de los movimientos y así sucesivamente.

N: se corresponde con el número de movimientos realizados por el caballo. Será una variable auxiliar para determinar si con el movimiento que se acaba de realizar se ha llegado a alguna solución, ya que cuando N adquiera el valor de CasillasxCasillas significará que el caballo a pasado por todas las casillas.

La inicialización se realizará en la función principal, a la que llamaremos El_viaje_del_Caballo(f,c,Casillas). Las variables que se pasan por ventanilla son la fila de la que parte el caballo, f, la columna, c, y el número de filas o columnas que tiene el tablero, Casillas. Después de la inicialización se procede a dar el primer paso. Para ello se utilizará la función nuevo_paso(Tablero,f,c,a,b,N).

La función nuevo_paso será una función recursiva en la que se irá probando cada uno de los 8 movimientos que puede dar el caballo. Para determinar cuál de los ocho movimientos se está probando utilizaremos una variable auxiliar a la que llamaremos movimiento.

En primer lugar, la función nuevo_paso probará a dar el primero de los 8 movimientos. Si es correcto lo guarda y vuelve a llamarse a sí misma volviendo a repetir el proceso, con lo que se da un paso adelante. Si el movimiento probado no es correcto (esto es, se sale del tablero o accede a una casilla por donde ya ha pasado) pasa a probar el siguiente movimiento. Cuando ha probado los 8 movimientos, la función termina y con ella termina también ese camino de búsqueda, con lo que se da un paso hacia atrás.

El diagrama de flujo con el algoritmo descrito anteriormente es el siguiente:


La variable N es una variable que contabiliza el número de movimientos realizados. 
No aparece en el diagrama de flujo, pero si en el código del programa. Gracias a esta variable, se soluciona la casuística que aparece cuando se ha cumplido el objetivo de recorrer todas las casillas del tablero y, en consecuencia, no es posible realizar ningún movimiento más. Se puede identificar que el programa ha llegado a este momento porque el valor de N coincide con size(Tablero,1)^2. Ahora lo que se hace es sacar por pantalla el tablero con los pasos realizados (Tablero(f1,c1)=N -observe que no se ha puesto ’;’ al final de la instrucción).

Es interesante el recurso empleado para poder utilizar los vectores con los movimientos a y b. Al ser dos vectores con los valores constantes, se ha definido como variables globales tanto en la función de inicialización (backtraking) como en la de búsqueda (nuevo_paso). Con esto se evita tener que pasar los valores de a y b por ventanilla en cada una de las llamadas, con lo que la velocidad del proceso mejora.

A continuación se presenta la primera de las múltiples soluciones que se obtienen cuando se le pide al programa que determine el camino a seguir para un tablero de 8x8 situando al caballo inicialmente en la casilla 1,1.



Puede observarse (con un poco de paciencia) como los movimientos realizados tienen una correspondencia con el orden en el que se han definido los 8 movimientos en los vecotres a y b.


Ejemplo 17. El problema de los emparejamientos estables

Imaginemos dos grupos de personas A y B con un mismo número de componentes N. 
Se trata de encontrar el conjunto de N parejas a,b siendo a del grupo A y b del grupo B, que satisfagan ciertas restricciones. Se pueden utilizar muchos criterios para establecer estos emparejamientos. Uno de ellos es conocido como la "regla de los emparejamientos estables", el cual se explica a continuación:

Supongamos que A es un conjunto de motoristas y B un conjunto de cámaras de televisión. El objetivo es tratar de emparejar a los motoristas con los cámaras de televisión para cubrir la retrasmisión de una carrera ciclista. Cada motorista y cada cámara tienen distintas preferencias a la hora de elegir una pareja del otro grupo. Si las N parejas se establecen de forma que existe un motorista y un cámara de televisión que se prefieren mutuamente frente a la pareja que les ha tocado respectivamente, entonces el emparejamiento resulta inestable. Si, por el contrario, este tipo de sinergias no existen, se dice entonces que el emparejamiento es estable. Esta situación caracteriza muchos problemas que se presentan cuando hay que realizar emparejamientos de acuerdo a ciertas preferencias.

Supongamos que acaban de nombrar a un nuevo jefe para cubrir la actualidad deportiva en ese canal de televisión. Este jefe quiere que todas las personas que están a su cargo estén lo más contestas posible. Va a intentar que todas las órdenes que se den estén consensuadas por todos los afectados. Se va a cubrir la retransmisión de una maratón con 8 parejas de motoristas y de cámaras. Para establecer los emparejamientos se ha decidido que cada motorista pase el orden de preferencia que tiene sobre los cámaras y que cada cámara pase el orden de preferencia que tiene sobre los motoristas. 
Con ello se ha elaborado la siguiente lista con la que hay que establecer los emparejamientos:


De forma que el motorista 1 prefiere estar en primer lugar con el cámara 7, en segundo lugar con el cámara 2 y así sucesivamente.

Un camino para dar con la solución es probar todos los pares de miembros de los dos grupos, uno detrás de otro, localizando las soluciones. Se establece, en este caso, una búsqueda de prueba y error hacia delante y hacia atrás sobre las distintas pruebas que se van haciendo. Este es el método seguido en el caso del problema de las 8 reinas, presentado en el libro "Aprenda a programar...". Llamando Prueba a la función para buscar la pareja al motorista M según el orden establecido mediante su ranking R, podemos escribir el siguiente diagrama de flujo que es completamente coincidente al del problema de las 8 reinas, salvando las pequeñas diferencias debidas a la casuística:


En el diagrama de flujo propuesto, se busca a un cámara que pueda ser pareja de un motorista. De manera que comenzamos buscando pareja al motorista 1, luego al motorista 2 y así sucesivamente; sin embargo observe que podría realizarse al revés, buscando primero pareja al cámara 1, luego al 2 etc.

Dentro de la Figura 5.9, la pregunta ¿Es válido? tiene dos partes. Para que la respuesta sea sí, hay que comprobar en primer lugar que el cámara no haya sido ya asignado. Y en segundo lugar hay que comprobar que el emparejamiento es estable.

Para ello hay que decidir cómo agrupar la información. En primer lugar vamos a guardar los datos iniciales que aparecen en la Tabla 5.1 en dos matrices:

MR: Matriz de 8x8 con el ranking establecido por los motoristas.
CR: Matriz de 8x8 con el ranking establecido por los cámaras.

Por ejemplo, MR(3,2) se corresponde con el cámara preferido en segundo lugar por el motorista 3, que es el cámara 2, según la Tabla 5.1.

Vamos a guardar el resultado de la búsqueda en un vector llamado X de 8 elementos en el que se indiquen ordenadamente el cámara elegido por el motorista de cada casilla. Así por ejemplo, X(3) se correspondería con el cámara asignado al motorista 3.

Además, va a ser conveniente establecer un segundo vector Y de otros 8 elementos donde guardaremos ordenadamente a los motoristas asignados a los distintos cámaras. Lógicamente, no es necesario crear Y, ya que es en realidad una información redundante. En realidad se puede crear Y a partir de X, y viceversa, según la relación:

Sin embargo, el disponer de Y va a mejorar sensiblemente la eficiencia del algoritmo.

Con esto, el diagrama de flujo de la Figura 5.9 puede ser reescrito de la siguiente manera:


Una parte fundamental en el diagrama de la Figura 5.10 es determinar si es estable la nueva pareja M-C establecida. Desgraciadamente no es posible establecer si es estable la pareja con una simple comprobación como en el caso del problema de las 8 reinas. Lo primero que tenemos que tener en cuenta es que la estabilidad o no de una pareja se determina según el ranking establecido en las matrices MR y CR. Sin embargo, éste ranking no está expresado de manera explícita en estas dos matrices. Lo interesante sería disponer de matrices en las que sí estuviera explicito de manera que se pudiera acceder directamente al ranking que tiene el motorista M sobre el cámara C y viceversa.

Para ello vamos a establecer dos matrices auxiliares que son función directa de MR y CR. Estas matrices son RMC y RCM. La primera matriz (RMC) contiene el ranking establecido por los motoristas sobre los cámaras. De manera que RMC(3,1) es el ranking que ocupa el cámara 1 según el orden de preferencia del motorista 3 (que es 4, según el ejemplo propuesto en la Tabla 5.1). Así mismo la segunda matriz, RCM, contiene el ranking establecido por los cámaras sobre los motoristas. Con estas dos matrices auxiliares se facilita muchísimo la determinación de la estabilidad o no de una nueva pareja.

El proceso para saber si es o no estable un emparejamiento se construye directamente aplicando la definición de la estabilidad. Un emparejamiento <M,C> no es estable por dos posibilidades:

1º Existe un cámara, distinto a C, que prefiere a M, frente al motorista que le han asignado y, a su vez, M le prefiere a él frente a C.
2º Existe un motorista distinto a M, que prefiere a C, frente al cámara que le han asignado y, a su vez, C le prefiere a él frente a M.

Lo que ahora toca es realizar una función cuyo encabezado sea:

function [XM,YM]=EmparejamientoEstable(MR,CR)

Donde MR y CR son las matrices anteriormente descritas que contienen el ranking, XM es una matriz cuyas filas se corresponden con cada una de las soluciones estables con los emparejamientos que se hacen a los motoristas e YM es el homólogo a XM pero con los cámaras.

Está función realizará la inicialización del proceso recursivo de prueba y error y lanzará la búsqueda de la pareja para el primer motorista. Según lo que se ha comentado, en la inicialización del proceso debe:

1º Inicializar los vectores X e Y
2º Crear las matrices RMC y RCM.
3º Lanzar la función Prueba para el motorista 1.
Por otra parte hay que, lógicamente, programar la función Prueba, cuyo encabezado será:

function Prueba(M,X,Y)

Siendo M el motorista al que se le busca pareja, X son los cámaras asignados a los motoristas e Y son los motoristas asignados a las cámaras.

Por último será necesario programar una tercera función que devuelva si un emparejamiento es o no estable. El encabezado será:

function E=Estable(M,C,X,Y)

Donde X, Y y M coinciden con los valores de entrada de la función Prueba. C es el cámara que se prueba a emparejar con el motorista M y E es 1 si el emparejamiento es estable y 0 si no lo es.

El resto de datos que necesitan las funciones (MR, CR, RMC o RCM), como no van a variar una vez definidos, deben guardarse como variables globales, tal y como se hace con los vectores que contienen los movimientos en el "viaje del caballo". Hay que observar que en el caso de la función de inicialización - EmparejamientoEstable(MR,CR)- no pueden definirse como variables globales MR y CR, ya que son los propios valores de entrada a la función, así que deberá utilizar otro nombre alternativo para estas dos matrices.

También se deben definir como variables globales las dos matrices de retorno XM e YM, para añadir una nueva fila cada vez que se encuentre alguna solución.


Espero haber ayudado en algo. Hasta la próxima oportunidad!









  
       
free counters

Páginas vistas en total según Google