You are on page 1of 19

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Ficha 5
Subproblemas
1.] Variantes de la instruccin condicional.

Hemos visto en una Ficha anterior la forma general tpica de una instruccin condicional,
consistente en una expresin lgica y dos ramas o salidas: la rama verdadera y la rama falsa.
Planteada de esta forma, la instruccin condicional suele ser designada como una condicin
doble. En muchos casos esta forma tpica es adecuada y suficiente para el planteo del
programa que est desarrollando.
Sin embargo, puede ocurrir (y de hecho es muy comn) que para una condicin slo se
especifique la realizacin de una accin si la respuesta es verdadera y no se requiera hacer
nada en caso de responder por falso. Para estos casos, en Python y otros lenguajes es
perfectamente vlido escribir una instruccin condicional que slo tenga la rama verdadera,
omitiendo por completo la falsa. Una instruccin condicional de ese tipo se suele designar
como condicin simple, y en ella no se especifica la rama else: la instruccin condicional
termina cuando termina la rama verdadera. La forma general tpica de una instruccin
condicional simple en Python es la siguiente:
if expresin lgica:
instrucciones de la rama verdadera
continuacin del programa

Las instrucciones de la rama verdadera se encolumnan en un bloque hacia la derecha, del


mismo modo que en una condicin doble, pero al terminar este bloque se escriben
directamente las instrucciones para continuar con el programa, en la misma columna del if
inicial, sin escribir la rama else. El diagrama de flujo de la Figura 1 aclara la forma de
funcionamiento.
Figura 1: Diagrama general de una instruccin condicional simple tpica.

Expresin
lgica

verdadero

Rama verdadera

Continuacin del
programa

Como se ve en la figura, si la expresin lgica es verdadera se ejecutar la rama verdadera y


luego continuar el programa, igual que en las condiciones dobles. Pero si la expresin es
Ing. Valerio Frittelli - 97

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

falsa, no se ejecutar ninguna rama especial y tambin se continuar con el programa. Vale
decir: el bloque etiquetado como "Continuacin del programa" en la figura, no es la rama o
salida falsa de la condicin, ya que ese mismo bloque se ejecutar tambin al responder por
verdadero a la expresin lgica. De hecho, ese bloque est fuera de la instruccin
condicional.
A modo de ejemplo, en el siguiente script el valor de la variable n empieza siendo cero. Si
el valor de otra variable x que se carga por teclado es mayor a cero, se cambia el valor de n
asignndole el cociente entre a y x, pero de otro modo no se hace nada y el valor final de la
variable n queda en 0:
n = 0
a = 100
x = int(input('x: '))
if x > 0:
n =

a / x

print('Valor final:', n)

El diagrama de flujo del script anterior, se ve en la figura siguiente:


Figura 2: Diagrama de flujo del script del clculo condicional del cociente.

Inicio
n = 0, a = 100
x

x>0

verdadero

n=a/x

n
Fin

Por otra parte, y continuando con el estudio de variantes para la instruccin condicional, es
posible que en la rama falsa y/o en la rama verdadera de una instruccin condicional se
requiera plantear otra instruccin condicional. De hecho, es posible que a su vez cada nueva
instruccin condicional incluya otras y as sucesivamente segn lo vaya necesitando el
programador, sin lmites tericos. Cuando esto ocurre, se tiene lo que se conoce como un
anidamiento de condiciones. A modo de ejemplo, analicemos el siguiente problema:
Problema 11.) Cargar por teclado tres nmeros enteros y determinar y mostrar el mayor de ellos. No
utilice para el proceso la funcin max() de la librera estndar de Python: disee el algoritmo
suponiendo que tal funcin no existe en el lenguaje que usar para el desarrollo del programa.
a.) Identificacin de componentes:

Ing. Valerio Frittelli - 98

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Resultados:

El mayor entre tres nmeros.

(may: int)

Datos:

Tres nmeros enteros.

(n1, n2, n3: int)

Procesos:
Problema de bsqueda del mayor de un conjunto. El desafo
bsico es tratar de plantear un esquema de condiciones que lleve al mayor del
conjunto, pero de forma que ese esquema incluya la menor cantidad posible de
condiciones. De esta forma, el programa ser ms breve, ms simple de
comprender, y posiblemente ms eficiente en cuanto a tiempo de ejecucin.
Existen muchas estrategias que podran aplicarse, pero una muy intuitiva es la
siguiente: comenzar con una de las tres variables (sea n1) y tratar de determinar si
esa variable contiene al mayor, sin preocuparse por las otras dos. Evidentemente,
el siguiente esquema de pseudocdigo condicional cumple con esa consigna, y
deja el valor del mayor en la variable may si ese mayor estaba en n1:
si n1 > n2

