MIT OpenCourseWare


1.00 Introducción a la informática y a la resolución de problemas de ingeniería. Primavera 2002

Página principal
¿Qué es OCW?
Ayuda
Feedback
Preguntas frecuentes
Glosario
 
 
Página principal del curso
Programa
Calendario
  Material de clase
  Clases de repaso
Trabajos
  Exámenes
  Avisos
  Lecturas obligatorias
  Otras fuentes

   MIT

   
 

Boletín de problemas 9

Fecha de entrega: viernes 3 de mayo de 2002

Problema 1. Argumentos de línea de comandos (10%)

Un modo de obtener datos de entrada del usuario es analizar los argumentos de la línea de comandos del método main() (véase página 99 del texto). El siguiente método main de ejemplo imprime cada argumento de línea de comandos en una línea separada.

static void main(String argv[]) {

     for (int i=0; i<argv.length; i++)

          System.out.println(argv[i]);

}

Escriba un programa Java™ corto llamado IntSummer para dar entrada a una lista de enteros con la línea de comandos. Haga que el programa almacena los enteros en un array de ints, calcule la suma de los enteros, y muestre el resultado de la suma con println. Asuma que la entrada de datos tiene el formato correcto.

Si utiliza una terminal UNIX o MS-DOS para ejecutar el programa, puede especificar los argumentos de comando de línea a su programa Java™ compilado de este modo:

unix% java IntSummer 1 2 3 4 5 6 7

Si ejecuta el programa desde Forte, puede definir los argumentos de la línea de comandos desde el menú "Build", en la opción de menú "Set Arguments".

A partir de ahí, puede ejecutar el programa como siempre.

Problema 2. Características del robot de embalaje. (90%)

Descripción del problema

En el boletín de problemas 7, hay un robot en la estación de embalaje cuyo cometido es poner los equipos en los palets antes de que se envuelvan en película retráctil y se envíen. Ha de saber cuántos equipos, de clases diferentes, puede poner en un palet. Los equipos que se embalan en película retráctil y se colocan sobre un palet son para un pedido específico de un cliente, que suelen ser impredecibles y muy variables. El robot necesita cierta inteligencia para tomar la decisión de embalaje en tiempo real.

Aunque se trata de un problema tridimensional, lo reduciremos a una dimensión (como se suele hacer en la práctica), del siguiente modo:

Tenemos un palet de longitud M, y un conjunto de equipos, cada uno de una longitud Li. Queremos saber qué subconjunto de equipos se pueden poner en este palet. Tras colocar un subconjunto en el primer palet, repetimos a continuación el cálculo para los equipos restantes hasta que se colocan en el palet. Normalmente, el último palet no se llenará del todo. (En algunos casos, muchos o incluso todos los palets no se llenan del todo). Asumimos que la altura y la anchura de los equipos es suficientemente similar como para no tenerse en cuenta. Aunque parece una asunción desproporcionada, suele ser viable en la práctica, especialmente si elegimos bien la orientación del embalaje de cada equipo (sobre su base, sobre su lateral, sobre su extremo).

En esta tarea, vamos a escribir un programa para que determine los equipos que se van a colocar en el primer palet. La generalización para determinar la ubicación de los palets del resto de los equipos no es muy complicada.

Utilizaremos un árbol para representar este problema y para estructurar su solución.  Dispondremos las longitudes Li en orden no decreciente. Cada longitud Li estará representada por un nodo en un árbol. El nodo raíz del árbol será un nodo 'vacío', es decir, un nodo 'nulo'.

Desde cada nodo, generaremos potencialmente dos hijos:

-         Un nodo izquierdo, correspondiente a la longitud siguiente que está dentro de la solución

-         Un nodo derecho, correspondiente a la longitud siguiente que no está dentro de la solución

La siguiente figura muestra el enfoque general.

En esta figura, asumimos que tenemos un array de equipos con 6 longitudes: {5, 10, 12, 13, 15, 18}. La longitud del palet es 30. En cada nodo, mostramos la longitud de los equipos que ya están en la solución y la de todos los equipos que todavía hay que calcular. Así, en el nodo raíz, hay una longitud 0 en la solución y 73 unidades de longitud que todavía hay que tener en cuenta. Utilizamos un array o Vector x para localizar la solución en cada punto del árbol.  Cuando xi= 1, la longitud Li está en la solución; si xi=0, la longitud Li no está en la solución.

 

 

 


En la figura, comenzamos colocando arbitrariamente la primera longitud, 5, en la solución.  Lo hacemos definiendo x0= 1.  En este nodo, el hijo izquierdo de la raíz, tenemos 5 unidades en la solución, y 68 que hay que tener en cuenta. Luego ponemos la longitud 10 en la solución, generando así el siguiente hijo de la izquierda del árbol. En este nodo (15,58), hay 15 unidades en la solución y 58 que hay que calcular. A continuación, podríamos considerar poner la longitud 12 en la solución para generar el nodo (27, 46); sin embargo, no podríamos profundizar en esta rama del árbol porque la siguiente longitud, 13, haría que la suma de la solución actual, 27, más 13 excediese el objetivo, 30. El nodo (27, 46) se muestra en gris porque el algoritmo descrito más abajo poda esta rama (mediante la regla de poda núm. 2) en lugar de generar el nodo.  