y n1 > n3:
may = n1
sino:
# el mayor no es n1!!!
La condicin planteada es simple y directa: se pregunta si n1 es mayor que n2 y si
al mismo tiempo n1 es mayor que n3, usando un conector y (conjuncin lgica)
(o sea, un and en Python). Si la respuesta es cierta, evidentemente el mayor est
en n1 y en la rama verdadera de esa condicin se asigna n1 en may.
El problema surge si la condicin fuese falsa, en cuyo caso no podemos afirmar en
forma inmediata cul es el mayor. Sin embargo, an cuando en este caso el
problema no est resuelto, tenemos una pequea ganancia: si la condicin fue
falsa, no sabemos cul es el mayor, pero sabemos de manera categrica que ese
mayor no es n1: si la construccin and fue falsa, significa que o bien n1 es menor
que n2, o bien es menor que n3, o bien es menor que ambas y en los tres casos
implica que n1 no es el mayor.
Por lo tanto, si la condicin entr en la rama falsa slo nos queda comparar n2
con n3 para saber cul de las dos contiene al mayor, lo cual puede hacerse con
otra condicin, anidada en esa rama falsa. La estructura de pseudocdigo podra
verse as:
si n1 > n2

y n1 > n3:
may = n1
sino:
si n2 > n3:
may = n2
sino:
may = n3
Note la forma en que se escribi el pseudocdigo del anidamiento de condiciones:
la rama falsa de la primera condicin incluye a la segunda condicin, escrita (o
indentada) en una nueva columna hacia la derecha. Toda la segunda condicin
est escrita a partir de esa columna, indicando que toda ella pertenece al bloque
de la rama falsa de la primera condicin. Y a su vez, las ramas verdadera y falsa de
la segunda condicin, se indentaron en una nueva columna hacia la derecha.
b.) Planteo del algoritmo: Mostramos tanto el pseudocdigo como el diagrama de flujo a
continuacin:

Ing. Valerio Frittelli - 99

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Figura 3: Pseudocdigo y diagrama de flujo del problema de clculo del mayor.

Algoritmo:
1.) Cargar n1, n2 y n3: tres nmeros enteros.
2.) Si n1 > n2 y n1 > n3:
2.1.) may = n1
3.) sino:
3.1.) si n2 > n3:
3.1.1.) may = n2
3.2.) sino:
3.2.1.) may = n3
4.) Mostrar may: el mayor de los tres nmeros.
Inicio
n1, n2, n3

n1 > n2 y
n1 > n3

may = n1

n2 > n3

may = n3

may = n2

may
Fin
c.) Desarrollo del programa: En base al diagrama y/o el pseudocdigo, el script o programa se
deduce en forma simple:
__author__ = 'Ctedra de AED'
# Ttulo general y carga de datos...
print('Problema del clculo del mayor entre tres nmeros')
n1 = int(input('N1: '))
n2 = int(input('N2: '))
n3 = int(input('N3: '))
# Procesos...
if n1 > n2 and n1 > n3:
may = n1
else:

Ing. Valerio Frittelli - 100

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

if n2 > n3:
may = n2
else:
may = n3
# Visualizacin de resultados..
print('El mayor es:', may)

La instruccin condicional anidada que aparece en este script sigue fielmente la estructura
del pseudocdigo que mostramos ms arriba. La segunda instruccin condicional est
incluida en el bloque de la rama falsa de la primera, y esto se indica en Python por medio de
la correcta indentacin de ese bloque.

Sealemos finalmente que en Python se puede plantear una variante para la instruccin
condicional, que permite evitar el anidamiento excesivo de condiciones. Se trata de la
variante if elif, que puede usarse en forma combinada con el if else normal [1] [2]. La
parte elif de una condicin, cuando est presente, equivale a un else que contenga a su vez
a otra condicin, sin tener que trabajar tanto en la indentacin de la estructura anidada y
simplificando el cdigo fuente. A modo de ejemplo, una estructura anidada tal como:
if opcion == 1:
print('Se eligi la opcin 1')
else:
if opcion == 2:
print('Se eligi la opcin 2')
else:
if opcion == 3:
print('Se eligi la opcin 3')
else:
print('Opcin no vlida')

podra reescribirse de la siguiente forma, ms compacta, usando elif:


if opcion == 1:
print('Se eligi
elif opcion == 2:
print('Se eligi
elif opcion == 3:
print('Se eligi
else:
print('Opcin no

la opcin 1')
la opcin ')
la opcin 3')
vlida')

Cada lnea que contiene un elif contina en forma directa con la expresin lgica que se
quera evaluar en la salida falsa de la condicin anterior, sin tener que volver a escribir la
palabra if en esa lnea. Observe que en este esquema, la ltima condicin llev un else y no
un elif, ya que esa rama no incluye (en el esquema original anidado) otra condicin, sino
directamente un print(). Note tambin que al usar elif se simplific de manera notable el
esquema de indentacin del script.
Un detalle interesante, es que Python no dispone de instrucciones condicionales mltiples
especiales como las instrucciones switch o case de otros lenguajes, pero como se vi en el
ejemplo anterior, el uso de elif permite plantear una estructura de condiciones anidadas que
equivale por completo a una condicin mltiple.

Ing. Valerio Frittelli - 101

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Por otra parte, observe que tanto el diagrama de flujo como el pseudocdigo no tienen por
qu modificarse si el programador piensa hacer uso de if elif en lugar de if else anidados.
La lgica es la misma, y en este caso Python provee una alternativa sintctica ms compacta
para escribir el mismo algoritmo. El script para el clculo del mayor que antes mostramos
con condiciones if else anidadas, puede replantearse as, mediante instrucciones if elif,
sin tocar en absoluto el diagrama de flujo ni el pseudocdigo de la Figura 3:
__author__ = 'Ctedra de AED'
# Ttulo general y carga de datos...
print('Problema del clculo del mayor entre tres nmeros')
n1 = int(input('N1: '))
n2 = int(input('N2: '))
n3 = int(input('N3: '))
# Procesos...
if n1 > n2 and n1 > n3:
may = n1
elif n2 > n3:
may = n2
else:
may = n3
# Visualizacin de resultados..
print('El mayor es:', may)

Para cerrar esta seccin, mostramos ahora un nuevo problema de aplicacin de los temas
vistos hasta aqu:
Problema 12.) Una compaa de alquiler de automviles necesita un programa que calcule lo que se
debe cobrar a cada cliente, teniendo en cuenta el kilometraje recorrido por el cliente al devolver el
automvil 1:
i. Si el cliente no super los 300 km recorridos se deber cobrar $500.
ii. Para recorridos desde ms de 300 km y hasta no ms de 1000 km se le cobrar $500 ms el

kilometraje excedente a los 300, a razn de $3 por kilmetro.


iii. Para recorridos mayores a 1000 km se le cobrar $500 ms el kilometraje excedente a los

300, a razn de $1,5 por kilmetro.


a.) Identificacin de componentes:

Resultados:

El monto a cobrar.

(monto: float)

Datos:

El kilometraje recorrido.

(kilometraje: int)

Procesos:
Problema de aritmtica bsica aplicado a un contexto comercial.
La base del algoritmo es determinar en qu rango est el valor de la variable
kilometraje, lo cual puede hacerse con condiciones anidadas y prestando atencin
a los lmites de esos rangos. Por otra parte, sabemos que si kilometraje es mayor
que 300, debemos saber cuntos kilmetros de excedente hubo, para calcular con

Este problema fue sugerido por la Ing. Marina Cardenas, docente de esta Ctedra.

Ing. Valerio Frittelli - 102

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

ello el monto final a pagar. Todo eso puede resumirse en el siguiente esquema de
pseudocdigo general:
si kilometraje <= 300:

monto = 500
sino:
excedente = kilometraje - 300
si kilometraje <= 1000:
monto = 500 + 3*excedente
sino:
monto = 500 + 1.5*excedente
La idea es simple: si kilometraje es mayor a 300, se calcula por nica vez el valor
del excedente, y luego se determina si el kilometraje super o no los 1000
kilmetros. Si lo hizo, se calcula el monto final sumando 1.5*excedente al valor
base de 500. Y si no super los 1000 kilmetros, se suma 3*excedente al monto
base de 500.
b.) Planteo del algoritmo: Mostramos ahora el diagrama de flujo de la solucin:
Inicio
kilometraje

kilometraje
<= 300
excedente = kilometraje - 300

monto = 500

kilometraje
<= 1000
monto = 500 + 1.5*excedente

monto = 500 + 3*excedente

monto

Fin

c.) Desarrollo del programa: Como siempre, en base al diagrama el script se deduce en forma
inmediata:
__author__ = 'Ctedra de AED'
# Ttulo general y carga de datos...
kilometraje = int(input("Ingrese la cantidad de kilmetros: "))
# Proceso: clculo del valor a cobrar
if kilometraje <= 300:
monto = 500

Ing. Valerio Frittelli - 103

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

else:
excedente = kilometraje - 300
if kilometraje <= 1000:
monto = 500 + 3*excedente
else:
monto = 500 + 1.5*excedente
# Visualizacin de resultados
print("El importe a pagar es:", monto)

2.] Introduccin al concepto de subproblema.

La mayora de los problemas que normalmente se enfrentan en la prctica son de estructura