A continuación generamos el hijo derecho del nodo (15,58) excluyendo la longitud 12 de la solución, para obtener el nodo (15,46). Pensamos en la posibilidad de añadir la longitud 13 (x3=1) para obtener el nodo (28,33), pero de nuevo no podemos avanzar, porque la siguiente longitud, 15, haría que el resultado de la suma sobrepasase 30. Al igual que antes, podamos el nodo izquierdo y no generamos el nodo (28,33). Volvemos al nodo (15,46) y excluimos la longitud 13, definiendo x3=0.  Esto genera un hijo derecho (15,33), e incluyendo la siguiente longitud, 15, alcanzamos una solución. Esta solución tiene x0=1, x1=1, x2=0, x3=0 y x4=1; en otras palabras, incluye las longitudes 5, 10 y 15.

Puede repasar el resto del ejemplo para ver como el algoritmo avanza generando hijos izquierdos hasta que no hay más soluciones, y entonces retrocede, genera un hijo derecho (si es posible), y continúa. El algoritmo acaba por atravesar el árbol entero que ha generado y concluye. Observe que no se genera el árbol de decisión completo, que en este ejemplo tendría una profundidad de 6 en todas sus rutas, porque podemos finalizar la generación de nodos antes, cuando estamos seguros de que no existen más soluciones en una ruta utilizando un conjunto de reglas de poda.

En un nodo, se pueden aplicar tres reglas de poda para determinar si se deberían generar más hijos. Si hacemos que:

s= suma de las longitudes ya en la solución, (primera cantidad mostrada en los nodos)

r= suma de las longitudes que hay que calcular, (segunda cantidad)

Lk= longitud del nodo k (k indica el nodo actual)

M= suma objetivo de las longitudes

Así, las tres reglas de podado se pueden enunciar como:

  1. Si (s + Lk =M), muestra la solución
  2. Si (s + Lk + Lk+1 <M), genera hijo izquierdo (xk= 1)
  3. Si (s + r - Lk >= M) y (s + Lk+1 <=M), genera hijo derecho (xk=0)

La regla 1 es muy sencilla: consiste en que si la solución en este nodo, más la longitud actual, equivale al objetivo, se muestra el resultado. 

La regla 2 enuncia que si la solución en este punto, más la longitud actual, más la siguiente longitud, suman menos que el objetivo, se genera un hijo izquierdo y se continúa. (Recuerde que las longitudes van en orden no decreciente, y no existen longitudes más cortas que Lk+1)

La regla 3 tiene dos partes. 

Parte a: la solución en este punto, más las longitudes restantes, pero sin incluir la longitud actual, ha de ser mayor que el objetivo. Si la solución en este punto, más las longitudes restantes sin la longitud actual, es menor que el objetivo, no puede existir una solución en esta ruta.

Parte b: la solución en este punto, más la siguiente longitud, pero sin incluir la longitud actual, ha de ser menor que el objetivo. Si la solución en este punto, más la longitud siguiente, sobrepasa el objetivo, no puede existir una solución en esta ruta.  

Las reglas 1 y 2 se excluyen mutuamente. La regla 3 se aplica a todos los nodos, al margen de las reglas 1 y 2. Si ninguna de las reglas se satisfacen en un nodo , quiere decir que ha alcanzado el final de una ruta. Retroceda hasta el nodo padre y pruebe con las reglas que aún no ha utilizado. (Por lo general, la primera vez que creó el nodo padre ya comprobó las reglas 1 y 2, por lo que, en este punto, sólo necesitará verificar la regla 3). Una vez que haya retrocedido hasta la raíz, ya ha terminado.

Estas reglas de poda dependen de que las longitudes estén ordenadas en orden no decreciente. (La semana próxima hablaremos del orden; para esta tarea asuma que los datos de entrada ya están ordenados)

Si no utiliza reglas de poda, incluso un problema pequeño con n=16 speakers generará 216 (2n) o 65.536 nodos. Una solución para 30 o 40 artículos sería informáticamente inviable, incluso en una gran computadora.  Incluso con las reglas de poda, pueden ocurrir supuestos peores que requieran cálculos O(2n). Por regla general, al resolver problemas específicos con datos conocidos por todos, estos supuestos se pueden evitar.

Trabajo

Escriba un programa que calcule el subconjunto de un conjunto de longitudes que, sumadas todas, arrojan un número determinado. Puede diseñarlo como desee, siempre que se atenga a los siguientes requisitos: en primer lugar, que el programa utilice argumentos de línea de comando para especificar la suma deseada y la lista de longitudes, en otra palabras, el primer argumento, argv[0], debería ser la anchura del palet M, y el argv[i] (donde i>0) la longitud de los equipos en orden no decreciente (Li); en segundo lugar, que el programa convierta las longitudes de entrada en números enteros y los almacene en un array o Vector de enteros; en tercer lugar, que el programa muestre todos los subconjuntos de las longitudes que, sumadas, arrojan el resultado deseado; puede utilizar System.out.println. Por último, tras mostrar las soluciones, que el programa muestre el número de nodos visitados en el árbol, y el número total de nodos potenciales (2n), donde n es el número de equipos.