compuesta, es decir, son problemas que pueden ser divididos en subproblemas cada vez
menores en complejidad, hasta llegar a subproblemas que no necesiten nuevas
subdivisiones (y que por eso se designan como problemas simples). Bsicamente, un
subproblema es un problema incluido dentro de otro de estructura ms compleja. En ese
sentido, todos los problemas, ejemplos y casos de anlisis que hemos analizado hasta ahora
en todas las Fichas anteriores, eran de estructura simple, porque no admitan ser divididos
en subproblemas menores2.
Un principio bsico en el planteo de algoritmos para resolver problemas, consiste
justamente en tratar de identificar los subproblemas simples de un problema compuesto,
considerando que cada subproblema simple es tambin un problema que admite datos,
desarrolla procesos y genera resultados.
Esta forma bsica de proceder, centrando el anlisis de un problema en los subproblemas
que pudiera contener, ha dado origen a la tcnica o paradigma de programacin que
usaremos y que generalmente se conoce como programacin estructurada3, en la que
justamente se trabaja de forma que los programadores descomponen un problema en
problemas menores, programan por separado los procesos que resuelven esos
subproblemas, y luego unen todo para formar el programa completo [3].
Idealmente, y en forma muy general, un problema compuesto se dividir en tantos
subproblemas como se hayan detectado de forma que cada uno de ellos requerir datos y
entregar resultados. Los resultados que cada uno genere, sern datos para los
subproblemas siguientes o ya sern los resultados finales esperados, como lo que se ve en la
Figura 4 en la cual se supone un problema compuesto con tres subproblemas incluidos en l.

Si de resolver problemas (simples, compuestos, y de todo tipo posible...) se trata, no podemos dejar de
recomendar la pelcula El Marciano (The Martian) estrenada en 2015 y candidata al Oscar. Fue dirigida por
Ridley Scott (el mismo que dirigi Blade Runner) y protagonizada por Matt Damon. Est basada en el reciente
best seller del escritor Andy Weir. Es la historia de un integrante de una hipottica misin a Marte, que por
accidente es dado por muerto y abandonado en el Planeta Rojo. El pobre astronauta deber resolver a partir
de all una enorme cantidad de problemas para sobrevivir hasta su eventual rescate, con un buen humor
infalible y atacando "de a un problema por vez". Imperdible la pelcula. Pero mucho mejor el libro.
3

Un conjunto de reglas y convenciones para trabajar en cierto contexto se designa en general como un
paradigma. En consecuencia, la tcnica de Programacin Estructurada se puede designar tambin en como el
Paradigma de Programacin Estructurada, en contraposicin a otras tcnicas y formas de trabajo que
constituyen otros paradigmas, como el Paradigma de Programacin Orientada a Objetos o el Paradigma de
Programacin Funcional, entre otros.

Ing. Valerio Frittelli - 104

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

La idea de esa figura, (insistimos: muy general y esquemtica) es que los datos del problema
compuesto original sern tomados a su vez como datos por alguno de sus subproblemas, el
cual los procesar y obtendr ciertos resultados parciales, que sern entregados como datos
al siguiente subproblema. En algn momento, alguno de los subproblemas obtendr y
entregar los resultados finales que se esperaban para el problema compuesto original. Los
procesos planteados en cada subproblema se pueden considerar independientes entre ellos,
pero se terminan relacionando por esta secuencia de resultados datos compartidos.
Figura 4: Esquema general de un problema compuesto que incluye tres subproblemas.

datos del
problema

subproblema 1

resultados
datos

subproblema 2

resultados
datos

subproblema 3

resultados
del problema

Un problema compuesto

Est claro que en una situacin real, este esquema puede variar y complicarse mucho ms:
los datos originales del problema compuesto podran ser tomados por dos o ms
subproblemas (y no por uno solo); los resultados finales podran llegar a ser obtenidos por
ms de un subproblema (y no slo por uno); y los resultados parciales de un subproblema
podran ser tomados como datos o entradas por ms de un subproblema posterior (y no slo
por uno) O incluso ms: cualquiera de los subproblemas podra a su vez ser compuesto,
dividindose en dos o ms subproblemas l mismo. Lo que intenta rescatar la Figura 4 es el
fundamento conceptual bsico: un problema compuesto contiene subproblemas que
aprovechan mutuamente los resultados parciales obtenidos para llegar en algn momento al
resultado final esperado.
A modo de ejemplo que permita aclarar el tema, analicemos ahora el siguiente problema de
aplicacin:
Problema 13.) En el contexto de un estudio estadstico, se requiere un programa que cargue tres
nmeros por teclado y luego proceda a determinar el menor de ellos y calcular el cuadrado y el cubo
del mismo.
b.) Identificacin de componentes:

Resultados:

El menor, su cuadrado y su cubo.

(men, cuad, cubo: int)

Datos:

Tres nmeros distintos.

(a, b, c: int)

Procesos: El problema puede ser dividido en dos subproblemas: uno de ellos


tiene como objetivo calcular el menor de los tres valores de entrada, y el segundo
busca calcular el cuadrado y el cubo de ese valor. En vez de intentar realizar todo
a la vez, lo cual creara eventuales confusiones, se trata de plantear cada
subproblema por separado, y luego unir las piezas para obtener el algoritmo
completo que permita desarrollar un programa.
Como cada subproblema es l mismo un problema, entonces cada uno tiene su
propio modelo de datos, procesos y resultados. Y en ese sentido, el planteo de
cada subproblema puede hacerse como sigue:
Subproblema 1:

Determinar el menor de los tres valores de entrada.

Resultados: El menor de tres nmeros.

(men: int)

Ing. Valerio Frittelli - 105

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Datos: Tres nmeros.

(a, b, c: int)

Procesos: El proceso de este subproblema consiste en plantear el


esquema de condiciones que permita encontrar el menor entre los
valores de las variables a, b, y c, lo cual puede hacer en base al
siguiente modelo de pseudocdigo:
si

a < b y a < c:
men = a
sino:
si b < c:
men = b
sino:
men = c

Subproblema 2: Calcular el cuadrado y el cubo del menor encontrado.


Resultados: El cuadrado y el cubo del menor. (cuad, cubo: int)
Datos: El menor de los valores de entrada.

(men: int)

Procesos: En este subproblema, todo el trabajo consiste en calcular


el cuadrado y el cubo del menor:
cuad
cubo

=
=

men ** 2
men ** 3

Aqu debe notarse que este subproblema toma como dato al valor
men que fue el resultado del subproblema anterior. Pero eso no
significa que el valor de men debe ser cargado por teclado: su valor
surge de los procesos del subproblema anterior, en particular de las
condiciones y asignaciones usadas para calcular el valor menor.
Es fcil ver que con estos dos subproblemas detectados y analizados, la estructura
grfica completa del problema original puede representarse a travs del modelo
que se ve en la Figura 5 :
Figura 5: Modelo de subproblemas para el problema del cuadrado y el cubo del menor.
Inicio
a, b, c

datos generales del


problema compuesto
original

Subproblema 1:
Determinar el menor entre a, b y c.
Problema del cuadrado
y el cubo del menor.
(problema compuesto)

- resultado subproblema 1
men
- dato subproblema 2
Subproblema 2:
Calcular el cuadrado y el cubo del
menor.

men, cuad, cubo

resultados generales del


problema compuesto
original

Fin

Ing. Valerio Frittelli - 106

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

c.) Planteo del algoritmo: A partir de la discusin hecha en la identificacin de componentes, y


tomando como base el modelo de subproblemas de la Figura 5, se puede plantear un
diagrama de flujo que contemple implcitamente a esos subproblemas, los cuales se
muestran remarcados con llaves de color azul para facilitar su identificacin (ver Figura 6):
Figura 6: Diagrama del flujo del problema del cubo y el cuadrado del menor, marcando subproblemas.
Inicio
a, b, c

a<by
a<c
men = a

b<c
men = c

subproblema 1:
Calcular el menor.
men = b

cuad = men ** 2
cubo = men ** 3

subproblema 2:
Calcular cuadrado y
cubo.

men, cuad, cubo

Fin

d.) Desarrollo del programa: Como siempre, en base al diagrama el script se deduce en forma
inmediata:
__author__ = 'Ctedra de AED'
# ttulos y carga de datos...
print('Determinacin del cuadrado y el cubo del menor')
a = int(input('Primer nmero: '))
b = int(input('Segundo nmero: '))
c = int(input('Tercer nmero: '))
# procesos...
# subproblema 1: determinar el menor...
if a < b and a < c:
men = a
else:
if b < c:
men = b
else:
men = c
# subproblema 2: calcular el cuadrado y el cubo del menor...
cuad = men ** 2

Ing. Valerio Frittelli - 107

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

cubo = men ** 3
# visualizacin de resultados...
print('El menor es:', men)
print('Su cuadrado es:', cuad)
print('Su cubo es:', cubo)

Como ya habr podido notar, a medida que se estudian problemas de estructura ms


compleja y se incorporan nuevos elementos (como instrucciones condicionales y
subproblemas), se hace tambin cada vez ms extenso el anlisis del problema a nivel de
identificacin de datos, resultados y procesos. Hemos indicado en una ficha anterior que en
la prctica, el programador hace gran parte de este proceso mentalmente, sin tanto rigor
descriptivo previo. Y eso es lo que comenzaremos a hacer de aqu en ms: para cada
problema, bastar con una brevsima identificacin de datos y resultados, para pasar luego
al planteo del diagrama de flujo o el pseudocdigo. Si fuese necesaria una discusin referida
a ciertos aspectos lgicos de la solucin, se incorporar brevemente antes de plantear el
diagrama [3].
Considere entonces un nuevo ejemplo de aplicacin:
Problema 14.) Se cargan por teclado dos nmeros. Calcular la superficie de un cuadrado, suponiendo
como lado del mismo al mayor de los nmeros dados y la superficie de un crculo suponiendo como
radio del mismo al menor de los nmeros dados.

Discusin y solucin: En este problema tambin se presentan dos subproblemas: en el