Asuma que las longitudes de entrada son en orden no decreciente, y que el objetivo M es factible (L0<= M y la suma de todas Li >= M.) No es obligatorio, pero, si lo desea, puede añadir esta comprobación a los datos de entrada.

Lo que sigue a continuación es una serie de sugerencias.  Puede crear una clase SubsetTree con un constructor y un método privado visit(). El método visit() puede aceptar los argumentos r y s mostrados en la figura, y un argumento k que muestre el nivel en el árbol. El método visit() pone en práctica las reglas de poda al visitar cada nodo del árbol; puede escribirse como un método recursivo que se llama a sí mismo con valores apropiados de r, s y k a medida que atraviesa el árbol. La clase SubsetTree puede tener un método público sum() que invoque el método visit() en el nodo raíz.

Puede utilizar un array o una representación de lista concatenada para almacenar el árbol. Si es usted valiente, se puede evitar el almacenaje del árbol: la combinación del array o el vector X y los argumentos r, s y k del método visit() puede localizar donde se encuentra en el árbol sin almacenar explícitamente ningún modo.

Fase de prueba

Haga pruebas con las longitudes {1, 2, 3, 4, 6, 10, 12, 15, 20, 30, 40, 45, 50} y varias M.

Debate

En este ejercicio, hemos elaborado una lista con todas las posibles soluciones para empaquetar el primer palet. En una situación real, tal vez convendría elegir una solución que tuviese el menor número posible de artículos (o los más largos) para llenar el primer palet. A continuación, podría eliminar esos artículos de la lista y ejecutar de nuevo el mismo algoritmo para determinar qué artículos poner en el palet, etc.

Nota extra

Si desea obtener un máximo de 40 puntos extra, escriba una interfaz gráfica de usuario (IGU) para el programa principal del boletín de ejercicios. Tiene la posibilidad de hacerlo en cualquier boletín de problemas del 6 al 10; pero sólo en uno de ellos. En general, es libre de diseñar la IGU que usted quiera; como si se tratase de un ejercicio en una 'hoja de papel en blanco'. No podrá utilizar System.out.println en su solución; todas las entradas y salidas de datos deben hacerse con Swing. Si opta por crear la interfaz gráfica de usuario ha de entregar dos soluciones:

- El trabajo general, sin la IGU, tal y como se describe en el encargo, lo que nos permite calificar la parte principal de trabajo sin tener que preocuparnos por los posible errores introducidos por la IGU.

- La solución completa con la IGU. En esta segunda entrega sólo se tendrá en cuenta, a efectos de calificación, la IGU, hasta un máximo de 40 puntos. Sólo se calificará la IGU (y sus interfaces inmediatas con el resto del código). Recibirá entre 0 y 40 puntos; aunque reciba 0 su nota general en el trabajo no se verá perjudicada o reducida.

Requisitos específicos para el boletín de problemas 9: su programa debe mostrar la solución gráficamente, igual que en la primera figura de esta tarea. Puede, aunque no es obligatorio, mostrar el árbol de decisión. Si opta por mostrarlo, sólo es necesario que lo haga en los árboles pequeños. No puede utilizar la línea de comando para la entrada de datos.

Entrega del trabajo

Requisitos

  • Problema 1: solamente por correo electrónico. No es necesario entregarlo en papel.
  • Problemas 2 y 3: copia en papel y copia electrónica de TODOS los códigos fuente (todos los archivos con la extensión .java).
  • Incluya en TODOS los archivos que presente su nombre, el nombre de usuario, la sección, el nombre del profesor ayudante, el número de trabajo y una relación de las personas con las que haya comentado el boletín de problemas. 
  • NO entregue copias electrónicas o en papel de código compilado (archivos .class).

Sanciones

  • Por pérdida de copia en papel: -10% de la puntuación del boletín de problemas.
  • Por pérdida de copia electrónica: -30% de la puntuación del boletín de problemas.
  • Por entrega fuera del plazo: -20% de la puntuación del boletín de problemas si es un día de retraso. Por más de un día de retraso = NO SE PUNTUARÁ

 

 

 

Massachusetts Institute of Technology © 2003 MIT | Información Jurídica | Privacidad
Todo uso del sitio de MIT OpenCourseWare y sus materiales de curso queda sujeto a las condiciones y términos de uso detallados
en la sección sobre Información Jurídica
Copyright © 2003 Portal Universia S.A. Todos los derechos reservados
(Avda. de Cantabria s/n - Edif. Arrecife, planta 00.28660 Boadilla del Monte) - Madrid. España.
Contacta con nosotros: Usuarios | Empresas-Instituciones-Medios comunicación
Código Ético | Aviso Legal | Política de confidencialidad | Quiénes somos: Sala de Prensa