primero se debe buscar el mayor y el menor entre dos valores, y en el segundo se deben
calcular las reas indicadas. Como el clculo de las reas no puede hacerse sin conocer cul
de los valores es el mayor y cul es el menor, es obvio entonces que el subproblema de
buscar el mayor y el menor debe resolverse antes que el clculo de las reas. Un esquema
general de subproblemas podra ser el siguiente:
Figura 7: Modelo de subproblemas para el problema de las reas del cuadrado y el crculo.
Inicio

a, b

datos generales del


problema compuesto
original

Subproblema 1:
Determinar el menor (men) y el
mayor (may) entre a y b.
Problema de las reas
del cuadrado y el
crculo.
(problema compuesto)

- resultados subproblema 1
men, may
- datos subproblema 2
Subproblema 2:
Calcular las reas del cuadrado y el
crculo (acuad y acirc)

acuad, acirc

resultados generales del


problema compuesto
original

Fin

Ing. Valerio Frittelli - 108

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

El subproblema 1 tomar los valores de las variables a y b cargados por teclado, determinar
el menor y el mayor y los copiar a su vez en las variables temporales men y may. De esta
forma, si luego se requiere volver procesar estos valores en diferentes lugares del programa,
no ser necesario preguntar nuevamente cul es el mayor y cul el menor: a partir del
ordenamiento de variables producido por este subproblema, el programa trabajar con las
variables men y may en lugar de a y b.
El subproblema 2 simplemente debe calcular las dos reas. El enunciado del problema indica
que debe suponerse un cuadrado cuyo lado sea igual al mayor de los nmeros de entrada
(que tenemos copiado en may) y debe suponerse tambin un crculo cuyo radio sea igual al
menor de esos datos (que tenemos en men). Por lo tanto, aplicando frmulas muy conocidas
de la geometra, el rea del cuadrado (acuad) ser acuad = may ** 2 (el cuadrado del lado) y
el rea del crculo (acirc) ser acirc = 3.1415 * men ** 2 (Pi por radio al cuadrado).
El diagrama de flujo puede verse en la Figura 8:
Figura 8: Diagrama de flujo del problema de la superficie del cuadrado y del crculo.
Inicio
a, b

a>b
men = a

men = b

may = b

may = a

acuad = may ** 2

subproblema 1:
Calcular el menor
y el mayor.

subproblema 2:
Calcular las reas.

acirc = 3.1415 * men ** 2


acuad, acirc

Fin

c.) Desarrollo del programa: El script en Python no presenta dificultades. Slo recuerde la
importancia de respetar la indentacin, que en el caso de las ramas de la condicin en este
caso es fundamental [2]:
__author__ = 'Ctedra de AED'
# ttulos y carga de datos...
print('Clculo de reas de un cuadrado y un crculo...')
a = int(input('Primer nmero: '))
b = int(input('Segundo nmero: '))
# procesos...

Ing. Valerio Frittelli - 109

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

# subproblema 1: determinar el menor y el mayor...


if a > b:
men = b
may = a
else:
men = a
may = b
# subproblema 2: calcular la reas...
acuad = may ** 2
acirc = 3.1415 * men ** 2
# visualizacin de resultados...
print('Area del cuadrado:', acuad)
print('Area del crculo:', acirc)

Anexo: Temas Avanzados


En general, cada Ficha de Estudios podr incluir a modo de anexo un captulo de Temas Avanzados,
en el cual se tratarn temas nombrados en las secciones de la Ficha, pero que requeriran mucho
tiempo para ser desarrollados en el tiempo regular de clase. El captulo de Temas Avanzados podra
incluir profundizaciones de elementos referidos a la programacin en particular o a las ciencias de la
computacin en general, como as tambin explicaciones y demostraciones de fundamentos
matemticos. En general, se espera que el alumno sea capaz de leer, estudiar, dominar y aplicar
estos temas an cuando los mismos no sean especficamente tratados en clase.
a.)

Caso de anlisis: un algoritmo para ordenar tres nmeros contenidos en tres variables.

Nos proponemos analizar con cierta profundidad un problema que se presentar en


reiteradas ocasiones a todo lo largo de este curso: el ordenamiento de un conjunto de
valores. En estas primeras etapas de la asignatura el problema aparecer simplificado: dado
un conjunto de unos pocos nmeros, mostrar esos nmeros en forma ordenada de menor a
mayor.
En este caso, nuestro objetivo ser ordenar un conjunto de slo tres nmeros, contenidos en
tres variables. Podemos hacer esto con las herramientas que hemos visto hasta ahora, en
forma muy elemental. Pero a medida que el curso avance ser cada vez mayor el volumen
de datos a ordenar, y para esos momentos debern estudiarse algoritmos algo ms
sofisticados y emplear otras herramientas disponibles en un lenguaje de programacin.
Para formalizar el trabajo, enunciamos el problema a modo de ejercicio:
Problema 15.) Se cargan por teclado tres nmeros. Se pide mostrarlos en pantalla, ordenados de
menor a mayor.

Discusin y solucin: Comenzaremos suponiendo que tenemos que ordenar un conjunto de


slo dos nmeros, que estn contenidos en sendas variables a y b que se cargarn por
teclado. Este caso es trivial, y puede resolverse con slo una condicin (como ya vimos en
una la Ficha 4, problema 8). Se puede plantear un esquema (a modo de subproblema) que
proceda a ordenar dos nmeros almacenados originalmente en las variables a y b
guardndolos ordenados en otras dos variables que llamaremos may y men. La idea final es
que si queremos ver esos dos nmeros ordenados, apliquemos este proceso y luego
mostremos los valores de men y may (en ese orden). En pseudocdigo, ese proceso podra
quedar as:

Ing. Valerio Frittelli - 110

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

ordenar_dos_numeros:
si a > b:
may =
men =
sino:
may =
men =

a
b
b
a

Si ahora queremos pasar a ordenar los tres nmeros que nos dieron, almacenados en tres
variables a, b y c, podemos mantener la idea que ya hemos usado: intentaremos reasignar
esos tres nmeros en otras tres variables llamadas men, med y may, de forma que la primera
(men) siempre termine conteniendo al menor de los tres originales, med al valor mediano, y
may al mayor.
Una primera idea que siempre suele surgir, consiste en usar tantas condiciones como
combinaciones posibles existan entre los nmeros originales. En nuestro caso, siendo tres las
variables de entrada, las combinaciones posibles son 6 y eso nos llevara a tener que
plantear 6 condiciones (si usamos condiciones simples), como se ve en el esquema siguiente
(en el que para simplificar, asumimos que las tres variables a, b y c tienen valores
diferentes):
# Pseudocdigo para el ordenamiento de tres nmeros: versin 1...
ordenar_tres_numeros:
si a > b > c:
may, med, men = a, b, c
si a > c > b:
may, med, men = a, c, b
si b > a > c:
may, med, men = b, a, c
si b > c > a:
may, med, men = b, c, a
si c > a > b:
may, med, men = c, a, b
si c > b > a:
may, med, men = c, b, a

An cuando la solucin obtenida parece buena, un programador debera acostumbrarse a


desconfiar de su "primer impulso" cuando busca un algoritmo, pues ese primer impulso
suele terminar en una solucin intuitivamente obvia, pero ineficiente o poco prctica en
trminos de demora en el tiempo de ejecucin o en la cantidad de lneas de cdigo que
deber escribir para implementarla. Estas soluciones en las que el programador explora
todas las posibles variantes y combinaciones posibles de resultados, se suelen designar
como estrategias de "fuerza bruta".
Veamos el caso: hemos encontrado una solucin simple, pero nos ha llevado a escribir seis
condiciones para plantearla. Podemos intuir que si seguimos este camino, nos ir cada vez
peor a medida que el nmero de datos aumente. Por caso, si queremos ordenar 4 nmeros
dispuestos en 4 variables de entrada, y seguimos la misma idea, requeriremos 24

Ing. Valerio Frittelli - 111

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

condiciones (que es igual al nmero de combinaciones posibles entre 4 valores...) y eso ya


parece demasiado trabajo...
Nuestro objetivo es encontrar un algoritmo que haga el ordenamiento de tres nmeros,
pero con la menor cantidad posible de instrucciones condicionales. Adems, queremos que
este algoritmo nos "abra la mente", para repetir misma la idea bsica cuando el nmero de
datos suba a 4 (por ejemplo) y tambin queramos la mnima cantidad de condiciones.
Una forma de hacerlo consiste en aplicar una variante simplificada de un algoritmo ms
amplio llamado ordenamiento por insercin. La idea es comenzar con una reduccin del
volumen de datos del problema: en vez de considerar los tres nmeros a, b y c originales,
suponemos que nos han dado slo dos (a y b) e intentamos ordenarlos llevndolos a las
variables men y may (por ahora, nos olvidamos de c y de la variable med):
Figura 9: Paso 1 del proceso de ordenar tres nmeros
a

men

med

ignorar

may

ignorar

Est claro que este primer ordenamiento de dos nmeros puede hacerse con nuestro ya
conocido proceso ordenar_dos_numeros (que ordena los dos valores a y b y usa un sola
condicin...) No importa si el menor estaba en a o en b, finalmente ese proceso lo asignar
en men. Y algo similar ocurrir con el mayor y la variable may. Una vez ordenados esos dos
primeros nmeros, de aqu en ms podemos olvidarnos de las variables a y b, y seguir
trabajando con men y may (que contienen los mismos valores que a y b, pero ahora
tenemos ms informacin: sabemos cul de las dos contiene al menor y cul al mayor.)
El siguiente paso (ahora s) es abrir el juego y considerar la variable c y la variable med. Es
obvio que tenemos aqu tres posibilidades:
El valor de c podra ser mayor que el que tenemos guardado en may. Sera el caso de la Figura
9 si c valiese 8. Esto significara que el valor que tenamos como el mayor, es en realidad el
valor mediano. Reasignamos primero el valor de may en la variable med, y luego guardamos
c en may. No tocamos el valor que tenamos en men (ya que definitivamente era el menor)
(ver Figura 10).
El valor de c podra ser menor que el que tenemos guardado en may, pero mayor al que
tenemos en men. Sera el caso del grfico de la Figura 9 si c valiese 4. Y esto significara que
el valor que tenemos en c es directamente el mediano: slo tendramos que asignar c en
med, y dejar men y may como estaban (ver Figura 11).

Ing. Valerio Frittelli - 112

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

Figura 10: Paso 2 del proceso, si c > may


if

c > may:
med = may
# 1
may = c
# 2
# no tocar men!!!

1
no tocar!!!
men

may

med

Figura 11: Tercer paso, si men < c < may


if

c > may:
med = may
may = c
else:
if c > men:
med = c

no tocar!!!

no tocar!!!
men

med

may

Finalmente, el valor de c podra ser menor que el que tenemos guardado en men. Sera el
caso del grfico de la Figura 9 si c valiese 1. Esto significara que el valor que tenamos como
el menor, es en realidad el valor mediano. Reasignamos primero el valor de men en la
variable med, y luego guardamos c en men. No tocamos el valor que tenamos en may (ya
que definitivamente era el mayor) (ver Figura 12 ).

Ing. Valerio Frittelli - 113

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

if c > may:
med = may
may = c
else:
if c > men:
med =
else:
med =
men =
// no

Figura 12: Cuarto paso, si c < men

c
men # 1
c
# 2
tocar may!

2
no tocar!!!

1
men

med

may

El algoritmo descripto se conoce como ordenamiento por insercin, porque una vez
ordenados los dos primeros nmeros en men y may, se toma el valor c y se lo inserta en el
lugar correcto (delante de may, entre may y men o detrs de men, segn sea el caso)
siguiendo los mecanismos sugeridos.
Despus de todo este anlisis, podemos plantear un programa completo que cargue por
teclado los tres nmeros a, b, c y los ordene por insercin. Primero se se procede a aplicar el
proceso ordenar_dos_numeros para el primer paso de ordenar a y b entre men y may; y
luego se aplican los pasos que hemos visto ms arriba para terminar el proceso insertando c
entre men y may. Es fcil ver que la cantidad total de condiciones empleadas en todo el
proceso es de slo tres: una en el proceso ordenar_dos_numeros y otras dos en el proceso
que ordenar los tres, con lo que logramos una sustancial mejora respecto de las seis
condiciones de nuestro primer intento...
__author__ = 'Ctedra de AED'
# Ttulo general y carga de datos...
print('Problema del ordenamiento de tres numeros')
a = int(input('a: '))
b = int(input('b: '))
c = int(input('c: '))
# Subproblema 1: ordenar dos numeros...
if a > b:
men = b
may = a
else:
men = a

Ing. Valerio Frittelli - 114

Ctedra de AED [Ciclo 2016]

Ficha 05: Subproblemas

may = b
# Subproblema 2: ordenar los tres numeros...
if c > may:
med = may
may = c
else:
if c > men:
med = c
else:
med = men
men = c
# Visualizacin
print('Menor:',
print('Medio:',
print('Mayor:',

de los resultados ordenados...


men)
med)
may)

Crditos
El contenido general de esta Ficha de Estudio fue desarrollado por el Ing. Valerio Frittelli, para ser
utilizada como material de consulta general en el cursado de la asignatura Algoritmos y Estructuras
de Datos Carrera de Ingeniera en Sistemas de Informacin UTN Crdoba, en el ciclo lectivo 2016.
Actuaron como revisores (indicando posibles errores, sugerencias de agregados de contenidos y
ejercicios, sugerencias de cambios de enfoque en alguna explicacin, etc.) en general todos los
profesores de la citada asignatura como miembros de la Ctedra, y particularmente los ingenieros
Cynthia Corso, Anala Guzmn, Karina Ligorria, Gustavo Federico Bett, Marcela Tartabini, Romina
Teicher, Marina Cardenas, Germn Romani y Julieta Fernndez, que realizaron aportes de
contenidos, propuestas de ejercicios y sus soluciones, sugerencias de estilo de programacin, y
planteo de enunciados de problemas y actividades prcticas, entre otros elementos.

Bibliografa
[1] Python Software Foundation, "Python Documentation,"
https://docs.python.org/3/. [Accessed 24 February 2015].

2015.

[Online].

Available:

[2] M. Pilgrim, "Dive Into Python - Python from novice to pro," 2004. [Online]. Available:
http://www.diveintopython.net/toc/index.html. [Accessed 6 March 2015].
[3] V. Frittelli, Algoritmos y Estructuras de Datos, Crdoba: Universitas, 2001.

Ing. Valerio Frittelli - 115

You might also like